1対1ビデオ通話
1対1ビデオ通話を実装するサンプルコードです。
前提条件
開始する前に、次の作業が必要です。
- PlanetKitを初期化してください。
- 適切なアクセストークンを取得してください。
- 1対1通話フローにて、APIを使用するための全般的なプロセスを確認してください。
1対1ビデオ通話実装時の考慮事項
受信者側で通話の通知を受けるには、通知用のシステムを実装するか、UWP(Universal Windows Platform)を利用してアプリケーションを実装後にプッシュ通知システムを連携する必要があります。
また、受信者にどのような情報を渡すべきかを知っておく必要があります。アプリサーバーの役割にて、アプリケーションが渡すべきデータであるcc_param
について確認できます。
MakeCall()
、VerifyCall()
を呼び出した後は、返されたSStartResult
のbSuccess
フィールドで成否を確認し、失敗した場合は、reason
フィールドも確認する必要があります。
bSuccess
がtrue
の場合、成功を意味します。- それ以外は失敗を意味し、
reason
に応じて適切に処理する必要があります。
イベントリスナーの実装
以下のように、通話で使用されるイベントリスナーを実装します。
ICallEvent
は、1対1通話のステータス変更イベント処理用のインターフェースを提供する抽象クラスです。ICallEvent
を継承したクラスを作成し、関数をオーバーライドします。IMyMediaStatusEvent
は、ローカルユーザーのメディアステータスの変更イベント処理用インターフェースを提供する抽象クラスです。マイクがミュートもしくはミュート解除された場合やオーディオの説明が更新された場合、ビデオのステータスが変更された場合など、イベントに基づいてローカルユーザーのUIを更新できます。IMyMediaStatusEvent
を継承したクラスを作成し、関数をオーバーライドします。
class CallEventListener : public PlanetKit::ICallEvent {
public:
// This is called after making a call on the caller side.
// Write your own code in function.
void OnWaitAnswer(PlanetKit::PlanetKitCallPtr pPlanetKitCall) override;
// This is called after making a call on the callee side.
// Write your own code in function.
void OnVerified(PlanetKit::PlanetKitCallPtr pPlanetKitCall, PlanetKit::CallVerifiedParamPtr pVerifiedParam) override;
// This is called after the call is connected on both sides.
// Write your own code in function.
void OnConnected(PlanetKit::PlanetKitCallPtr pPlanetKitCall, PlanetKit::CallConnectedParamPtr pConnectedParam) override;
// This is called after the call is disconnected on both sides.
// Write your own code in function.
void OnDisconnected(PlanetKit::PlanetKitCallPtr pPlanetKitCall, PlanetKit::CallDisconnectedParamPtr pDisconnectedParam) 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.
//
};
ローカルユーザーのビデオプレビュー
プレビュー機能を使用すると、ローカルユーザーが1対1通話セッションに関係なく、自分のビデオをプレビューできます。
ローカルユーザーのビデオプレビューを開始するには、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);
通話の作成(発信側)
新たに通話を開始するには、適切なMakeCallParamPtr
引数と共にMakeCall()
を呼び出します。
- ビデオ通話を作成するために
true
を引数としてMakeCallParam::SetIsVideoCall()
を呼び出します。 - 発信者のビデオの初期状態は、
MakeCallParam::SetInitialMyVideoState()
で設定できます。- ビデオの初期状態のデフォルト値は、
PLNK_INITIAL_MY_VIDEO_STATE_RESUME
です。 PLNK_INITIAL_MY_VIDEO_STATE_PAUSE
を引数としてSetInitialMyVideoState()
を呼び出して発信者のビデオの初期状態が一時停止に設定された場合、発信者のビデオは送信されません。この場合、発信者のビデオは通話が接続された後、ResumeMyVideo()
を呼び出して送信できます。
- ビデオの初期状態のデフォルト値は、
class YourApplication {
private :
// Prepare PlanetKitCall instance.
PlanetKit::PlanetKitCallPtr m_pCall;
// Prepare call event listener instance.
PlanetKit::SharedPtr<CallEventListener> m_pCallEventListener = PlanetKit::MakeAutoPtr<CallEventListener>();
// Prepare member variables to manage MyMediaStatusPtr and MyMediaStatusListener instances
PlanetKit::MyMediaStatusPtr m_pMyMediaStatus;
PlanetKit::SharedPtr<MyMediaStatusListener> m_pMyMediaStatusListener = PlanetKit::MakeAutoPtr<MyMediaStatusListener>();
};
void YourApplication::MakeCallExample(const std::wstring& wstrAccessToken, PlanetKit::EInitialMyVideoState eInitialMyVideoState) {
// Prepare local user's ID and peer's ID.
std::wstring strMyUserId = "your user id";
std::wstring strMyServiceId = "your service id";
std::wstring strPeerUserId = "peer id";
std::wstring strPeerServiceId = "peer service id";
// Create myId and peerId.
PlanetKit::UserIdPtr pMyId = PlanetKit::UserId::Create(strMyUserId.c_str(), strMyServiceId.c_str());
PlanetKit::UserIdPtr pPeerId = PlanetKit::UserId::Create(strPeerUserId.c_str(), strPeerServiceId.c_str());
// Create MakeCallParam with Create API.
PlanetKit::MakeCallParamPtr pMakeCallParam = PlanetKit::MakeCallParam::CreateWithAccessToken(
pMyId,
pPeerId,
wstrAccessToken.c_str()
);
// Set the call type to video call
pMakeCallParam->SetIsVideoCall(true);
// Set the initial video state
pMakeCallParam->SetInitialMyVideoState(eInitialMyVideoState);
// Set required parameter.
pMakeCallParam->SetCallEvent(m_pCallEventListener);
// Now you have to create a PlanetKit::PlanetKitCall type object
// through the PlanetKit::PlanetKitManager::MakeCall() function.
// Please note that the PlanetKit::PlanetKitCall 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 MakeCall() 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 MakeCall() will start the call without a microphone device.
auto pMic = pPlanetKitManager->GetAudioManager()->GetCurrentMic();
PlanetKit::SStartResult sStartResult = pPlanetKitManager->MakeCall(pMakeCallParam, pMic, &m_pCall);
if (sStartResult.bSuccess == false) {
LOG_ERROR("MakeCall() failed. Reason: " << sStartResult.reason);
}
}
通話通知の受信(受信側)
Windows用PlanetKitを使用する際には、指定した受信者にcc_param
を引き渡すシステムを備える必要があります。
以下のコードは、次のような前提で作成しました。
- すべてのクライアントのアプリケーションは、特定のユーザーに新しい電話がかかってきたかどうかを知らせるために、定期的にアプリサーバーでの通話通知を確認します。
- 通知データは、JSON形式の文字列で渡します。
void YourApplication::UpdateNotificationFromServer(std::string& strCCParam) {
char strPushDataFromAppServer[2048];
// The app server can deliver cc_param with the desired protocol through the application channel.
// We assume the app server forwards cc_param in JSON string format in this example.
// The strPushDataFromAppServer is a JSON string containing cc_param received from the app server.
// strPushDataFromAppServer looks like this:
//
//{
// ...,
// "cc_param": "...",
// ...
//}
// We assume GetNotificationThroughApplicationChannel() reads JSON string including cc_param.
GetNotificationThroughApplicationChannel(strPushDataFromAppServer);
// We assume JSON-C open source library (https://github.com/json-c/json-c) is used to parse JSON strings.
json_object *pJsonObjectResponse = json_tokener_parse(strPushDataFromAppServer);
json_object *pJsonObjectCCParam = json_object_object_get(pJsonObjectResponse, "cc_param");
strCCParam = json_object_get_string(pJsonObjectCCParam);
return;
}
通話の受信(受信側)
VerifyCallParam
を作成し、VerifyCall()
を呼び出して通話を受信します。
class YourApplication {
private :
// Prepare PlanetKitCall instance.
PlanetKit::PlanetKitCallPtr m_pCall;
// Prepare callback event listener instance.
PlanetKit::SharedPtr<CallEventListener> m_pCallEventListener = PlanetKit::MakeAutoPtr<CallEventListener>();
// Prepare member variables to manage MyMediaStatusPtr and MyMediaStatusListener instances
PlanetKit::MyMediaStatusPtr m_pMyMediaStatus;
PlanetKit::SharedPtr<MyMediaStatusListener> m_pMyMediaStatusListener = PlanetKit::MakeAutoPtr<MyMediaStatusListener>();
};
void YourApplication::VerifyCallExample(std::string& strCCParam) {
// Prepare for VerifyCall API's parameter.
PlanetKit::VerifyCallParamPtr pVerifyCallParam;
// Prepare my ID.
std::wstring strMyUserId = "your user id";
std::wstring strServiceId = "Your service id";
PlanetKit::UserIdPtr pMyId = PlanetKit::UserId::Create(strMyUserId.c_str(), strServiceId.c_str());
// Now you can create CCParamPtr with the PlanetKitManager instance.
PlanetKit::PlanetKitManagerPtr pPlanetKitManager = PlanetKit::PlanetKitManager::GetInstance();
PlanetKit::CCParamPtr pCCParam = pPlanetKitManager->CreateCCParam(strCCParam.c_str());
// Create VerifyCallParam.
pVerifyCallParam = PlanetKit::VerifyCallParam::Create(pMyId, pCCParam);
// Set the required parameter.
pVerifyCallParam->SetCallEvent(m_pCallEventListener);
// Now you have to create a PlanetKit::PlanetKitCall type object
// through the PlanetKit::PlanetKitManager::VerifyCall() function.
// Please note that the PlanetKit::PlanetKitCall type object is the main call instance
// that controls call-related functions after the call setup completion.
PlanetKit::PlanetKitCallPtr pPlanetKitCall;
// The currently used microphone device must be passed to VerifyCall() 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 VerifyCall() will start the call without a microphone device.
auto pMic = pPlanetKitManager->GetAudioManager()->GetCurrentMic();
PlanetKit::SStartResult sStartResult = pPlanetKitManager->VerifyCall(pVerifyCallParam, pMic, &m_pCall);
if (sStartResult.bSuccess == false) {
LOG_ERROR("VerifyCall() failed. Reason: " << sStartResult.reason);
}
}
通話の応答(受信側)
一般的に通話を受信した後、通話を受けるかどうかを決める時間が必要です。通話に応答するには、AcceptCall()
を呼び出します。
- 受信者のビデオの初期状態は、
AcceptCall()
のeInitialMyVideoState
パラメーターで設定できます。eInitialMyVideoState
パラメーターのデフォルト値は、PLNK_INITIAL_MY_VIDEO_STATE_RESUME
です。PLNK_INITIAL_MY_VIDEO_STATE_PAUSE
を引数として引き渡し、受信者のビデオの初期状態が一時停止に設定された場合、受信者のビデオは送信されません。この場合、受信者のビデオは通話が接続された後、ResumeMyVideo()
を呼び出して送信できます。
m_pCall
変数は、VerifyCall()
で検証済みのPlanetKitCall
インスタンスです。
void YourApplication::AcceptCallExample(bool bPreparation, PlanetKit::EInitialMyVideoState eInitialMyVideoState) {
m_pCall->AcceptCall(bPreparation, PlanetKit::CallStartMessagePtr(nullptr), eInitialMyVideoState);
}
ローカルユーザーに対するメディアステータスリスナーの設定
通話が接続されると、ローカルユーザーに対するメディアステータスのイベントリスナーを設定します。
void YourApplication::SetMyMediaStatusListenerExample() {
PlanetKit::MyMediaStatusPtr pMyMediaStatus = m_pCall->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_pCall->AddMyVideoView(hRenderWnd);
}
ピアのためのビデオビュー追加
AddPeerVideoView()
を呼び出してピアのビデオがレンダリングされるビデオビューを追加します。ビデオのレンダリングは、ピアのビデオ状態によって、開始または中止されます。
void YourApplication::AddPeerVideoViewExample(HWND hRenderWnd) {
// Add window handle. PlanetKit will render peer's video after adding window handle.
m_pCall->AddPeerVideoView(hRenderWnd);
}
通話の切断
通話を切断するには、EndCall()
を呼び出します。
void YourApplication::EndCallExample() {
// Unregister the event listener
this->m_pMyMediaStatus->Unregister();
m_pCall->EndCall();
}