1-to-1 audio call
This page provides a code example for making a 1-to-1 audio call.
Prerequisites
Before you begin, you must do the following:
- Initialize PlanetKit.
- Get a proper access token.
- Check the overall API usage flow in 1-to-1 call flow.
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
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.
ICallEvent
is an abstract class that provides an interface to handle events related to call setup. Create a class that extendsICallEvent
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, or when the audio description is updated. Create a class that extendsIMyMediaStatusEvent
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;
...
//
// Also, you should implement other override functions.
//
};
Make an outgoing call (caller side)
To start a new call, call MakeCall()
with an appropriate MakeCallParamPtr
argument.
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) {
// 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 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);
}
}
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:
- All client applications periodically read call notifications from the app server to notify a specific user of a new call.
- 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.
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);
}
}
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 m_pCall
variable is a PlanetKitCall
instance that has been verified by VerifyCall()
.
void YourApplication::AcceptCallExample(bool bPreparation) {
m_pCall->AcceptCall(bPreparation);
}
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_pMyMediaStatusListener);
}
End a call
To end a call, call EndCall()
.
void YourApplication::EndCallExample() {
// Unregister the event listener
this->m_pMyMediaStatus->Unregister();
m_pCall->EndCall();
}