本文にスキップする
Version: 6.0

1対1ビデオ通話

1対1ビデオ通話を実装するサンプルコードです。

前提条件

開始する前に、次の作業が必要です。

1対1ビデオ通話実装時の考慮事項

受信者側で通話の通知を受けるには、通知用のシステムを実装するか、UWP(Universal Windows Platform)を利用してアプリケーションを実装後にプッシュ通知システムを連携する必要があります。

また、受信者にどのような情報を渡すべきかを知っておく必要があります。アプリサーバーの役割にて、アプリケーションが渡すべきデータであるcc_paramについて確認できます。

MakeCall()VerifyCall()を呼び出した後は、返されたSStartResultbSuccessフィールドで成否を確認し、失敗した場合は、reasonフィールドも確認する必要があります。

  • bSuccesstrueの場合、成功を意味します。
  • それ以外は失敗を意味し、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を引き渡すシステムを備える必要があります。

以下のコードは、次のような前提で作成しました。

  1. すべてのクライアントのアプリケーションは、特定のユーザーに新しい電話がかかってきたかどうかを知らせるために、定期的にアプリサーバーでの通話通知を確認します。
  2. 通知データは、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()を呼び出して送信できます。
Tip

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();
}

関連サンプルコード

関連ドキュメント