본문으로 건너뛰기
Version: 5.5

릴리스 노트

Windows용 PlanetKit 5.5의 릴리스 노트입니다.

PlanetKit 5.5.2

릴리스 일자: 2025-02-27

특정 상황에서 발생하는 간헐적인 크래시 수정

  • 통화 중 비행기 모드를 활성화한 직후 특정 기기에서 간헐적으로 발생하던 크래시를 수정했습니다.

PlanetKit 5.5.1

릴리스 일자: 2025-01-15

통화 시작 시 음성 전송 시작 지연 문제 수정

1대1 통화 및 그룹 통화 시작 시 로컬 사용자의 음성 전송을 시작하는 데 500ms 지연이 발생하는 문제를 해결했습니다.

PlanetKit 5.5.0

릴리스 일자: 2024-12-09

카메라 장치 관리 API 개선

  • 비디오 캡처 처리 과정을 간소화하기 위해 카메라 장치 관리 API를 개편했습니다.
  • Planet Cloud로 데이터를 보낼 때에만 카메라가 켜지도록 카메라 장치 관리 API를 개선했습니다.
  • 이제 영상 통화에서 카메라의 초기 상태를 제어할 수 있습니다.
    • 1대1 통화: EInitialMyVideoState 유형의 속성 또는 파라미터가 MakeCallParam, PlanetKitCall::AcceptCall(), PlanetKitCall::EnableVideo()에 추가되어 영상 통화를 시작하거나 영상 통화로 전환할 때 카메라 상태를 제어할 수 있습니다.
    • 그룹 통화: EInitialMyVideoState 유형의 속성 또는 파라미터가 ConferenceParamPlanetKitConference::EnableVideo()에 추가되어 영상 통화를 시작하거나 영상 통화로 전환할 때 카메라 상태를 제어할 수 있습니다.

API

변경
  • CameraController, PlanetKitCall, PlanetKitConference class 1-to-1 callGroup call

    이전 버전PlanetKit 5.5
    bool CameraController::AddMyView(WindowHandle hWind)bool PlanetKitCall::AddMyVideoView(WindowHandle hWind)
    bool PlanetKitConference::AddMyVideoView(WindowHandle hWind)
    bool CameraController::RemoveMyView(WindowHandle hWind)bool PlanetKitCall::RemoveMyVideoView(WindowHandle hWind)
    bool PlanetKitConference::RemoveMyVideoView(WindowHandle hWind)
    bool CameraController::RegisterMyVideoReceiver(IVideoReceiver *pReceiver)bool PlanetKitCall::AddMyVideoReceiver(IVideoReceiver* pReceiver)
    bool PlanetKitConference::AddMyVideoReceiver(IVideoReceiver* pReceiver)
    bool CameraController::DeregisterMyVideoReceiver(IVideoReceiver *pReceiver)bool PlanetKitCall::RemoveMyVideoReceiver(IVideoReceiver* pReceiver)
    bool PlanetKitConference::RemoveMyVideoReceiver(IVideoReceiver* pReceiver)
    bool CameraController::AddPeerView(WindowHandle hWind)bool PlanetKitCall::AddPeerVideoView(WindowHandle hWind)
    bool CameraController::AddPeerView(WindowHandle hWind, UserIdPtr pUserPtr)bool PlanetKitConference::AddPeerVideoView(UserIdPtr pPeerID, WindowHandle hWind)
    bool CameraController::RemovePeerView(WindowHandle hWind)bool PlanetKitCall::RemovePeerVideoView(WindowHandle hWind)
    bool PlanetKitConference::RemovePeerVideoView(WindowHandle hWind)
    bool CameraController::RegisterPeersVideoReceiver(IVideoReceiver *pReceiver)bool PlanetKitCall::AddPeerVideoReceiver(IVideoReceiver* pReceiver)
    bool CameraController::DeregisterPeersVideoReceiver(IVideoReceiver *pReceiver)bool PlanetKitCall::RemovePeerVideoReceiver(IVideoReceiver* pReceiver)
  • PlanetKitCall class 1-to-1 call

    이전 버전PlanetKit 5.5
    void AcceptCall(bool bPreparation, CallStartMessagePtr pCallStartMessage = CallStartMessagePtr(nullptr), bool bRecordOnCloud = false)void AcceptCall(bool bPreparation, CallStartMessagePtr pCallStartMessage = CallStartMessagePtr(nullptr), EInitialMyVideoState eInitialMyVideoState = PLNK_INITIAL_MY_VIDEO_STATE_RESUME, bool bRecordOnCloud = false)
    bool EnableVideo(void* pUserData = nullptr, ResultCallback pCallback = nullptr)bool EnableVideo(EInitialMyVideoState eInitialMyVideoState = PLNK_INITIAL_MY_VIDEO_STATE_RESUME, void* pUserData = nullptr, ResultCallback pCallback = nullptr)
  • PlanetKitConference class Group call

    이전 버전PlanetKit 5.5
    bool EnableVideo(void *pUserData = nullptr, ResultCallback pCallback = nullptr)bool EnableVideo(EInitialMyVideoState eInitialMyVideoState = PLNK_INITIAL_MY_VIDEO_STATE_RESUME, void *pUserData = nullptr, ResultCallback pCallback = nullptr)
추가
  • EVideoControlResult enum 1-to-1 callGroup call
    • EVideoControlResult_PreviewAlreadyExist
    • EVideoControlResult_CreateRenderFail
    • EVideoControlResult_CameraIsAlreadyInUseByAnotherApplication
    • EVideoControlResult_PreviewHandleIsInvalid
    • EVideoControlResult_PreviewReceiverIsInvalid
  • EInitialMyVideoState enum 1-to-1 callGroup call
    • PLNK_INITIAL_MY_VIDEO_STATE_RESUME
    • PLNK_INITIAL_MY_VIDEO_STATE_PAUSE
  • ECameraControlResult enum 1-to-1 callGroup call
    • PLNK_CAMERA_CONTROL_RESULT_NONE
    • PLNK_CAMERA_CONTROL_RESULT_FAILED_TO_CREATE_CAMERA_DEVICE
    • PLNK_CAMERA_CONTROL_RESULT_SELECTED_CAMERA_IS_REMOVED
    • PLNK_CAMERA_CONTROL_RESULT_NO_CAMERA_SELECTED
  • CameraController class 1-to-1 callGroup call
    • bool StartPreview(WindowHandle hWind)
    • bool StartPreview(IVideoReceiver* pReceiver)
    • bool StopPreview(WindowHandle hWind)
    • bool StopPreview(IVideoReceiver* pReceiver)
  • ConferenceParam class Group call
    • EInitialMyVideoState GetInitialMyVideoState()
    • void SetInitialMyVideoState(EInitialMyVideoState eInitialMyVideoState)
  • MakeCallParam class 1-to-1 call
    • EInitialMyVideoState GetInitialMyVideoState()
    • void SetInitialMyVideoState(EInitialMyVideoState eInitialMyVideoState)
  • PlanetKitCall class 1-to-1 call
    • void RemoveAllMyVideoViewAndReceiver()
    • void RemoveAllPeerVideoViewAndReceiver()
  • PlanetKitConference class Group call
    • void RemoveAllMyVideoViewAndReceiver()
    • bool AddPeerVideoReceiver(UserIdPtr pPeerID, IVideoReceiver* pReceiver)
    • bool RemovePeerVideoReceiver(IVideoReceiver* pReceiver)
    • void RemoveAllPeerVideoViewAndReceiver()
삭제
  • CameraController class 1-to-1 callGroup call
    • bool InitializeRender()
    • bool FinalizeRender()
    • EVideoControlResult StartCapture()
    • bool StopCapture()

예제 코드

  • 새로 추가된 CameraController::StartPreview(WindowHandle)CameraController::StartPreview(IVideoReceiver*)를 사용하여 로컬 사용자의 카메라에서 전송되는 비디오를 미리 볼 수 있습니다. 다음은 CameraController::StartPreview(WindowHandle)를 사용하는 예입니다.

    class YourApplication {
    void StartPreview() {
    // Get PlanetKit::CameraController instance from PlanetKit::PlanetKitManager.
    auto planetKitCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();

    // Start preview.
    planetKitCameraController->StartPreview(m_hWnd);
    }

    private:
    // Prepare your window handle (HWND) where you want to render video from the camera device.
    HWND m_hWnd;
    }
  • 비디오를 직접 처리하려면 IVideoReceiver를 상속하는 비디오 수신 모듈(video receiver)을 구현하고 CameraController::StartPreview(IVideoReceiver*)를 사용하세요.

    class MyVideoReceiver : public PlanetKit::IVideoReceiver {
    public:
    void OnVideo(const PlanetKit::SVideoFrame* pVideoFrame, PlanetKit::UserIdPtr pUserID) {
    // Handling video processing.
    ...
    }
    };

    class YourApplication {
    void StartPreview() {
    // Get PlanetKit::CameraController instance from PlanetKit::PlanetKitManager.
    auto planetKitCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();

    // Start preview.
    planetKitCameraController->StartPreview(&m_myVideoReceiver);
    }

    private:
    // Prepare your video receiver where you want to render video from the camera device.
    MyVideoReceiver m_myVideoReceiver;
    }
  • 1대1 통화 또는 그룹 통화에 연결한 후 로컬 사용자의 비디오를 화면에 렌더링하려면 AddMyVideoView(WindowHandle) 또는 AddMyVideoView(IVideoReceiver*)를 사용하세요.

  • EnableVideo()DisableVideo()가 호출되면 카메라가 자동으로 켜지고 꺼집니다.

  • EnableVideo()를 사용하여 영상 통화로 전환한 후 AddMyVideoView()를 사용하여 렌더링을 위한 뷰를 등록하면 영상이 화면에 보입니다.

    class YourApplication {
    void AddMyVideoView() {
    m_pCall->AddMyVideoView(m_hMyView);
    }

    private:
    PlanetKit::PlanetKitCallPtr m_pCall;
    HWND m_hMyView;
    }

마이그레이션

  • CameraController::StartCapture()CameraController::StopCapture()를 사용하여 카메라를 직접 제어하는 ​​기능을 제거했습니다.

  • 로컬 사용자의 미리보기의 경우 CameraController::StartPreview()를 사용하고 통화가 연결된 후 PlanetKitCall::AddMyVideoView() 또는 PlanetKitConference::AddMyVideoView()를 사용하세요.

  • 버전 5.4 이하에서 카메라 미리보기를 시작하고 중지하는 과정은 다음과 같습니다.

    class YourApplication {
    void StartPreview() {
    auto pCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();
    pCameraController->StartCapture();

    // Add `HWND`.
    pCameraController->AddMyView(m_hMyView);
    }

    void StopPreview() {
    auto pCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();
    pCameraController->StopCapture();

    // Remove `HWND`.
    pCameraController->RemoveMyView(m_hMyView);
    }

    private:
    HWND m_hMyView;
    };
  • 5.5 버전부터 카메라 미리보기를 시작 및 중지하는 과정은 다음과 같습니다.

    class YourApplication {
    void StartPreview() {
    auto pCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();

    pCameraController->startPreview(m_hMyView);
    }

    void StopPreview() {
    auto pCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();

    pCameraController->StopPreview(m_hMyView);
    }

    private:
    HWND m_hMyView;
    };
  • 5.4 이하 버전의 경우 1대1 통화나 그룹 통화에서 로컬 사용자의 비디오를 렌더링하는 과정은 다음과 같습니다.

    class YourApplication {
    void ToVideoCall() {
    // Enable video call.
    m_pCall->EnableVideo(this, [](void* pUserData, bool bSuccess) {
    if(bSuccess == true) {
    YourApplication* pApp = static_cast<YourApplication*>(pUserData);
    // Succeed to change video call.
    auto pCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();

    // Start camera capture.
    pCameraController->StartCapture();

    // Add my view for rendering of local user's video.
    pCameraController->AddMyView(pApp->m_hMyView);
    }
    });
    }

    private:
    PlanetKit::PlanetKitCallPtr m_pCall;
    HWND m_hMyView;
    }
  • 5.5 버전부터 로컬 사용자의 비디오를 렌더링하는 과정은 다음과 같습니다.

    class YourApplication {
    void ToVideoCallAsResume() {
    // Enable video call.
    m_pCall->EnableVideo(PlanetKit::EInitialMyVideoState::PLNK_INITIAL_MY_VIDEO_STATE_RESUME, this, [](void* pUserData, bool bSuccess) {
    // Camera device will be started automatically on success of `EnableVideo()` because the first parameter is `EInitialMyVideoState::PLNK_INITIAL_MY_VIDEO_STATE_RESUME`.
    if(bSuccess == true) {
    YourApplication* pApp = static_cast<YourApplication*>(pUserData);
    // Add my view for rendering of local user's video.
    pApp->m_pCall->AddMyVideoView(pApp->m_hMyView);

    // Add peer view for rendering of remote user's video.
    pApp->m_pCall->AddPeerVideoView(pApp->m_hPeerView);
    }
    });
    }

    void ToVideoCallAsPaused() {
    // Enable video call.
    m_pCall->EnableVideo(PlanetKit::EInitialMyVideoState::PLNK_INITIAL_MY_VIDEO_STATE_PAUSE, this, [](void* pUserData, bool bSuccess) {
    // Camera device will be stopped automatically on success of `EnableVideo()` because the first parameter is `EInitialMyVideoState::PLNK_INITIAL_MY_VIDEO_STATE_PAUSE`.
    if(bSuccess == true) {
    // Add peer view for rendering of remote user's video.
    pApp->m_pCall->AddPeerVideoView(pApp->m_hPeerView);

    // Add my view for rendering of local user's video.
    pApp->m_pCall->AddMyVideoView(pApp->m_hMyView);

    // Currently, the sending video state is paused, and you can call PlanetKitCall::ResumeMyVideo() to start video capture.
    ...
    }
    });
    }


    private:
    PlanetKit::PlanetKitCallPtr m_pCall;
    HWND m_hMyView;
    HWND m_hPeerView;
    }

화면 공유 API 변경

  • 화면 공유 기능이 통화 세션과 연결되어 있기 때문에 렌더링 뷰를 등록하는 기능을 ScreenShareController에서 PlanetKitCallPlanetKitConference로 옮겼습니다.

API

변경
  • ScreenShareController, PlanetKitCall, PlanetKitConference class 1-to-1 callGroup call

    이전 버전PlanetKit 5.5
    bool ScreenShareController::AddMyView(WindowHandle hWind)bool PlanetKitCall::AddMyScreenShareVideoView(WindowHandle hWind)
    bool PlanetKitConference::AddMyScreenShareVideoView(WindowHandle hWind)
    bool ScreenShareController::RemoveMyView(WindowHandle hWind)bool PlanetKitCall::RemoveMyScreenShareVideoView(WindowHandle hWind)
    bool PlanetKitConference::RemoveMyScreenShareVideoView(WindowHandle hWind)
    bool ScreenShareController::RegisterMyVideoReceiver(IVideoReceiver *pReceiver)bool PlanetKitCall::AddMyScreenShareVideoReceiver(IVideoReceiver* pReceiver)
    bool PlanetKitConference::AddMyScreenShareVideoReceiver(IVideoReceiver* pReceiver)
    bool ScreenShareController::DeregisterMyVideoReceiver(IVideoReceiver *pReceiver)bool PlanetKitCall::RemoveMyScreenShareVideoReceiver(IVideoReceiver* pReceiver)
    bool PlanetKitConference::RemoveMyScreenShareVideoReceiver(IVideoReceiver* pReceiver)
    bool ScreenShareController::AddPeerView(WindowHandle hWind)bool PlanetKitCall::AddPeerScreenShareVideoView(WindowHandle hWind)
    bool ScreenShareController::AddPeerView(WindowHandle hWind, UserIdPtr pUserPtr)bool PlanetKitConference::AddPeerScreenShareVideoView(UserIdPtr pPeerID, WindowHandle hWind)
    bool ScreenShareController::RemovePeerView(WindowHandle hWind)bool PlanetKitCall::RemovePeerScreenShareVideoView(WindowHandle hWind)
    bool PlanetKitConference::RemovePeerScreenShareVideoView(WindowHandle hWind)
    bool ScreenShareController::RegisterPeersVideoReceiver(IVideoReceiver *pReceiver)bool PlanetKitCall::AddPeerScreenShareVideoReceiver(IVideoReceiver* pReceiver)
    bool ScreenShareController::DeregisterPeersVideoReceiver(IVideoReceiver *pReceiver)bool PlanetKitCall::RemovePeerScreenShareVideoReceiver(IVideoReceiver* pReceiver)
추가
  • PlanetKitCall class 1-to-1 call
    • void RemoveAllMyScreenShareVideoViewAndReceiver()
    • void RemoveAllPeerScreenShareVideoViewAndReceiver()
  • PlanetKitConference class Group call
    • void RemoveAllMyScreenShareVideoViewAndReceiver()
    • bool AddPeerScreenShareVideoReceiver(UserIdPtr pPeerID, IVideoReceiver* pReceiver)
    • bool RemovePeerScreenShareVideoReceiver(IVideoReceiver* pReceiver)
    • void RemoveAllPeerScreenShareVideoViewAndReceiver()

예제 코드

  • 새로 추가된 PlanetKitCall::AddMyScreenShareVideoView()PlanetKitConference::AddMyScreenShareVideoView()로 로컬 사용자의 화면 공유 비디오를 렌더링할 수 있습니다.

    class YourApplication {
    void StartScreenShare() {
    auto pScreenShareController = PlanetKit::PlanetKitManager::GetInstance()->GetScreenShareController();

    PlanetKit::ScreenShareInfoArray screenShareInfos;
    pScreenShareController->GetScreenShareInfos(screenShareInfos);

    // Choose screen share information and start.
    m_pCall->StartMyScreenShare(screenShareInfos.At(0), this, [](void* pUserData, bool bSuccess) {
    if(bSuccess == true) {
    YourApplication* pApp = static_cast<YourApplication*>(pUserData);

    pApp->m_pCall->AddMyScreenShareVideoView(m_hScreenShareView);
    }
    });
    }

    private:
    PlanetKit::PlanetKitCallPtr m_pCall;
    HWNd m_hScreenShareView;
    };
  • 원격 사용자의 화면 공유 비디오는 PlanetKitCall::AddPeerScreenShareVideoView()로 렌더링할 수 있습니다.

    class YourApplication {
    void StartRenderingPeerScreenShare() {
    m_pCall->AddPeerScreenShareVideoView(m_hScreenShareRenderWnd);
    }

    private:
    PlanetKit::PlanetKitCallPtr m_pCall;
    HWNd m_hScreenShareRenderWnd;
    };

오디오 후킹 기능 추가

  • 오디오 후킹(audio hooking) 기능을 이용하여 상대방에게 오디오를 전송하기 전에 오디오 데이터를 가져올 수 있습니다. 이 기능은 로컬 사용자의 음성을 변조하거나 오디오 데이터를 음성 인식에 활용하는 용도로 사용할 수 있습니다.

API

추가
  • AudioData struct 1-to-1 call
    • unsigned int unBufferSize
    • PlanetKitByte* pBuffer
  • EAudioSampleType enum 1-to-1 call
    • PLNK_AUDIO_SAMPLE_TYPE_SIGNED_FLOAT32 = 0
    • PLNK_AUDIO_SAMPLE_TYPE_SIGNED_SHORT16 = 1
  • PlanetKitHookedAudio class 1-to-1 call
    • const unsigned int GetSampleRate()
    • const unsigned int GetChannel()
    • const EAudioSampleType GetAudioSampleType()
    • const unsigned int GetSampleCount()
    • const unsigned long long GetSequenceNumber()
    • bool SetAudioData(const PlanetKitByte* pBuffer, unsigned int unBufferSize)
    • const AudioData GetAudioData()
  • IPlanetKitAudioHook class 1-to-1 call
    • void OnHooked(PlanetKitHookedAudioPtr pHookedAudio)
  • PlanetKitCall class 1-to-1 call
    • bool EnableHookMyAudio(IPlanetKitAudioHook* pAudioHook, void* pUserData = nullptr, ResultCallback pCallback = nullptr)
    • bool DisableHookMyAudio(void* pUserData = nullptr, ResultCallback pCallback = nullptr)
    • bool PutHookedMyAudioBack(PlanetKitHookedAudioPtr pHookedAudio)

예제 코드

  • 다음 샘플 코드는 음성을 변조하기 위해 오디오 후킹 기능을 사용하는 방법을 보여줍니다.

    // Implement audio modifier with IPlanetKitAudioHook
    class MyAudioHook : public PlanetKit::IPlanetKitAudioHook {
    public:
    void OnHooked(PlanetKit::PlanetKitHookedAudioPtr pHookedAudio) {
    const AudioData audioData = pHookedAudio->GetAudioData();

    if(m_pAudioBuffer == nullptr) {
    m_pAudioBuffer = new unsigned char[audioData.unBufferSize];
    }

    // Dump audio data
    memcpy(m_pAudioBuffer, audioData.pBuffer, audioData.unBufferSize);

    // Process `m_pAudioBuffer` as necessary
    ...

    // Set modified data to pHookedAudio
    pHookedAudio->SetAudioData(m_pAudioBuffer, audioData.unBufferSize);

    // Put audio data back to PlanetKit
    m_pCall->PutHookedMyAudioBack(pHookedAudio);
    }

    private:
    unsigned char* m_pAudioBuffer = nullptr;
    unsigned int m_unBufferSize = 0;

    // Prepare instance of `PlanetKitCall`
    PlanetKit::PlanetKitCallPtr m_pCall;
    }

    class MyApplication {
    public :
    // Method to enable audio hook
    void EnableAudioHook() {
    m_pCall->EnableHookMyAudio(&m_audioHook, this, [](void* pUserData, bool bSuccess){
    if(bSuccess == true) {
    OutputDebugStringW(L"Audio hook enabled successfully\n");
    }
    else {
    OutputDebugStringW(L"Failed to enable audio hook\n");
    }
    });
    }

    // Method to disable the audio hook
    void DisableAudioHook() {
    m_pCall->DisableHookMyAudio(this, [](void* pUserData, bool bSuccess) {
    if(bSuccess == true) {
    OutputDebugStringW(L"Audio hook disabled successfully\n");
    }
    else {
    OutputDebugStringW(L"Failed to disable audio hook\n");
    }
    });
    }

    private :
    // Prepare instance of PlanetKitCall
    PlanetKit::PlanetKitCallPtr m_pCall;

    // Prepare instance of MyAudioHook
    MyAudioHook m_audioHook;
    };

화면 잠금으로 인한 통화 종료 이유 추가

  • 이 통화 종료 이유는 사용자의 요청이나 시스템 비활성화로 인해 화면이 잠겼을 때 데스크톱 시스템에서만 발생합니다. 상대방이 데스크톱을 사용 중이고 상대방의 화면이 잠기는 경우 통화가 종료되며 이벤트를 통해 이 이유를 전달받습니다.

API

추가
  • EDisconnectReason enum 1-to-1 callGroup call
    • PLNK_DISCONNECT_REASON_DESKTOP_SCREEN_LOCKED = 1314