C++ 在 Unreal 中为游戏增加实时音视频互动的教程详解

2020-05-29 11:02:26于丽

创建回调方法

接下来创建回调方法,返回本地和远端的视频帧

//VideoCall.cpp
void VideoCall::RegisterOnLocalFrameCallback(
 std::function<void(std::uint8_t*, std::uint32_t, std::uint32_t, std::uint32_t)> OnFrameCallback)
{
 OnLocalFrameCallback = std::move(OnFrameCallback);
}
void VideoCall::RegisterOnRemoteFrameCallback(
 std::function<void(std::uint8_t*, std::uint32_t, std::uint32_t, std::uint32_t)> OnFrameCallback)
{
 OnRemoteFrameCallback = std::move(OnFrameCallback);
}

创建呼叫方法

我们需要利用这个方法来实现“加入频道”和“离开频道”。

增加 StartCall

首先创建 VideoFrameObserver 对象,然后根据你的场景来设置以下回调。

OnLocalFrameCallback:用于 SDK 获取本地摄像头采集到的视频帧。 OnRemoteFrameCallback:用于 SDK 获取远端摄像头采集到的视频帧。

在 InitAgora 的 MediaEngine 对象中通过 registerVideoFrameObserver 方法注册 VideoFrameObserver。为了保证 EncryptionType 和 EncryptionKey 不为空,需要先设置 EncryptionMode 和 EncryptionSecret。然后按照你的需要来设置频道参数,并调用 joinChannel。

//VideoCall.cpp
void VideoCall::StartCall(
 const FString& ChannelName,
 const FString& EncryptionKey,
 const FString& EncryptionType)
{
 if (!RtcEnginePtr)
 {
 return;
 }
 if (MediaEnginePtr)
 {
 if (!VideoFrameObserverPtr)
 {
 VideoFrameObserverPtr = MakeUnique<VideoFrameObserver>();
 std::function<void(std::uint8_t*, std::uint32_t, std::uint32_t, std::uint32_t)> OnCaptureVideoFrameCallback
 = [this](std::uint8_t* buffer, std::uint32_t width, std::uint32_t height, std::uint32_t size)
 {
 if (OnLocalFrameCallback)
 {
 OnLocalFrameCallback(buffer, width, height, size);
 }
 else { UE_LOG(LogTemp, Warning, TEXT("VideoCall OnLocalFrameCallback isn't set")); }
 };
 VideoFrameObserverPtr->setOnCaptureVideoFrameCallback(std::move(OnCaptureVideoFrameCallback));
 std::function<void(std::uint8_t*, std::uint32_t, std::uint32_t, std::uint32_t)> OnRenderVideoFrameCallback
 = [this](std::uint8_t* buffer, std::uint32_t width, std::uint32_t height, std::uint32_t size)
 {
 if (OnRemoteFrameCallback)
 {
 OnRemoteFrameCallback(buffer, width, height, size);
 }
 else { UE_LOG(LogTemp, Warning, TEXT("VideoCall OnRemoteFrameCallback isn't set")); }
 };
 VideoFrameObserverPtr->setOnRenderVideoFrameCallback(std::move(OnRenderVideoFrameCallback));
 }
 MediaEnginePtr->registerVideoFrameObserver(VideoFrameObserverPtr.Get());
 }
 int nRet = RtcEnginePtr->enableVideo();
 if (nRet < 0)
 {
 UE_LOG(LogTemp, Warning, TEXT("enableVideo : %d"), nRet)
 }
 if (!EncryptionType.IsEmpty() && !EncryptionKey.IsEmpty())
 {
 if (EncryptionType == "aes-256")
 {
 RtcEnginePtr->setEncryptionMode("aes-256-xts");
 }
 else
 {
 RtcEnginePtr->setEncryptionMode("aes-128-xts");
 }
 nRet = RtcEnginePtr->setEncryptionSecret(TCHAR_TO_ANSI(*EncryptionKey));
 if (nRet < 0)
 {
 UE_LOG(LogTemp, Warning, TEXT("setEncryptionSecret : %d"), nRet)
 }
 }
 nRet = RtcEnginePtr->setChannelProfile(agora::rtc::CHANNEL_PROFILE_COMMUNICATION);
 if (nRet < 0)
 {
 UE_LOG(LogTemp, Warning, TEXT("setChannelProfile : %d"), nRet)
 }
 //"demoChannel1";
 std::uint32_t nUID = 0;
 nRet = RtcEnginePtr->joinChannel(NULL, TCHAR_TO_ANSI(*ChannelName), NULL, nUID);
 if (nRet < 0)
 {
 UE_LOG(LogTemp, Warning, TEXT("joinChannel ret: %d"), nRet);
 }
}