릴리스 노트
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
유형의 속성 또는 파라미터가ConferenceParam
및PlanetKitConference::EnableVideo()
에 추가되어 영상 통화를 시작하거나 영상 통화로 전환할 때 카메라 상태를 제어할 수 있습니다.
- 1대1 통화:
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 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()
삭제
CameraController
class 1-to-1 callGroup callbool 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
에서PlanetKitCall
및PlanetKitConference
로 옮겼습니다.
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 callvoid RemoveAllMyScreenShareVideoViewAndReceiver()
void RemoveAllPeerScreenShareVideoViewAndReceiver()
PlanetKitConference
class Group callvoid 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 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)
예제 코드
-
다음 샘플 코드는 음성을 변조하기 위해 오디오 후킹 기능을 사용하는 방법을 보여줍니다.
// 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 callPLNK_DISCONNECT_REASON_DESKTOP_SCREEN_LOCKED = 1314