实现音视频互动

  • Windows

更新时间不可用

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

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

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

更多概念详见关键概念。

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

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

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

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

前提条件

在实现功能以前,请按照以下要求准备开发环境:

  • Windows 7 或以上版本的设备。
  • Microsoft Visual Studio 2017 或以上版本。
  • C++ 11 或以上版本。
  • 如果使用 C# 开发,还需要 .NET 桌面开发组件。
  • 可以访问互联网的计算机。如果你的网络环境部署了防火墙,参考应对防火墙限制以正常使用声网服务。
  • 一个有效的声网账号以及声网项目。请参考开通 RTC 服务从声网控制台获得 App ID 和临时 Token。

注意

临时 Token 的有效期是 24 小时。Token 过期会导致加入频道失败。

创建项目 (C++)

以 Windows 11 为例,参考以下操作或官方文档在 Visual Studio 2022 中创建一个项目来实现实时音视频互动功能,如果你已有自己的项目,可跳过这一步骤。

  1. 在 Visual Studio 中,选择文件 > 新建 > 项目 来创建一个新项目。在弹出的窗口中,选择 MFC 应用作为项目模板,点击下一步将项目名称设为 AgoraQuickStart 并设置项目储存位置,然后点击创建。

  2. 在弹出的 MFC 应用程序窗口中,将应用程序类型设为基于对话框,将使用 MFC 设为在共享 DLL 中使用 MFC。进入生成的类,将生成的类设为 Dlg,将基类设为 CDialog,最后点击完成。

集成 SDK (C++)

  1. 从下载获取最新的 Windows SDK,解压并打开。
  2. 打开已下载的 SDK 文件,并将其中的 sdk 文件夹复制到你的项目路径下。保证 sdk 文件夹和你的 sln 文件处于同一目录。

注意

自 4.5.0 起,RTC SDK 和 RTM SDK (2.2.0 及以上版本) 都包含 libaosl.dll 库。如果你通过 CDN 手动集成 RTC SDK 且同时集成了 RTM SDK,为避免冲突,请手动删除版本较低的 libaosl.dll 库。4.6.0 RTC SDK libaosl.dll 库版本为 1.3.0。你可以通过查看 libaosl.dll 文件的属性来得知库的版本信息。

配置项目属性 (C++)

在解决方案资源管理器窗口中,右击项目名称并点击属性进行以下配置:

  1. 进入 C/C++ > 常规 > 附加包含目录菜单,输入 $(SolutionDir)sdk\high_level_api\include。

  2. 进入链接器 > 常规 > 附加库目录菜单,输入 $(SolutionDir)sdk\x86_64。

    信息

    如果你是 x86 的 Windows 操作系统,请输入 $(SolutionDir)sdk\x86。

  3. 进入链接器 > 输入 > 附加依赖项菜单,输入 $(SolutionDir)sdk\x86_64\agora_rtc_sdk.dll.lib。

    信息

    如果你是 x86 的 Windows 操作系统,请输入 $(SolutionDir)sdk\x86\agora_rtc_sdk.dll.lib。

  4. 进入高级菜单,在高级属性中,把将内容复制到 OutDir 和将 C++ 运行时复制到输出目录设为是。

  5. 进入生成事件 > 生成后事件 >命令行 菜单,输入 copy $(SolutionDir)sdk\x86_64\*.dll $(SolutionDir)$(Platform)\$(Configuration)。

  6. 完成上述配置后点击应用。

创建用户界面 (C++)

根据实时音视频互动的场景需要,你需要在你的应用中添加如下 UI:

  • 展示本地视频的视图框
  • 展示远端视频的视图框
  • 输入频道名称的输入框
  • 加入和离开频道按钮

你可以参考下列步骤来创建用户界面。

实现步骤 (C++)

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

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

以下展示实现实时互动基本流程的完整示例代码:

注意

复制完整示例代码到你的项目之后,你需要将代码中的 APP_ID 和 token 替换成你在声网控制台获取的 App ID 和临时 Token。

参考下列步骤来在你的应用中实现实时互动:

初始化引擎 (C++)

在调用其他声网 API 前,你需要调用 createAgoraRtcEngine 创建一个IRtcEngine 对象,然后调用 initialize 并传入 App ID,初始化 IRtcEngine。

注意

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

C++
// 创建 IRtcEngine 对象
m_rtcEngine = createAgoraRtcEngine();

// 创建 IRtcEngine 上下文对象
RtcEngineContext context;

// 输入你的 App ID。你可以在声网控制台获取你的项目的 App ID
context.appId = APP_ID;

// 添加注册回调和事件
context.eventHandler = &m_eventHandler;

// 初始化
int ret = m_rtcEngine->initialize(context);
if (ret == 0) {
    m_initialize = true;
} else {
    m_initialize = false;
}

启用视频模块 (C++)

  1. 调用 enableVideo 方法,启用视频模块。
  2. 调用 setupLocalVideo 初始化本地视图,同时设置本地的视频显示属性。
  3. 调用 startPreview 方法,开启本地视频预览。
C++
// 启用视频模块
m_rtcEngine->enableVideo();
...

// 设置本地视频显示属性
VideoCanvas canvas;
// 设置视频尺寸等比缩放
canvas.renderMode = RENDER_MODE_TYPE::RENDER_MODE_HIDDEN;
// 用户 ID
canvas.uid = 0;
// 视频显示窗口
canvas.view = m_staLocal.GetSafeHwnd();
m_rtcEngine->setupLocalVideo(canvas);
// 开启本地视频预览
m_rtcEngine->startPreview();

加入频道并发布音视频流 (C++)

调用 joinChannel[2/2] 方法、填入你在控制台获取的临时 Token,以及获取 Token 时填入的频道名加入频道,并设置用户角色。

C++
void CAgoraQuickStartDlg::OnBnClickedBtnJoin() {
    CString strChannelName;
    // 获取频道名
    m_edtChannelName.GetWindowText(strChannelName);
    if (strChannelName.IsEmpty()) {
        AfxMessageBox(_T("Fill channel name first"));
        return;
    }

    ChannelMediaOptions option;
    // 设置频道场景为直播场景
    options.channelProfile = CHANNEL_PROFILE_LIVE_BROADCASTING;
    // 设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可
    options.clientRoleType = CLIENT_ROLE_BROADCASTER;
    // 发布麦克风采集的音频流
    options.publishMicrophoneTrack = true;
    // 发布摄像头采集的视频流
    options.publishCameraTrack = true;
    // 自动订阅所有音频流
    options.autoSubscribeAudio = true;
    // 自动订阅所有视频流
    options.autoSubscribeVideo = true;
    // 填入你在控制台获取的临时 Token 加入频道
    m_rtcEngine->joinChannel(token, cs2utf8(strChannelName).c_str(), 0, option);
}

实现常用回调 (C++)

你可以根据需求,在初始化时实现其他功能,如注册用户加入、离开频道等回调。

C++
class CAgoraQuickStartRtcEngineEventHandler : public IRtcEngineEventHandler {
public:
    // 注册 onJoinChannelSuccess 回调
    // 本地用户成功加入频道时,会触发该回调
    virtual void onJoinChannelSuccess(const char* channel, uid_t uid, int elapsed) {
        if (m_hMsgHanlder) {
            ::PostMessage(m_hMsgHanlder, WM_MSGID(EID_JOIN_CHANNEL_SUCCESS), uid, 0);
        }
    }

    // 注册 onUserJoined 回调
    // 远端主播成功加入频道时,会触发该回调
    virtual void onUserJoined(uid_t uid, int elapsed) {
        if (m_hMsgHanlder) {
            ::PostMessage(m_hMsgHanlder, WM_MSGID(EID_USER_JOINED), uid, 0);
        }
    }

    // 注册 onUserOffline 回调
    // 远端主播离开频道或掉线时,会触发该回调
    virtual void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason) {
        if (m_hMsgHanlder) {
            ::PostMessage(m_hMsgHanlder, WM_MSGID(EID_USER_OFFLINE), uid, 0);
        }
    }

private:
    HWND m_hMsgHanlder;
};

设置远端视图 (C++)

当远端用户加入频道时,从远端用户加入频道的回调中获取到的远端用户的 uid,然后调用 setupRemoteVideo 设置并渲染远端视图。

C++
LRESULT CAgoraQuickStartDlg::OnEIDUserJoined(WPARAM wParam, LPARAM lParam) {
    // 远端用户加入回调
    uid_t remoteUid = wParam;
    if (m_remoteRender) {
        return;
    }
    // 设置远端视频显示属性
    VideoCanvas canvas;
    // 设置视频尺寸等比缩放
    canvas.renderMode = RENDER_MODE_TYPE::RENDER_MODE_HIDDEN;
    // 远端用户 ID
    canvas.uid = remoteUid;
    canvas.view = m_staRemote.GetSafeHwnd();
    m_rtcEngine->setupRemoteVideo(canvas);
    m_remoteRender = true;
}

离开频道 (C++)

根据场景需要,如关闭应用或应用切换至后台时,调用 leaveChannel 离开当前频道。

C++
void CAgoraQuickStartDlg::OnBnClickedBtnLeave() {
    // 停止本地视频预览
    m_rtcEngine->stopPreview();
    // 离开频道
    m_rtcEngine->leaveChannel();

    // 清除本地视图
    VideoCanvas canvas;
    canvas.uid = 0;
    m_rtcEngine->setupLocalVideo(canvas);

    m_remoteRender = false;
}

如果你不再需要互动,调用 release 方法释放引擎资源。

注意

  • 调用 release 后,你将无法再使用 SDK 的所有方法和回调。如需再次使用实时音视频互动功能,你必须重新创建一个新的引擎。详见初始化引擎。 该方法为同步调用。需要等待引擎资源释放后才能执行其他操作,因此建议在子线程中调用该方法,避免主线程阻塞。
C++
CDialog::~CDialog() {
    // 在对象被销毁时释放资源
    if(m_rtcEngine){
       m_rtcEngine->release(true);
       m_rtcEngine = NULL;
    }
}

调试应用 (C++)

按照以下步骤来测试你的应用:

  1. 在 Visual Studio 中,选择本地 Windows 调试器开始编译应用。
  2. 在输入框中输入你要加入的频道名,并点击加入按钮加入频道,你将在本地视图中看到自己。
  3. 邀请一位朋友通过另一台设备来使用相同的 App ID、频道名、Token 加入频道。你的朋友加入频道后,你们可以听见、看见对方。

创建项目 (C#)

参考以下操作,在 Visual Studio 中创建一个 Windows 项目:

  1. 在 Visual Studio 上创建一个 Windows Forms 应用项目,详见 Create a Windows Forms app in Visual Studio with C#。
  2. 打开 Configuration Manager 窗口,在 Active solution platform 下拉菜单中选择 New,在弹出的窗口中选择 x64 或 x86 作为目标平台。

集成 SDK (C#)

使用 Visual Studio 中的 NuGet 包管理器,将 SDK 集成到项目中。详见快速入门:在 Visual Studio 中安装和使用包。

信息

你可以在 agora_rtc_sdk 中获取最新发布的 SDK 的版本信息。

创建用户界面 (C#)

为直观地体验视频通话,你需要根据应用场景创建用户界面(UI)。若你的项目中已有用户界面,可略过此步骤。

如果你想实现音视频互动,推荐在 UI 上添加以下控件:

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

参考以下步骤创建 UI。

  1. 创建 Join 和 Leave 按钮

    1. 在你的项目中,打开 Solution Explore 窗口,双击 Form1.cs,打开 Toolbox 窗口,选择 Button 控件,依次添加两个按钮,并将两个按钮拖放至合适位置。
    2. 将鼠标移至其中一个按钮上,点击鼠标右键,选中 Properties,在打开的 Properties 窗口中修改 Text 属性为 Join,修改 Name 属性为 btnJoin。
    3. 重复上一个步骤来修改另一个按钮的属性:修改 Text 为 Leave;修改 Name 为 btnLeave。
  2. 创建本地及远端视图窗口

    1. 打开 Toolbox 窗口,选中 PictureBox 控件,依次为本地视图和远端视图在合适的位置添加控件。
    2. 将鼠标移至本地视图窗口控件上,点击鼠标右键,选中 Properties,在打开的 Properties 窗口中修改 Name 属性为 videoboxLocal;修改 BorderStyle 为 FixedSingle。
    3. 重复上一个步骤修改远端视图窗口控件的属性:修改 Name 为 videoboxRemote;修改 BorderStyle 为 FixedSingle。
  3. 创建频道名输入框

    1. 打开 Toolbox 窗口,选中 TextBox 控件,然后将其拖拽至合适位置。
    2. 将鼠标移至添加好的输入框控件上,点击鼠标右键,选中 Properties ,修改其属性 Name 为 txChannelName。
  4. 保存上述步骤的更改。

  5. 分别双击 Join 和 Leave 按钮,IDE 会自动关联点击事件处理函数。

此时你的 UI 界面如下图所示:

实现步骤 (C#)

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

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

下面列出了一段实现实时互动基本流程的完整代码以供参考。

信息

在 APP_ID 和 Token 字段中传入你在控制台获取到的 App ID 和临时 Token。

导入声网相关的类 (C#)

导入声网 RTC SDK 相关的类。

C#
using Agora.Rtc;

初始化引擎 (C#)

调用 CreateAgoraRtcEngine 方法创建一个 RtcEngine 对象,然后调用 initialize 初始化 RtcEngine。

C#
// 创建引擎
engine_ = RtcEngine.CreateAgoraRtcEngine();

// 配置引擎实例
RtcEngineContext ctx = new RtcEngineContext()
{
    appId = APP_ID,
    areaCode = AREA_CODE.AREA_CODE_GLOB,
    logConfig = { filePath = "rtc.log" }
};

//  初始化引擎
var ret = engine_.Initialize(ctx);
if (ret != 0)
{
    Console.WriteLine("=====>Initialize failed {0}", ret);
    return;
}

启用视频模块 (C#)

  1. 调用 EnableVideo 方法,启用视频模块。
  2. 调用 SetupLocalVideo 初始化本地视图,同时设置本地的视频显示属性。
  3. 调用 StartPreview 方法,开启本地视频预览。
C#
// 启用视频模块
ret = engine_.EnableVideo();
if (ret != 0)
{
    Console.WriteLine("=====>EnableVideo failed {0}", ret);
}

// 设置本地视图
VideoCanvas canvas = new VideoCanvas();
canvas.view = (long)videoboxLocal.Handle;
canvas.renderMode = RENDER_MODE_TYPE.RENDER_MODE_FIT;

ret = engine_.SetupLocalVideo(canvas);
if (ret != 0)
{
    Console.WriteLine("=====>SetupLocalVideo failed {0}", ret);
}

// 开启本地视频预览
ret = engine_.StartPreview(VIDEO_SOURCE_TYPE.VIDEO_SOURCE_CAMERA_PRIMARY);
if (ret != 0)
{
    Console.WriteLine("=====>StartPreview failed {0}", ret);
}

加入频道并发布音视频流 (C#)

调用 JoinChannel[2/2] 加入频道,填入你在控制台获取的临时 Token,以及获取 Token 时填入的频道名加入频道,并设置用户角色。

C#
ChannelMediaOptions options = new ChannelMediaOptions();
// 设置频道场景为直播
options.channelProfile.SetValue(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING);
// 设置用户角色为主播
options.clientRoleType.SetValue(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);

// 发布麦克风采集的音频流
options.publishMicrophoneTrack = true;
// 发布摄像头采集的视频流
options.publishCameraTrack = true;
// 自动订阅所有音频流
options.autoSubscribeAudio = true;
// 自动订阅所有视频流
options.autoSubscribeVideo = true;

var ret = engine_.JoinChannel(APP_TOKEN, txChannelName.Text, 0, options);

设置远端用户视图 (C#)

调用 SetupRemoteVideo 方法初始化远端用户视图,同时设置远端用户的视图在本地显示属性。你可以通过 OnUserJoined 回调获取远端用户的 uid。

C#
private void OnUserJoined(RtcConnection connection, uint remoteUid, int elapsed)
{
    VideoCanvas canvas = new VideoCanvas();
    canvas.view = (long)videoboxRemote.Handle;
    canvas.renderMode = RENDER_MODE_TYPE.RENDER_MODE_FIT;
    canvas.uid = remoteUid
    int ret = engine_.SetupRemoteVideo(canvas);
    Console.WriteLine("----->SetupRemoteVideo, ret={0}", ret);
}

实现常用回调 (C#)

根据使用场景,定义必要的回调。以下示例代码展示如何实现 OnJoinChannelSuccess、 OnUserJoined 和 OnUserOffline 回调。

C#
public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed)
{
    Console.WriteLine("----->OnJoinChannelSuccess channel={0} uid={1}", connection.channelId,connection.localUid);
}
public override void OnUserJoined(RtcConnection connection, uint remoteUid, int elapsed)
{
    Console.WriteLine("----->OnUserJoined uid={0}", remoteUid);
    if (EventOnUserJoined != null)
        EventOnUserJoined.Invoke(connection, remoteUid, elapsed);
}
public override void OnUserOffline(
    RtcConnection connection,
    uint remoteUid,
    USER_OFFLINE_REASON_TYPE reason
)

开始音视频互动 (C#)

在 btnJoin_Click 函数中调用 JoinChannel[2/2] 方法,当用户点击 Join 按钮时开始音视频互动。

C#
private void btnJoin_Click(object sender, EventArgs e)
{
    if (null != engine_)
    {
        ...
        var ret = engine_.JoinChannel(APP_TOKEN, txChannelName.Text, 0, options);
        Console.WriteLine("=====>JoinChannel result {0}", ret);
    }
}

结束音视频互动 (C#)

  1. 在 btnLeave_Click 函数中调用 LeaveChannel 方法,当用户点击 Leave 按钮时结束音视频互动。

    C#
    private void btnLeave_Click(object sender, EventArgs e)
    {
        if (null != engine_)
        {
            var ret = engine_.StopPreview();
            var ret = engine_.LeaveChannel();
            Console.WriteLine("=====>LeaveChannel result {0}", ret);
        }
    }
  2. 调用 Dispose 销毁引擎,并释放声网 SDK 中使用的所有资源。

    C#
    engine_.Dispose()

    警告

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

测试你的项目 (C#)

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

  1. 将你从声网控制台获取的 App ID 和临时 Token 分别填入到 Form1.cs 文件的 APP_ID 和 APP_TOKEN 中。
  2. 在 Visual Studio 中点击 Start 按钮运行你的项目,你将在本地视图中看到自己。
  3. 在输入框中输入你在声网控制台生成临时 Token 时填写的频道名,并点击 Join 按钮加入频道。
  4. 邀请一位朋友通过另一台设备来使用相同的 App ID、频道名、Token 加入频道。你的朋友加入频道后,你们可以听见、看见对方。

后续步骤

  • 在测试或生产环境中,为确保通信安全,声网推荐使用 Token 服务器来生成 Token,详见使用 Token 鉴权。
  • 如果你想要实现极速直播场景,可以在互动直播的基础上,通过修改观众端的延时级别为低延时 (AUDIENCE_LATENCY_LEVEL_LOW_LATENCY)实现。详见实现极速直播。

参考信息

示例项目

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

常见问题

相关文档