Skip to main content
Version: 5.5

1-to-1 video call

This page provides a code example for making a 1-to-1 audio call.

Prerequisites

Before you begin, you must do the following:

Considerations for implementing a 1-to-1 audio call

To receive call notifications on the callee side, you must implement your own notification system, or implement an application using Universal Windows Platform (UWP) and integrate a push notification system.

You also need to know what information must be delivered to the callee. Refer to Role of the app server, which describes cc_param, the data that must be delivered by your application.

After calling MakeCall() or VerifyCall(), you must check the bSuccess field of the returned SStartResult first and then reason field if the call failed.

  • If bSuccess is true, 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.

  • ICallEvent is an abstract class that provides an interface to handle events related to call setup. Create a class that extends ICallEvent 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 extends IMyMediaStatusEvent and override the functions.
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.
//
};

Preview the local user's video

The preview feature allows the local user to preview their own video regardless of the 1-to-1 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);

Make an outgoing call (caller side)

To start a new call, call MakeCall() with an appropriate MakeCallParamPtr argument.

  • To make a video call, call MakeCallParam::SetIsVideoCall() with true.
  • The caller's initial video state can be set with MakeCallParam::SetInitialMyVideoState().
    • The default value of the initial video state is PLNK_INITIAL_MY_VIDEO_STATE_RESUME.
    • If the caller's initial video state is set to paused by calling SetInitialMyVideoState() with PLNK_INITIAL_MY_VIDEO_STATE_PAUSE, the caller's video is not transmitted. The caller's video can be transmitted by calling ResumeMyVideo() after the call is connected.
class YourApplication {
private :
// Prepare PlanetKitCall instance.
PlanetKit::PlanetKitCallPtr m_pCall;

// Prepare call event listener instance.
CallEventListener m_cCallEventListener;

// Prepare member variables to manage MyMediaStatusPtr and MyMediaStatusListener instances
PlanetKit::MyMediaStatusPtr m_pMyMediaStatus;
MyMediaStatusListener m_cMyMediaStatusListener;
};

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_cCallEventListener);

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

PlanetKit::SStartResult sStartResult = pPlanetKitManager->MakeCall(pMakeCallParam, &m_pCall);
if (sStartResult.bSuccess == false) {
LOG_ERROR("MakeCall() failed. Reason: " << sStartResult.reason);
}
}

Receive a call notification (callee side)

When you use PlanetKit for Windows, you must prepare a system to deliver cc_param to a designated callee.

The following example assumes that:

  1. All client applications periodically read call notifications from the app server to notify a specific user of a new call.
  2. The notification data is delivered in JSON string format.
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;
}

Respond to an incoming call (callee side)

Create VerifyCallParam and call VerifyCall() to continue to receive the new call.

class YourApplication {
private :
// Prepare PlanetKitCall instance.
PlanetKit::PlanetKitCallPtr m_pCall;

// Prepare callback event listener instance.
CallEventListener m_cCallEventListener;

// Prepare member variables to manage MyMediaStatusPtr and MyMediaStatusListener instances
PlanetKit::MyMediaStatusPtr m_pMyMediaStatus;
MyMediaStatusListener m_cMyMediaStatusListener;
};

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_cCallEventListener);

// 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;
PlanetKit::SStartResult sStartResult = pPlanetKitManager->VerifyCall(pVerifyCallParam, &m_pCall);
if (sStartResult.bSuccess == false) {
LOG_ERROR("VerifyCall() failed. Reason: " << sStartResult.reason);
}
}

Accept an incoming call (callee side)

In general, the callee needs time to decide whether to accept a new call after responding to the call. To accept a call, call AcceptCall().

  • The callee's initial video state can be set with the eInitialMyVideoState parameter of AcceptCall().
    • The default value of the eInitialMyVideoState parameter is PLNK_INITIAL_MY_VIDEO_STATE_RESUME.
    • If the callee's initial video state is set to paused by passing PLNK_INITIAL_MY_VIDEO_STATE_PAUSE, the callee's video is not transmitted. The callee's video can be transmitted by calling ResumeMyVideo() after the call is connected.
Tip

The m_pCall variable is a PlanetKitCall instance that has been verified by VerifyCall().

void YourApplication::AcceptCallExample(bool bPreparation, PlanetKit::EInitialMyVideoState eInitialMyVideoState) {
m_pCall->AcceptCall(bPreparation, PlanetKit::CallStartMessagePtr(nullptr), eInitialMyVideoState);
}

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_pCall->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() {
// Prepare your window handle (HWND) where you want to render local user's video.
HWND hWnd;

// Add window handle. PlanetKit will render local user's video after adding window handle.
m_pCall->AddMyVideoView(hWnd);
}

Add a video view for the peer

Call AddPeerVideoView() to add a video view where the peer's video will be rendered. The rendering of the video starts or stops according to the peer's video status.

void YourApplication::AddPeerVideoViewExample() {
// Prepare your window handle (HWND) where you want to render peer's video.
HWND hWnd;

// Add window handle. PlanetKit will render peer's video after adding window handle.
m_pCall->AddPeerVideoView(hWnd);
}

End a call

To end a call, call EndCall().

void YourApplication::EndCallExample() {
// Unregister the event listener
this->m_pMyMediaStatus->Unregister();

m_pCall->EndCall();
}