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

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

创建视频通话C++类

VideoCall 类管理与 Agora SDK 的通信。需要创建多个方法和接口。

创建类接口

回到 Unreal 编辑器,再创建一个新的 C++类,命名为 VideoCall.h。然后进入VideoCall.h文件,添加一下接口:

//VideoCall.h
#pragma once
#include "CoreMinimal.h"
#include <functional>
#include <vector>
#include "AgoraRtcEngine.h"
#include "AgoraMediaEngine.h"
class VideoFrameObserver;
class AGORAVIDEOCALL_API VideoCall
{
public:
 VideoCall();
 ~VideoCall();
 FString GetVersion() const;
 void RegisterOnLocalFrameCallback(
 std::function<void(std::uint8_t*, std::uint32_t, std::uint32_t, std::uint32_t)> OnLocalFrameCallback);
 void RegisterOnRemoteFrameCallback(
 std::function<void(std::uint8_t*, std::uint32_t, std::uint32_t, std::uint32_t)> OnRemoteFrameCallback);
 void StartCall(
 const FString& ChannelName,
 const FString& EncryptionKey,
 const FString& EncryptionType);
 void StopCall();
 bool MuteLocalAudio(bool bMuted = true);
 bool IsLocalAudioMuted();
 bool MuteLocalVideo(bool bMuted = true);
 bool IsLocalVideoMuted();
 bool EnableVideo(bool bEnable = true);
private:
 void InitAgora();
private:
 TSharedPtr<agora::rtc::ue4::AgoraRtcEngine> RtcEnginePtr;
 TSharedPtr<agora::media::ue4::AgoraMediaEngine> MediaEnginePtr;
 TUniquePtr<VideoFrameObserver> VideoFrameObserverPtr;
 //callback
 //data, w, h, size
 std::function<void(std::uint8_t*, std::uint32_t, std::uint32_t, std::uint32_t)> OnLocalFrameCallback;
 std::function<void(std::uint8_t*, std::uint32_t, std::uint32_t, std::uint32_t)> OnRemoteFrameCallback;
 bool bLocalAudioMuted = false;
 bool bLocalVideoMuted = false;
};

创建初始化方法

进入 VideoCall.cpp 文件,添加以下代码:

//VideoCall.cpp
#include "AgoraVideoDeviceManager.h"
#include "AgoraAudioDeviceManager.h"
#include "MediaShaders.h"
#include "VideoFrameObserver.h"

用agora::rtc::ue4::AgoraRtcEngine::createAgoraRtcEngine()创建引擎,初始化 RtcEnginePtr 变量。创建一个RtcEngineContext对象,然后在ctx.eventHandler 和ctx.appId中设定 event handler 和 App ID 。初始化引擎,并创建AgoraMediaEngine对象,初始化 MediaEnginePtr。

//VideoCall.cpp
VideoCall::VideoCall()
{
 InitAgora();
}
VideoCall::~VideoCall()
{
 StopCall();
}
void VideoCall::InitAgora()
{
 RtcEnginePtr = TSharedPtr<agora::rtc::ue4::AgoraRtcEngine>(agora::rtc::ue4::AgoraRtcEngine::createAgoraRtcEngine());
 static agora::rtc::RtcEngineContext ctx;
 ctx.appId = "aab8b8f5a8cd4469a63042fcfafe7063";
 ctx.eventHandler = new agora::rtc::IRtcEngineEventHandler();
 int ret = RtcEnginePtr->initialize(ctx);
 if (ret < 0)
 {
 UE_LOG(LogTemp, Warning, TEXT("RtcEngine initialize ret: %d"), ret);
 }
 MediaEnginePtr = TSharedPtr<agora::media::ue4::AgoraMediaEngine>(agora::media::ue4::AgoraMediaEngine::Create(RtcEnginePtr.Get()));
}
FString VideoCall::GetVersion() const
{
 if (!RtcEnginePtr)
 {
 return "";
 }
 int build = 0;
 const char* version = RtcEnginePtr->getVersion(&build);
 return FString(ANSI_TO_TCHAR(version));
}