グループビデオ通話
グループビデオ通話を実装するサンプルコードです。
前提条件
開始する前に、次の作業が必要です。
- 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::ConferenceVideoUpdatedParamPtr 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.
PlanetKit::SharedPtr<ConferenceEventListener> m_pConferenceEventListener = PlanetKit::MakeAutoPtr<ConferenceEventListener>();
// Prepare member variables to manage MyMediaStatusPtr and MyMediaStatusListener instances
PlanetKit::MyMediaStatusPtr m_pMyMediaStatus;
PlanetKit::SharedPtr<MyMediaStatusListener> m_pMyMediaStatusListener = PlanetKit::MakeAutoPtr<MyMediaStatusListener>();
};
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_pConferenceEventListener);
// 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();
// The currently used microphone device must be passed to JoinConference() as an argument.
// If the microphone in use has not been set, set it using the ChangeMic() of AudioManager.
// If the microphone is not set, PlanetKit::NullOptional will be retrieved by GetCurrentMic().
// Passing PlanetKit::NullOptional to JoinConference() will start the conference without a microphone device.
auto pMic = pPlanetKitManager->GetAudioManager()->GetCurrentMic();
PlanetKit::SStartResult sStartResult = pPlanetKitManager->JoinConference(pConferenceParam, pMic, &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_pMyMediaStatusListener);
}
ローカルユーザーのためのビデオビュー追加
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_peerControlEventListener);
};
private:
PlanetKit::PeerControlPtr m_pPeerControl;
// Window handle to render peer's video.
HWND m_hVideoWnd;
// Event listener for getting PeerControl's event.
PlanetKit::SharedPtr<PeerControlEventListener> m_peerControlEventListener = PlanetKit::MakeAutoPtr<PeerControlEventListener>( 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();
}