그룹 영상 통화
그룹 영상 통화를 구현하는 예제 코드입니다.
필수 조건
시작하기 전에 다음 작업을 수행해야 합니다.
- PlanetKit을 초기화하세요.
- 적절한 액세스 토큰을 획득하세요.
- 그룹 통화 흐름에서 전반적인 API 사용 과정을 확인하세요.
그룹 영상 통화 구현 시 고려 사항
JoinConference()
를 호출한 다음에는 반환된 SStartResult
의 bSuccess
필드로 성공 여부를 확인하고 실패한 경우 reason
필드도 확인해야 합니다.
bSuccess
가true
인 경우 성공을 의미합니다.- 그렇지 않으면 실패를 의미하며
reason
에 따라 적절한 조치를 취해야 합니다.
이벤트 리스너 구현
다음처럼 통화에서 사용될 이벤트 리스너를 구현하세요.
IConferenceEvent
는 그룹 통화의 상태 변경 이벤트 처리용 인터페이스를 제공하는 추상 클래스입니다.IConferenceEvent
를 상속한 클래스를 만들고, 함수를 오버라이드하세요.IMyMediaStatusEvent
는 로컬 사용자의 미디어 상태 변경 이벤트 처리용 인터페이스를 제공하는 추상 클래스입니다. 마이크가 음소거되거나 음소거 해제되는 경우나 오디오 설명이 업데이트되는 경우 또는 비디오 상태가 업데이트되는 경우 등 이벤트를 기반으로 로컬 사용자의 UI를 업데이트할 수 있습니다.IMyMediaStatusEvent
를 상속한 클래스를 만들고, 함수를 오버라이드하세요.
class ConferenceEventListener : public PlanetKit::IConferenceEvent {
public:
// This is called when the call is connected.
// Write your own code in function.
void OnConnected(PlanetKit::PlanetKitConferencePtr pPlanetKitConference, PlanetKit::ConferenceConnectedParamPtr pParam) override;
// This is called when the call is disconnected.
// Write your own code in function.
void OnDisconnected(PlanetKit::PlanetKitConferencePtr pPlanetKitConference, PlanetKit::ConferenceDisconnectedParamPtr pParam) override;
// This is called when the list of peers is updated.
// Write your own code in function.
void OnPeerListUpdate(PlanetKit::PlanetKitConferencePtr pPlanetKitConference, PlanetKit::ConferencePeerUpdateParamPtr pParam) override;
// This is called when the video of one or more peers is updated.
// Write your own code in function.
void OnPeersVideoUpdated(PlanetKit::PlanetKitConferencePtr pPlanetKitConference, PlanetKit::ConferenceVideoUpdatedParam* pParam) override;
...
//
// Also, you should implement other override functions.
//
};
class MyMediaStatusListener : public PlanetKit::IMyMediaStatusEvent {
public :
// This is called when the local user's audio is muted.
// Write your own code in function.
void OnMuted(PlanetKit::MyMediaStatusPtr pMyStatus) override;
// This is called when the local user's audio is unmuted.
// Write your own code in function.
void OnUnmuted(PlanetKit::MyMediaStatusPtr pMyStatus) override;
// This is called when the local user's audio description is updated.
// Write your own code in function.
void OnMyAudioDescriptionUpdated(PlanetKit::MyMediaStatusPtr pMyStatus, const PlanetKit::MyAudioDescription& sMyAudioDescription) override;
// This is called when the local user's video status is updated.
// Write your own code in function.
void OnUpdateVideoStatus(PlanetKit::MyMediaStatusPtr pMyStatus, PlanetKit::VideoStatus sStatus) override;
...
//
// Also, you should implement other override functions.
//
};
로컬 사용자의 비디오 미리보기
미리보기 기능을 사용하면 로컬 사용자가 그룹 통화 세션과 관계없이 자신의 비디오를 미리 볼 수 있습니다.
로컬 사용자의 비디오 미리보기를 시작하려면 CameraController::StartPreview()
를 호출하세요.
// Get PlanetKit::CameraController instance from PlanetKit::PlanetKitManager.
auto planetKitCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();
// Prepare your window handle (HWND) where you want to render video from the camera device.
HWND hWnd;
// Start preview.
planetKitCameraController->StartPreview(hWnd);
로컬 사용자의 비디오 미리보기를 종료하려면 CameraController::StopPreview()
를 호출하세요.
// Get PlanetKit::CameraController instance from PlanetKit::PlanetKitManager.
auto planetKitCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();
// Stop preview.
planetKitCameraController->StopPreview(hWnd);
그룹 통화 입장
그룹 통화에 입장하려면 적절한 ConferenceParamPtr
인자와 함께 JoinConference()
를 호출하세요.
- 그룹 영상 통화에 입장하도록
true
를 인자로ConferenceParam::SetIsVideoCall()
을 호출하세요. - 로컬 사용자의 초기 비디오 상태는
ConferenceParam::SetInitialMyVideoState()
로 설정할 수 있습니다.- 초기 비디오 상태의 기본값은
PLNK_INITIAL_MY_VIDEO_STATE_RESUME
입니다. PLNK_INITIAL_MY_VIDEO_STATE_PAUSE
를 인자로SetInitialMyVideoState()
를 호출하여 로컬 사용자의 초기 비디오 상태가 일시 중지로 설정된 경우 로컬 사용자의 비디오는 전송되지 않습니다. 이 경우 로컬 사용자의 비디오는 통화가 연결된 후ResumeMyVideo()
를 호출하여 전송할 수 있습니다.
- 초기 비디오 상태의 기본값은
class YourApplication {
private :
// Prepare PlanetKitConference instance.
PlanetKit::PlanetKitConferencePtr m_pConference;
// Prepare call event listener instance.
ConferenceEventListener m_cConferenceEventListener;
// Prepare member variables to manage MyMediaStatusPtr and MyMediaStatusListener instances
PlanetKit::MyMediaStatusPtr m_pMyMediaStatus;
MyMediaStatusListener m_cMyMediaStatusListener;
};
void YourApplication::JoinConferenceExample(const std::wstring strRoomId, const std::wstring strAccessToken, PlanetKit::EInitialMyVideoState eInitialMyVideoState) {
// Prepare local user's ID.
std::wstring strUserId = "local user's user id";
std::wstring strServiceId = "local user's service id";
// Create the UserId object.
PlanetKit::UserIdPtr pUserId = PlanetKit::UserId::Create(strUserId.c_str(), strServiceId.c_str());
// Create ConferenceParam with Create API.
PlanetKit::ConferenceParamPtr pConferenceParam = PlanetKit::ConferenceParam::CreateWithAccessToken(
pUserId,
strRoomId.c_str(),
strServiceId.c_str(),
strAccessToken.c_str()
);
// Set the call type to video call
pConferenceParam->SetIsVideoCall(true);
// Set the initial video state
pConferenceParam->SetInitialMyVideoState(eInitialMyVideoState);
// Set required parameter.
pConferenceParam->SetConferenceEvent(&m_cConferenceEventListener);
// Now you have to create a PlanetKit::PlanetKitConference type object
// through the PlanetKit::PlanetKitManager::JoinConference() function.
// Please note that the PlanetKit::PlanetKitConference type object is the main call instance
// that controls call-related functions after the call setup completion.
PlanetKit::PlanetKitManagerPtr pPlanetKitManager = PlanetKit::PlanetKitManager::GetInstance();
PlanetKit::SStartResult sStartResult = pPlanetKitManager->JoinConference(pConferenceParam, &m_pConference);
if (sStartResult.bSuccess == false) {
// Handle an error by referring to sStartResult.reason
}
}
로컬 사용자에 대한 미디어 상태 리스너 설정
통화가 연결되면 로컬 사용자에 대한 미디어 상태 리스너를 설정하세요.
void YourApplication::SetMyMediaStatusListenerExample() {
PlanetKit::MyMediaStatusPtr pMyMediaStatus = m_pConference->GetMyMediaStatus();
// Keep the local user's media status instance
this->m_pMyMediaStatus = pMyMediaStatus;
// Register the event listener
this->m_pMyMediaStatus->Register(&m_cMyMediaStatusListener);
}
로컬 사용자를 위한 비디오 뷰 추가
AddMyVideoView()
를 호출하여 로컬 사용자의 비디오가 렌더링될 비디오 뷰를 추가하세요. 비디오 렌더링은 로컬 사용자의 비디오 상태에 따라 시작되거나 중지됩니다.
void YourApplication::AddMyVideoViewExample(HWND hRenderWnd) {
// Add window handle. PlanetKit will render local user's video after adding window handle.
m_pConference->AddMyVideoView(hRenderWnd);
}
각 피어에 대한 피어 컨트롤 생성
피어 목록이 업데이트되면 새로 추가된 피어에 대해 PeerControl
을 생성하고 IPeerControlEvent
를 구현하는 이벤트 리스너를 등록하세요. 이벤트 리스너를 사용하여 각 피어의 상태 변경을 처리할 수 있습니다.
// Prepare event listener class for getting peer's media change events.
class PeerControlContainer;
class PeerControlEventListener : public PlanetKit::IPeerControlEvent {
public:
PeerControlEventListener(PeerControlContainer* pParentContainer) { m_pParentContainer = pParentContainer; }
void OnInitialized(PlanetKit::PeerControlPtr pPeerControl, bool bResult) override;
void OnMuted(PlanetKit::PeerControlPtr pPeerControl) override;
void OnUnmuted(PlanetKit::PeerControlPtr pPeerControl) override;
void OnVideoUpdated(PlanetKit::PeerControlPtr pPeerControl, PlanetKit::SubgroupPtr pSubgroup, const PlanetKit::VideoStatus& videoStatus) override {
switch(videoStatus.eVideoState) {
case PlanetKit::EVideoState::PLNK_VIDEO_STATE_DISABLED:
// The peer's video is disabled.
// The video stops even if you don't call PeerControl::StopVideo() and PeerControl::ClearView().
break;
case PlanetKit::EVideoState::PLNK_VIDEO_STATE_ENABLED:
// You can start rendering peer's video with this sample code.
pPeerControl->StartVideo(pSubgroup->GetSubgroupName(), PlanetKit::EVideoResolution::PLNK_VIDEO_RESOLUTION_RECOMMENDED);
// Set HWND to render peer's video.
pPeerControl->SetView(m_pParentContainer->m_hVideoWnd);
break;
case PlanetKit::EVideoState::PLNK_VIDEO_STATE_PAUSED:
// Write your own code for paused video.
break;
}
}
void OnDisconnected(PlanetKit::PeerControlPtr pPeerControl) override {
pPeerControl->Unregister();
}
...
private:
PeerControlContainer* m_pParentContainer = nullptr;
};
// Prepare PeerControlContainer for using PlanetKit::PeerControl
class PeerControlContainer {
public:
PeerControlContainer(PlanetKit::PeerControlPtr pPeerControl) {
// Keep instance of PeerControl.
m_pPeerControl = pPeerControl;
// Register my event listener to instance of PeerControl.
m_pPeerControl->Register(&m_cPeerControlEventListener);
};
private:
PlanetKit::PeerControlPtr m_pPeerControl;
// Window handle to render peer's video.
HWND m_hVideoWnd;
// Event listener for getting PeerControl's event.
PeerControlEventListener m_cPeerControlEventListener{ this };
};
// You can handle added or removed peers in PlanetKit::IConferenceEvent::OnPeerListUpdate()
void ConferenceEventListener::OnPeerListUpdate(PlanetKit::PlanetKitConferencePtr pPlanetKitConference, PlanetKit::ConferencePeerUpdateParamPtr pParam) {
// Get the list of added peers.
auto const& arrAdded = pParam->GetAddedPeer();
for(int nIdx = 0; nIdx < arrAdded.Size(); ++nIdx) {
// Create PeerControlContainer instance.
PeerControlContainer* pPeerControlContainer = new PeerControlContainer(arrAdded.At(nIdx)->CreatePeerControl());
// Keep instance of PeerControlContainer as you want to.
...
}
}
그룹 통화 퇴장
그룹 통화에서 퇴장하려면 LeaveConference()
를 호출하세요.
void YourApplication::LeaveConferenceExample() {
// Unregister the event listener
this->m_pMyMediaStatus->Unregister();
m_pConference->LeaveConference();
}