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;
...
//
// Also, you should implement other override functions.
//
};
통화 생성(발신 측)
새 통화를 시작하려면 적절한 MakeCallParamPtr 인자와 함께 MakeCall()을 호출하세요.
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);
}
}
통화 알림 수신(착신 측)
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()을 호출하세요.
m_pCall 변수는 VerifyCall()에서 검증을 마친 PlanetKitCall 인스턴스입니다.
void YourApplication::AcceptCallExample(bool bPreparation) {
m_pCall->AcceptCall(bPreparation);
}
로컬 사용자에 대한 미디어 상태 리스너 설정
통화가 연결되면 로컬 사용자에 대한 미디어 상태 리스너를 설정하세요.
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);
}
통화 종료
통화를 종료하려면 EndCall()을 호출하세요.
void YourApplication::EndCallExample() {
// Unregister the event listener
this->m_pMyMediaStatus->Unregister();
m_pCall->EndCall();
}