实现音视频互动

  • Unreal C++

更新时间不可用

了解如何快速接入实时互动 RTC,完成环境准备、参数配置、示例运行和核心流程验证。

本文介绍如何集成声网实时互动 SDK,通过少量代码从 0 开始实现一个简单的实时互动 App,适用于互动直播和视频通话场景。 首先,你需要了解以下有关音视频实时互动的基础概念:

  • 声网实时互动 SDK:由声网开发的、帮助开发者在 App 中实现实时音视频互动的 SDK。
  • 频道:用于传输数据的通道,在同一个频道内的用户可以进行实时互动。
  • 主播:可以在频道内发布音视频,同时也可以订阅其他主播发布的音视频。
  • 观众:可以在频道内订阅音视频,不具备发布音视频权限。

更多概念详见关键概念。

下图展示在 App 中实现音视频互动的基本工作流程:

  1. 所有用户调用 joinChannel 方法加入频道,并根据需要设置用户角色:

    • 互动直播:如果用户需要在频道中发流,则设为主播;如果用户只需要收流,则设为观众。
    • 视频通话:将所有用户的角色都设为主播。
  2. 加入频道后,不同角色的用户具备不同的行为:

    • 所有用户默认都可以接收频道中的音视频流。
    • 主播可以在频道内发布音视频流。
    • 观众如果需要发流,可在频道内调用 setClientRole 方法修改用户角色,使其具备发流权限。

前提条件

  • Unreal Engine 4.27 及以上版本
  • 两台设备,不可使用虚拟机。参考下方列出的 Unreal Engine 官方文档,根据你的目标平台和引擎版本准备开发环境:
    开发平台参考文档备注
    AndroidAndroid 开发环境要求无
    iOSiOS 开发环境要求有效的 Apple 开发者签名。
    macOSmacOS 开发环境要求有效的 Apple 开发者签名。
    WindowsWindows 开发环境要求32 位 Windows 仅支持 Unreal Engine 4 及以下版本,你需要在 AgoraPluginLibrary.Build.cs 文件中将 Windows 32 相关的代码取消注释。
    表格内容超出当前宽度,可横向滚动查看更多列。
  • 可以访问互联网的计算机。如果你的网络环境部署了防火墙,参考应对防火墙限制以正常使用声网服务。
  • 一个有效的声网账号以及声网项目。请参考开通 RTC 服务从声网控制台获得以下信息:
    • App ID:声网随机生成的字符串,用于识别你的项目。
    • 临时 Token:Token 也称为动态密钥,在客户端加入频道时对用户鉴权。临时 Token 的有效期为 24 小时。
    • 频道名:用于标识频道的字符串。

创建项目

参考以下步骤或 Unreal 官方操作指南创建一个 Unreal 项目。若已有 Unreal 项目,可以直接查看集成 SDK。

  1. 打开 Unreal Engine,点击 Games。
  2. 依次填入以下内容后,点击 Create。
    • Template:项目类型。选择 Blank。
    • Project Defaults:项目默认设置。
      • Language:开发语言。选择 C++。
      • Target Platform:目标平台。选择 Desktop。
    • Project Location:项目存储路径。
    • Project Name:项目名称。

集成 SDK

  1. 前往下载页面,在视频 SDK 中下载最新版本的 Unreal SDK,并解压缩。
  2. 在你的项目根目录文件夹下,创建名为 Plugins 的文件夹。
  3. 将 Unreal SDK 文件夹中的 AgoraPlugin 拷贝到 Plugins 中。

创建用户界面

为直观地体验视频直播,需根据应用场景创建用户界面(UI)。

如果你想实现一个视频直播,推荐在 UI 上添加以下控件:

  • 本地主播视频窗口
  • 远端主播视频窗口
  • 加入/离开频道按钮

参考以下步骤创建 UI。若你的项目中已有用户界面可略过此步骤。

  1. 创建 Widget Blueprint

    在 Unreal Editor 中,点击 Content Drawer > Content,右击选择 User Interface > Widget Blueprint。将创建的 Widget Blueprint 命名为 AgoraWidget,双击 AgoraWidget 进入蓝图。

  1. 在 Widget Blueprint 中创建本地及远端主播视图窗口

    1. 创建视图画布。选择 Palette > PANEL > Canvas Panel,将其拖至 AgoraWidget 中。

  1. 创建本地视图窗口。选择 COMMON > Image,将其拖至 Canvas Panel 中,重命名为 LocalVideo,并调整在画布中的位置。设置示例如下:

    • Position X:350
    • Position Y:150
    • size X:450
    • Size Y:450
  2. 重复上述步骤创建远端视图窗口,将其命名为 RemoteVideo,并调整在画布中的位置。设置示例如下:

    • Position X:1200
    • Position Y:150
    • size X:450
    • Size Y:450
  3. 在 Widget Blueprint 中创建加入和离开频道按钮

    1. 在 AgoraWidget 中,选择 COMMON > Button,将其拖至 Canvas Panel 中,重命名为 JoinBtn,并调整按钮在画布中的位置。设置示例如下:

      • Position X:300
      • Position Y:700
      • size X:240
      • Size Y:120
    2. 选择 COMMON > Text,将其拖至 JoinBtn 中。选中 JoinBtn 的 Text 控件,在 Details 面板中将 Text 的文本内容修改为 Join。

    3. 重复上述步骤来创建一个 LeaveBtn。你可以根据自己的需求调整按钮位置。

  4. 保存上述步骤的更改。此时 Widget Blueprint 中的 UI 界面如下图所示:

  1. 创建 Level Blueprint,并关联已创建的 Widget Blueprint

    1. 在 Unreal Editor 中,点击 Content Drawer,右击选择 Level 并命名为 agoraLevel。

    2. 双击打开 agoraLevel,点击 Open Level Blueprint。

  1. 右击在搜索框中输入 Create Widget,选择已创建的 AgoraWidget 按照同样的方式依次创建 Event BeginPlay 和 Add to Viewport,并按照下图进行连接:

  1. 保存上述步骤的更改,并运行项目,此时你创建的 UI 界面如下图所示:

实现步骤

本小节介绍如何实现一个实时音视频互动 App。你可以先复制完整的示例代码到你的项目中,快速体验实时音视频互动的基础功能,再按照实现步骤了解核心 API 调用。

下图展示了使用声网 RTC SDK 实现音视频互动的基本流程:

下面列出了实现实时互动基本流程的完整代码以供参考。复制以下代码即可快速体验实时互动基础功能。

信息

在 _appID、_token 和 _channelName 字段中传入你在控制台获取到的 App ID、临时 Token,以及生成临时 Token 时填入的频道名。

处理系统逻辑

本步骤介绍如何导入实现视频直播所需的 C++ 库,并获取摄像头及麦克风设备权限。

  1. 新建 C++ 类,生成头文件和库文件

    在 Unreal Editor 中,选择 Tools > New C++ Class,然后选择 All Classes,找到 UserWidget 并命名为 AgoraWidget,点击 Create Class 创建类。 此时一个新的 C++ 类将添加到你的项目中,你可以看到一个 AgoraWidget.h 文件和一个 AgoraWidget.cpp 文件。

  2. 添加声网依赖库

    在 Project/Source/Project/Project.Build.cs 文件中,向 PublicDependencyModuleNames.AddRange() 添加声网依赖库。

    C++
    // 添加 AgoraPlugin 依赖库
    PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore","AgoraPlugin" });
  3. 初始化自定义的 Widget

    在 Project/Source/AgoraWidget.h 文件中添加以下代码:

    C++
    protected:
        // 初始化自定义的 Widget
        void NativeConstruct() override;
  4. 添加系统所需权限

  1. 关联 C++ 类和 Widget

    在 Unreal Editor 中,点击 Content Drawer,选择 Class Settings > Graph,将 Class Options 下的 Parent Class 设置为 AgoraWidget。

导入声网库

在 AgoraWidget.h 中添加如下 include 代码:

C++
#include "AgoraPluginInterface.h"

定义 App ID 和 Token

  1. 导入变量相关库

    在 AgoraWidget.h 中添加如下 include 代码:

    C++
    #include "Components/Image.h"
    #include "Components/Button.h"
  2. 创建变量,用于创建和加入频道

    在 GENERATED_BODY() 后添加如下代码,变量名称必须与创建 UI 的控件名称一致:

    C++
    // 填入你的 App ID
    FString _appID = "";
    // 填入你的频道名
    FString _channelName = "";
    // 填入 Token
    FString _token = "";
    
    // 定义变量属性
    UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
    UImage* RemoteVideo = nullptr;
    
    UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
    UImage* LocalVideo = nullptr;
    
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (BindWidget))
    UButton* JoinBtn = nullptr;
    
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (BindWidget))
    UButton* LeaveBtn = nullptr;
    
    // 定义 IRtcEngine 全局变量
    agora::rtc::IRtcEngine* RtcEngineProxy;

初始化引擎

在调用其他声网 API 前,需要创建并初始化 IRtcEngine 实例。在 AgoraWidget.h 和 AgoraWidget.cpp 文件中添加 SetupVideoSDKEngine 的方法和实现。示例代码如下:

注意

在初始化 SDK 前,需确保终端用户已经充分了解并同意相关的隐私政策。

C++
private:
    // 获取安卓权限
    void CheckAndroidPermission();
    // 创建并初始化 IRtcEngine
    void SetupVideoSDKEngine();

引用 UI 元素

在 AgoraWidget.h 和 AgoraWidget.cpp 文件中的 SetupVideoSDKEngine() 后添加设置 UI 元素的方法和实现。示例代码如下:

C++
private:
    // 获取安卓权限
    void CheckAndroidPermission();
    // 创建并初始化 IRtcEngine
    void SetupVideoSDKEngine();
    // 设置 UI 元素
    void SetupUI();

加入和离开频道

在 AgoraWidget.h 和 AgoraWidget.cpp 文件中添加本地用户加入和离开频道的方法和实现。示例代码如下:

C++
// 在 UPROPERTY 后添加如下代码:
UFUNCTION(BlueprintCallable)
void Join();
UFUNCTION(BlueprintCallable)
void Leave();

实现回调

设置本地用户和远端主播加入和离开频道后的视频显示。在 AgoraWidget.h 和 AgoraWidget.cpp 文件中添加回调的方法和实现。示例代码如下:

C++
// 在 agora::rtc::IRtcEngine* RtcEngineProxy; 后添加如下代码:
// 本地用户离开频道时,会触发该回调
void onLeaveChannel(const agora::rtc::RtcStats& stats) override;

// 远端主播加入频道时,会触发该回调
void onUserJoined(agora::rtc::uid_t uid, int elapsed) override;

// 远端主播离开频道时,会触发该回调
void onUserOffline(agora::rtc::uid_t uid, agora::rtc::USER_OFFLINE_REASON_TYPE reason) override;

// 本地用户加入频道时,会触发该回调
void onJoinChannelSuccess(const char* channel, agora::rtc::uid_t uid, int elapsed) override;

清理所有会话相关的资源

离开频道后,如果你想退出应用或者释放 IRtcEngine 内存,需调用 release 方法销毁 IRtcEngine。在 AgoraWidget.h 和 AgoraWidget.cpp 文件中的 NativeConstruct() 后添加 NativeDestruct() 的方法和实现。

注意

  • 该方法为同步调用。需要等待引擎资源释放后才能执行其他操作,因此建议在子线程中调用该方法,避免主线程阻塞。
  • 调用 release 后,你将无法再使用 SDK 的所有方法和回调。如需再次使用实时音视频互动功能,你必须重新创建一个新的引擎。详见初始化引擎。
C++
void NativeDestruct() override;

测试你的项目

按照以下步骤来测试你的视频直播项目:

  1. 在 AgoraWidget.h 中,将你的项目的 App ID、频道名以及临时 Token 分别填入到 _appID、_channelName、_token 之后。
  2. 在 Unreal Editor 中,点击播放按钮来运行你的项目,然后点击 Join 来加入直播。
  3. 邀请一位朋友通过另一台设备来使用相同的 App ID、频道名、Token 加入频道。如果你的朋友以主播身份加入,你们可以听见、看见对方;如果作为观众加入,你只能看到自己,你的朋友可以看到你并听到你的声音。

后续步骤

  • 如果你的目标平台是 macOS 或 iOS,则需要在打包时添加实时互动所需的摄像头和麦克风等权限,详见如何为 Unreal Engine 项目添加实时互动所需的权限?
  • 在本文示例中,使用了临时 Token 加入频道。在测试或生产环境中,为确保通信安全,声网推荐使用 Token 服务器来生成 Token,详见使用 Token 鉴权。
  • 如果你想要实现极速直播场景,可以在互动直播的基础上,通过修改观众端的延时级别为低延时 (AUDIENCE_LATENCY_LEVEL_LOW_LATENCY)实现。详见实现极速直播。

参考信息

示例项目

声网提供了开源的示例项目供你参考,你可以前往下载或查看其中的源代码。

常见问题

相关文档