写点什么

基于 Agora SDK 实现 Windows 端的多人视频互动

  • 2020-02-25
  • 本文字数:4271 字

    阅读完需:约 14 分钟

基于 Agora SDK 实现 Windows 端的多人视频互动

本文介绍如何通过 Agora SDK 在 Windows 平台快速实现互动直播。互动直播和实时通话的区别就在于,直播频道的用户有角色之分。你可以将角色设置为主播或者观众,其中主播可以收、发流,观众只能收流。

Demo 体验

Agora 在 GitHub 上提供一个开源的实时音视频通话示例项目 OpenLive-Windows。在实现相关功能前,你可以下载并查看源代码:https://github.com/AgoraIO/Basic-Video-Broadcasting/tree/master/OpenLive-Windows

前提条件

  • Microsoft Visual Studio 2017 或以上版本

  • 支持 Windows 7 或以上版本的 Windows 设备

  • 有效的 Agora 账户(免费注册)

  • 如果你的网络环境部署了防火墙,请根据声网文档中心的「应用企业防火墙限制」打开相关端口。

设置开发环境

本节介绍如何创建项目,并将 Agora SDK 集成至你的项目中。

创建 Windows 项目

参考以下步骤创建一个 Windows 项目。若已有 Windows 项目,直接查看集成 SDK。


  1. 打开 Microsoft Visual Studio 并点击新建项目。

  2. 进入新建项目窗口,选择项目类型为 MFC 应用程序,输入项目名称,选择项目存储路径,并点击确认。

  3. 进入 MFC 应用程序窗口,选择应用程序类型为基于对话框,并点击完成。

  4. 集成 SDK


参考以下步骤将 Agora SDK 集成到你的项目中。

1. 配置项目文件

  • 根据应用场景,从 SDK 下载获取最新 SDK,解压并打开。

  • 打开已下载的 SDK 文件,并将其中的 sdk 文件夹复制到你的项目文件夹下。

2. 配置项目属性

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


  • 进入 C/C++ > 常规 > 附加包含目录菜单,点击编辑,并在弹出窗口中输入 $(SolutionDir)include。

  • 进入链接器 > 常规 > 附加库目录菜单,点击编辑,并在弹出窗口中输入 $(SolutionDir)。

  • 进入链接器 > 输入 > 附加依赖项菜单,点击编辑,并在弹出窗口中输入 agora_rtc_sdk.lib。

实现音视频直播

本节介绍如何实现音视频直播。视频直播的 API 使用时序见下图:



  1. 创建用户界面


为直观地体验音视频通话,需根据应用场景创建用户界面(UI)。若项目中已有用户界面,直接查看初始化 IRtcEngine。


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


  • 主播视频窗口

  • 离开频道按钮

  • 当你使用示例项目中的 UI 设计时,你将会看到如下界面:



  1. 初始化 IRtcEngine


在调用其他 Agora API 前,需要创建并初始化 IRtcEngine 对象。


你需要在该步骤中填入项目的 App ID。请参考如下步骤在控制台创建 Agora 项目并获取 App ID。


  1. 登录控制台,点击左侧导航栏的项目管理图标 。

  2. 点击创建,按照屏幕提示设置项目名,选择一种鉴权机制,然后点击提交。

  3. 在项目管理页面,你可以获取该项目的 App ID。

  4. 调用 createAgoraRtcEngine 和 initialize 方法,传入获取到的 App ID,即可初始化 IRtcEngine。


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


// 创建实例。m_lpRtcEngine = createAgoraRtcEngine();RtcEngineContext ctx;
// 添加注册回调和事件。ctx.eventHandler = &m_engineEventHandler;
// 输入你的 App ID。ctx.appId = "YourAppID";
// 初始化 IRtcEngine。m_lpRtcEngine->initialize(ctx);
// 继承 IRtcEngineEventHandler 类中的回调与事件。class CAGEngineEventHandler : public IRtcEngineEventHandler{public: CAGEngineEventHandler(); ~CAGEngineEventHandler(); void setMainWnd(HWND wnd); HWND GetMsgReceiver() {return m_hMainWnd;};
// 在主播调用 joinChannel 方法后,此回调会报告加入频道的主播信息。 virtual void onJoinChannelSuccess(const char* channel, uid_t uid, int elapsed);
// 在主播调用 leaveChannel 方法后,此回调会报告离开频道的主播信息。 virtual void onLeaveChannel(const RtcStats& stat);

// 在引擎收到第一帧远端视频流并解码成功时,会触发此回调。 virtual void onFirstRemoteVideoDecoded(uid_t uid, int width, int height, int elapsed);

// 在主播调用 leaveChannel 方法后,此回调会报告该主播离开频道及离线原因。 virtual void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason);private: HWND m_hMainWnd;};
复制代码


  1. 设置频道模式


初始化结束后,调用 setChannelProfile 方法,将频道模式设为直播。


一个 IRtcEngine 只能使用一种频道模式。如果想切换为其他模式,需要先调用 release 方法释放当前的 IRtcEngine 实例,然后调用 createAgoraRtcEngine 和 initialize 方法创建一个新实例,再调用 setChannelProfile 设置新的频道模式。


// 设置频道模式为直播。m_lpRtcEngine->setChannelProfile(CHANNEL_PROFILE_LIVE_BROADCASTING);
复制代码


  1. 设置用户角色


直播频道有两种用户角色:主播和观众,其中默认的角色为观众。设置频道模式为直播后,你可以在 App 中参考如下步骤设置用户角色:


  • 让用户选择自己的角色是主播还是观众

  • 调用 setClientRole 方法,然后使用用户选择的角色进行传参

  • 注意,直播频道内的用户,只能看到主播的画面、听到主播的声音。加入频道后,如果你想切换用户角色,也可以调用 setClientRole 方法。


BOOL CAgoraObject::SetClientRole(CLIENT_ROLE_TYPE role, LPCSTR lpPermissionKey){    // 设置用户角色。    int nRet = m_lpAgoraEngine->setClientRole(role);    m_nRoleType = role;    return nRet == 0 ? TRUE : FALSE;}// 创建选择用户角色的对话框。void CEnterChannelDlg::OnCbnSelchangeCmbRole(){    int nSel = m_ctrRole.GetCurSel();    if (nSel == 0)        CAgoraObject::GetAgoraObject()->SetClientRole(CLIENT_ROLE_BROADCASTER);    else        CAgoraObject::GetAgoraObject()->SetClientRole(CLIENT_ROLE_AUDIENCE);}
复制代码


  1. 设置本地视图


如果你想实现一个语音直播,可以直接查看加入频道。


成功初始化 IRtcEngine 对象后,需要在加入频道前设置本地视图,以便主播在直播中看到本地图像。参考以下步骤设置本地视图:


  • 调用 enableVideo 方法启用视频模块。

  • 调用 setupLocalVideo 方法设置本地视图。


// 启用视频模块。m_lpRtcEngine->enableVideo();
// 设置本地视图。VideoCanvas vc;vc.uid = 0;vc.view = hVideoWnd;vc.renderMode = RENDER_MODE_TYPE::RENDER_MODE_HIDDEN;m_lpRtcEngine->setupLocalVideo(vc);
复制代码


  1. 加入频道


完成设置角色和本地视图后(视频直播场景),你就可以调用 joinChannel 方法加入频道。你需要在该方法中传入如下参数:


  • channelName: 传入能标识频道的频道 ID。输入频道 ID 相同的用户会进入同一个频道。

  • token:传入能标识用户角色和权限的 Token。可设为如下一个值:

  • 若项目已启用 App 证书,请使用 Token。

  • NULL

  • 临时 Token。临时 Token 服务有效期为 24 小时。你可以在控制台里生成一个临时 Token,详见获取临时 Token。

  • 在你的服务器端生成的 Token。在安全要求高的场景下,我们推荐你使用此种方式生成的 Token,详见生成 Token。

  • uid: 本地用户的 ID。数据类型为整型,且频道内每个用户的 uid 必须是唯一的。若将 uid 设为 0,则 SDK 会自动分配一个 uid,并在 onJoinChannelSuccess 回调中报告。

  • 更多的参数设置注意事项请在声网文档中心查找并参考 joinChannel 接口中的参数描述。


// 在频道中开启 Web SDK 与 Native SDK 互通。m_lpRtcEngine->enableWebSdkInteroperability(true);

// 加入频道。BOOL CAgoraObject::JoinChannel(LPCTSTR lpChannelName, UINT nUID, LPCSTR lpDynamicKey){ int nRet = 0; LPCSTR lpStreamInfo = "{\"owner\":true,\"width\":640,\"height\":480,\"bitrate\":500}";#ifdef UNICODE CHAR szChannelName[128]; ::WideCharToMultiByte(CP_ACP, 0, lpChannelName, -1, szChannelName, 128, NULL, NULL); nRet = m_lpAgoraEngine->joinChannel(lpDynamicKey, szChannelName, lpStreamInfo, nUID);#else nRet = m_lpAgoraEngine->joinChannel(lpDynamicKey, lpChannelName, lpStreamInfo, nUID);#endif if (nRet == 0) m_strChannelName = lpChannelName; return nRet == 0 ? TRUE : FALSE;}
复制代码


  1. 设置远端视图


视频直播中,不论你是主播还是观众,都应该看到频道中的所有主播。在加入频道后,可通过调用 setupRemoteVideo 方法设置远端主播的视图。


远端主播成功加入频道后,SDK 会触发 onFirstRemoteVideoDecoded 回调,该回调中会包含这个主播的 uid 信息。在该回调中调用 setupRemoteVideo 方法,传入获取到的 uid,设置该主播的视图。


// 在引擎收到第一帧远端视频流并解码成功时,会触发此回调。void CAGEngineEventHandler::onFirstRemoteVideoDecoded(uid_t uid, int width, int height, int elapsed){    LPAGE_FIRST_REMOTE_VIDEO_DECODED lpData = new AGE_FIRST_REMOTE_VIDEO_DECODED;    lpData->uid = uid;    lpData->width = width;    lpData->height = height;    lpData->elapsed = elapsed;    if(m_hMainWnd != NULL)        ::PostMessage(m_hMainWnd, WM_MSGID(EID_FIRST_REMOTE_VIDEO_DECODED), (WPARAM)lpData, 0);}VideoCanvas canvas;canvas.renderMode = RENDER_MODE_FIT;POSITION pos = m_listWndInfo.GetHeadPosition();......AGVIDEO_WNDINFO &agvWndInfo = m_listWndInfo.GetNext(pos);canvas.uid = agvWndInfo.nUID;canvas.view = m_wndVideo[nIndex].GetSafeHwnd();agvWndInfo.nIndex = nIndex;
// 设置远端视图。CAgoraObject::GetEngine()->setupRemoteVideo(canvas);
复制代码


  1. 离开频道


根据场景需要,如结束通话、关闭 App 或 App 切换至后台时,调用 leaveChannel 离开当前通话频道。


BOOL CAgoraObject::LeaveCahnnel(){    m_lpAgoraEngine->stopPreview();
// 离开频道。 int nRet = m_lpAgoraEngine->leaveChannel(); m_nSelfUID = 0; return nRet == 0 ? TRUE : FALSE;}

void CAgoraObject::CloseAgoraObject(){ if(m_lpAgoraEngine != NULL) // 释放 IRtcEngine 对象。 m_lpAgoraEngine->release(); if(m_lpAgoraObject != NULL) delete m_lpAgoraObject; m_lpAgoraEngine = NULL; m_lpAgoraObject = NULL;}
复制代码


示例代码


你可以在 OpenLive-Windows 示例代码中查看完整的源码和代码逻辑。


github:https://github.com/AgoraIO/Basic-Video-Broadcasting/tree/master/OpenLive-Windows


运行项目


在 Windows 设备中运行该项目。当成功开始视频直播时,主播可以看到自己的画面;观众可以看到主播的画面。


本文转载自声网 Agora 公众号。


原文链接:https://mp.weixin.qq.com/s/_FESvpZq7yrYxn3eqz0Beg


2020-02-25 17:45873

评论

发布
暂无评论
发现更多内容

第 14 章 -《Linux 一学就会》- RAID磁盘阵列的原理与搭建

学神来啦

Linux linux运维 linux云计算

教你用Java7的Fork/Join框架开发高并发程序

华为云开发者联盟

Java 算法 线程 高并发 Fork/Join框架

12种 vo2dto 方法,就 BeanUtils.copyProperties 压测最拉胯!【快双11了,别用错喽】

小傅哥

Java 小傅哥 MapStruct vo2dto JMapper

设计电商秒杀系统

木云先森

架构训练营

校友录小程序开发笔记三十二:校友卡模块设计与实现

CC同学

GitHub标星过万!阿里内部流传的JDK源码剖析手册到底有多强?

程序员 jdk 面试 java

低代码BPM平台

低代码小观

低代码 企业 企业管理 BPM 低代码平台

为绿色而生:智慧矿山可视化数治监管

一只数据鲸鱼

数据可视化 智慧矿山 煤矿 矿山

设计模式如何提升 vivo 营销自动化业务扩展性 | 引擎篇01

vivo互联网技术

自动化 后端 设计模式 软件架构设计 java

仅需三天,受人追捧的华为内部Java优化笔记登顶Github热搜!

Java 架构 面试 程序人生 编程语言

SSH是什么?怎么组成?有哪些优势?

行云管家

SSH 服务器 SSH工具 服务器管理协议

浙江金华市正规等保测评机构有几家?在哪里?联系电话是多少?

行云管家

网络安全 等保 等保测评

想提高运维效率,那就把MySQL数据库部署到Kubernetes 集群中

华为云开发者联盟

MySQL 运维 测试 MySQL数据库 Kubernetes 集群

一加9 Pro怎么样?值得入手的全能旗舰

Geek_8a195c

「 活动 」连续 3 天,企业容器应用实战营上海站来啦!

阿里巴巴云原生

阿里云 Kubernetes 容器 云原生 活动

专场预告 | DTCC数据库技术大会云溪数据库专场

浪潮云

云计算

【优化技术专题】「线程间的高性能消息框架」终极关注Disruptor的核心源码和Java8的@Contended伪共享指南

洛神灬殇

Disruptor 异步执行 高性能框架 10月月更

机器翻译是否能替代人工翻译?从前世今生说起

博文视点Broadview

“828页Java面试手册”在我手,何愁offer不到手!

Java 程序员 架构 面试 后端

双减来了!人工智能如何促进教育领域转型?

京东科技开发者

人工智能 大数据 AI 教育行业

2021年9月国产数据库大事记

墨天轮

数据库 华为云 国产数据库 达梦 人大金仓

直播回顾|蒋烁淼:《下一代企业级应用软件论坛》可观测性主题精彩分享

观测云

可观测性

授人以渔,华为“开源雨林”计划致力推动开源生态发展

每一个用到canvas的小伙伴都应该了解的fabric.js

荣顶

JavaScript 大前端 canvas 图形处理 画布

成本直降50% | 阿里云发布云原生网关,开启下一代网关新进程

阿里巴巴中间件

阿里云 微服务 云原生 中间件 网关

DCI架构是如何解决DDD战术建模缺点的?

华为云开发者联盟

领域驱动设计 对象 建模 对象编程 DCI架构

再见收费的Navicat!操作所有数据库靠它就够了!

Java 数据库 架构 开源项目

云计算改变企业的传统思考方式

低代码小观

云计算 创新 企业 企业管理 传统观念

百分点大数据技术团队:低代码平台实践

百分点科技技术团队

梦幻西游H5游戏超详细图文架设教程

echeverra

H5游戏

Vue进阶(幺叁幺):父子组件传值实现数据深拷贝

No Silver Bullet

Vue 深拷贝 10月月更

基于 Agora SDK 实现 Windows 端的多人视频互动_文化 & 方法_声网_InfoQ精选文章