Group video call
This page provides a code example for implementing a group video call.
Prerequisites
Before you begin, you must do the following:
- Initialize PlanetKit.
- Get a proper access token.
- Check the overall API usage flow in Group call flow.
Considerations for implementing a group audio call
After calling JoinConference()
, you must check the bSuccess
field of the returned SStartResult
first and then reason
field if the call failed.
- If
bSuccess
istrue
, it means success. - Otherwise, it means failure and you must take an appropriate action based on the
reason
.
Implement event listeners
Implement the event listeners to be used on the call.
IConferenceEvent
is an abstract class that provides an interface to handle status change events of a group call. Create a class that extendsIConferenceEvent
and override the functions.IMyMediaStatusEvent
is used to handle the local user's media status change events. You can update the local user's UI based on these events, such as when the mic becomes muted or unmuted, when the audio description is updated, or when the video status is updated. Create a class that extendsIMyMediaStatusEvent
and override the functions.
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.
//
};
Preview the local user's video
The preview feature allows the local user to preview their own video regardless of the group call session.
To starting previewing the local user's video, call 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);
To stop previewing the local user's video, call CameraController::StopPreview()
.
// Get PlanetKit::CameraController instance from PlanetKit::PlanetKitManager.
auto planetKitCameraController = PlanetKit::PlanetKitManager::GetInstance()->GetCameraController();
// Stop preview.
planetKitCameraController->StopPreview(hWnd);
Join a group call
To join a group call, call JoinConference()
with a proper ConferenceParamPtr
.
- To join a group video call, call
ConferenceParam::SetIsVideoCall()
withtrue
. - The local user's initial video state can be set with
ConferenceParam::SetInitialMyVideoState()
.- The default value of the initial video state is
PLNK_INITIAL_MY_VIDEO_STATE_RESUME
. - If the local user's initial video state is set to paused by calling
SetInitialMyVideoState()
withPLNK_INITIAL_MY_VIDEO_STATE_PAUSE
, the local user's video is not transmitted. The local user's video can be transmitted by callingResumeMyVideo()
after the call is connected.
- The default value of the initial video state is
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
}
}
Set the media status listener for the local user
Once the call is connected, add the media status listener for the local user.
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);
}
Add a video view for the local user
Call AddMyVideoView()
to add a video view where the local user's video will be rendered. The rendering of the video starts or stops according to the local user's video status.
void YourApplication::AddMyVideoViewExample(HWND hRenderWnd) {
// Add window handle. PlanetKit will render local user's video after adding window handle.
m_pConference->AddMyVideoView(hRenderWnd);
}
Create peer control for each peer
When the peer list is updated, create PeerControl
for newly added peers and register a event listener that implements IPeerControlEvent
. You can handle the status change of each peer using the the event listener.
// 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.
...
}
}
Leave a group call
To leave a group call, call LeaveConference()
.
void YourApplication::LeaveConferenceExample() {
// Unregister the event listener
this->m_pMyMediaStatus->Unregister();
m_pConference->LeaveConference();
}