Skip to main content
Version: 5.5

Release notes

This page provides the release notes of PlanetKit 5.5 for Windows.

PlanetKit 5.5.2

Release date: 2025-02-27

Fix occasional crash that occurred in specific situations

  • Fixed an occasional crash that occurred on certain devices immediately after enabling airplane mode during a call.

PlanetKit 5.5.1

Release date: 2025-01-15

Fix an issue with delay in initiating voice transmission at the start of a call

Fixed an issue where there was a 500ms delay in initiating the transmission of the local user's voice at the start of 1-to-1 calls and group calls.

PlanetKit 5.5.0

Release date: 2024-12-09

Enhance camera device management API

  • We have revamped the camera device management API to streamline the process of handling video capture.
  • The camera device management API has been enhanced so that the camera is turned on only when sending data to Planet Cloud.
  • You can now control the initial state of the camera in video calls.
    • 1-to-1 call: Property or parameter of type EInitialMyVideoState have been added to MakeCallParam, PlanetKitCall::AcceptCall(), and PlanetKitCall::EnableVideo(), allowing you to control the camera state when starting or switching to a video call.
    • Group call: Property or parameter of type EInitialMyVideoState have been added to ConferenceParam and PlanetKitConference::EnableVideo(), allowing you to control the camera state when starting or switching to a video call.

API

Changed
  • CameraController, PlanetKitCall, PlanetKitConference classes 1-to-1 callGroup call

    PreviousPlanetKit 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

    PreviousPlanetKit 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

    PreviousPlanetKit 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)
Added
  • 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()
Removed
  • CameraController class 1-to-1 callGroup call
    • bool InitializeRender()
    • bool FinalizeRender()
    • EVideoControlResult StartCapture()
    • bool StopCapture()

Example code

  • The newly added CameraController::StartPreview(WindowHandle) and CameraController::StartPreview(IVideoReceiver*) allow you to preview video from the local user's camera. The following is an example of using 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;
    }
  • If you want to handle video processing directly, you can implement your own video receiver by inheriting from IVideoReceiver and use 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;
    }
  • To render the local user's video on the screen after connecting to a 1-to-1 call or a group call, you can use AddMyVideoView(WindowHandle) or AddMyVideoView(IVideoReceiver*).

  • The camera automatically turns on and off when EnableVideo() and DisableVideo() are called.

  • After switching to a video call using EnableVideo(), you can register a view for rendering using AddMyVideoView(), and the video will appear on the screen.

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

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

Migration

  • The functionality to directly control the camera using CameraController::StartCapture() and CameraController::StopCapture() has been removed.

  • For the local user's preview, use CameraController::StartPreview(), and after a call is connected, use PlanetKitCall::AddMyVideoView() or PlanetKitConference::AddMyVideoView().

  • In version 5.4 or lower, the process for starting and stopping camera preview is as follows.

    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;
    };
  • Starting with version 5.5, the process for starting and stopping camera preview is as follows.

    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;
    };
  • In version 5.4 or lower, the process for rendering the local user's video on a 1-to-1 call or a group call is as follows.

    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;
    }
  • Starting with version 5.5, the process for rendering the local user's video is as follows.

    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;
    }

Change screen share API

  • Since the screen share functionality is tied to the call session, the feature for registering a rendering view has been moved from ScreenShareController to PlanetKitCall and PlanetKitConference.

API

Changed
  • ScreenShareController, PlanetKitCall, PlanetKitConference classes 1-to-1 callGroup call

    PreviousPlanetKit 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)
Added
  • 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()

Example code

  • The newly added PlanetKitCall::AddMyScreenShareVideoView() and PlanetKitConference::AddMyScreenShareVideoView() can render the local user's screen share video.

    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;
    };
  • You can render a remote user's screen share video with PlanetKitCall::AddPeerScreenShareVideoView().

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

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

Add the audio hooking feature

  • Audio hooking allows you to get the audio data before Planet Cloud transmits audio to a peer. This function can be used to modify the local user's voice or use the audio data for speech recognition.

API

Added
  • 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)

Example code

  • The following sample code shows how to use the audio hooking function for voice modification.

    // 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;
    };

Add a disconnect reason for screen lock

  • This disconnect reason occurs only on desktop systems when the desktop screen is locked by the user or due to system inactivity. When the peer is using a desktop and the screen is locked, the call will end and you will receive this reason through an event.

API

Added
  • EDisconnectReason enum 1-to-1 callGroup call
    • PLNK_DISCONNECT_REASON_DESKTOP_SCREEN_LOCKED = 1314