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 toMakeCallParam
,PlanetKitCall::AcceptCall()
, andPlanetKitCall::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 toConferenceParam
andPlanetKitConference::EnableVideo()
, allowing you to control the camera state when starting or switching to a video call.
- 1-to-1 call: Property or parameter of type
API
Changed
-
CameraController
,PlanetKitCall
,PlanetKitConference
classes 1-to-1 callGroup callPrevious 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 callPrevious 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 callPrevious 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)
Added
EVideoControlResult
enum 1-to-1 callGroup callEVideoControlResult_PreviewAlreadyExist
EVideoControlResult_CreateRenderFail
EVideoControlResult_CameraIsAlreadyInUseByAnotherApplication
EVideoControlResult_PreviewHandleIsInvalid
EVideoControlResult_PreviewReceiverIsInvalid
EInitialMyVideoState
enum 1-to-1 callGroup callPLNK_INITIAL_MY_VIDEO_STATE_RESUME
PLNK_INITIAL_MY_VIDEO_STATE_PAUSE
ECameraControlResult
enum 1-to-1 callGroup callPLNK_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 callbool StartPreview(WindowHandle hWind)
bool StartPreview(IVideoReceiver* pReceiver)
bool StopPreview(WindowHandle hWind)
bool StopPreview(IVideoReceiver* pReceiver)
ConferenceParam
class Group callEInitialMyVideoState GetInitialMyVideoState()
void SetInitialMyVideoState(EInitialMyVideoState eInitialMyVideoState)
MakeCallParam
class 1-to-1 callEInitialMyVideoState GetInitialMyVideoState()
void SetInitialMyVideoState(EInitialMyVideoState eInitialMyVideoState)
PlanetKitCall
class 1-to-1 callvoid RemoveAllMyVideoViewAndReceiver()
void RemoveAllPeerVideoViewAndReceiver()
PlanetKitConference
class Group callvoid RemoveAllMyVideoViewAndReceiver()
bool AddPeerVideoReceiver(UserIdPtr pPeerID, IVideoReceiver* pReceiver)
bool RemovePeerVideoReceiver(IVideoReceiver* pReceiver)
void RemoveAllPeerVideoViewAndReceiver()
Removed
CameraController
class 1-to-1 callGroup callbool InitializeRender()
bool FinalizeRender()
EVideoControlResult StartCapture()
bool StopCapture()
Example code
-
The newly added
CameraController::StartPreview(WindowHandle)
andCameraController::StartPreview(IVideoReceiver*)
allow you to preview video from the local user's camera. The following is an example of usingCameraController::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 useCameraController::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)
orAddMyVideoView(IVideoReceiver*)
. -
The camera automatically turns on and off when
EnableVideo()
andDisableVideo()
are called. -
After switching to a video call using
EnableVideo()
, you can register a view for rendering usingAddMyVideoView()
, 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()
andCameraController::StopCapture()
has been removed. -
For the local user's preview, use
CameraController::StartPreview()
, and after a call is connected, usePlanetKitCall::AddMyVideoView()
orPlanetKitConference::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
toPlanetKitCall
andPlanetKitConference
.
API
Changed
-
ScreenShareController
,PlanetKitCall
,PlanetKitConference
classes 1-to-1 callGroup callPrevious 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)
Added
PlanetKitCall
class 1-to-1 callvoid RemoveAllMyScreenShareVideoViewAndReceiver()
void RemoveAllPeerScreenShareVideoViewAndReceiver()
PlanetKitConference
class Group callvoid RemoveAllMyScreenShareVideoViewAndReceiver()
bool AddPeerScreenShareVideoReceiver(UserIdPtr pPeerID, IVideoReceiver* pReceiver)
bool RemovePeerScreenShareVideoReceiver(IVideoReceiver* pReceiver)
void RemoveAllPeerScreenShareVideoViewAndReceiver()
Example code
-
The newly added
PlanetKitCall::AddMyScreenShareVideoView()
andPlanetKitConference::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 callunsigned int unBufferSize
PlanetKitByte* pBuffer
EAudioSampleType
enum 1-to-1 callPLNK_AUDIO_SAMPLE_TYPE_SIGNED_FLOAT32 = 0
PLNK_AUDIO_SAMPLE_TYPE_SIGNED_SHORT16 = 1
PlanetKitHookedAudio
class 1-to-1 callconst 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 callvoid OnHooked(PlanetKitHookedAudioPtr pHookedAudio)
PlanetKitCall
class 1-to-1 callbool 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 callPLNK_DISCONNECT_REASON_DESKTOP_SCREEN_LOCKED = 1314