基于 Agora SDK 实现 Windows 端的一对一视频通话(基于3.6.2版本)
前提条件
Microsoft Visual Studio 2019 或以上版本
支持 Windows 7 或以上版本的 Windows 设备
有效的 Agora 账户(免费注册)
注:如果你的网络环境部署了防火墙,请根据声网文档中心的「应用企业防火墙限制」打开相关端口。
设置开发环境
本节介绍如何创建项目,并将 Agora SDK 集成至你的项目中。
创建 Windows 项目
参考以下步骤创建一个 Windows 项目。若已有 Windows 项目,直接查看集成 SDK。
创建 新的MFC项目
1.打开 Microsoft Visual Studio 并点击新建项目。
2.进入新建项目窗口,选择项目类型为 MFC 应用程序,输入项目名称,选择项目存储路径,并点击确认。
3.进入MFC 应用程序窗口,选择应用程序类型为基于对话框,并点击完成。
初学者直接下载文中后面的github地址项目
集成 SDK
参考以下步骤将 Agora SDK 集成到你的项目中。
1.配置项目文件
根据应用场景,从 官网获取最新 SDK,解压并打开。
将下载包中的 sdk 文件夹复制到你的项目文件夹下。
目前3.6.2版本,目录结构为libs/include,libs/x86,libs/x86_64
2.配置项目属性
在解决方案资源管理器窗口中,右击项目名称并点击属性进行以下配置,配置完成后点击确定。
进入 C/C++ > 常规 > 附加包含目录菜单,点击编辑,并在弹出窗口选择解压的libs/include。
进入链接器 > 常规 > 附加库目录菜单,点击编辑,并在弹出窗口中解压的libs/x86或libs/x86_64。
进入链接器 > 输入 > 附加依赖项菜单,点击编辑,并在弹出窗口中解压的 agora_rtc_sdk.lib。
实现音视频通话
本节介绍如何实现音视频通话。视频通话的 API 调用时序见下图:
1. 创建用户界面
根据场景需要,为你的项目创建音视频通话的用户界面。若已有用户界面,可以直接初始化 IRtcEngine。
如果你想实现一个视频通话,我们推荐你添加如下 UI 元素:
本地视频窗口
远端视频窗口
结束通话按钮
当你使用本文链接中,GitHub项目中的界面时,你将会看到如下界面:
2. 初始化 IRtcEngine
在调用其他 Agora API 前,需要创建并初始化 IRtcEngine 对象。
你需要在该步骤中填入项目的 App ID。请参考如下步骤在控制台(console.agora.io)创建 Agora 项目并获取 App ID:
1.登录控制台,点击左侧导航栏的项目管理图标 。
2.点击创建,按照屏幕提示设置项目名,选择一种鉴权机制,然后点击提交。
3.在项目管理页面,你可以获取该项目的 App ID。
调用 createAgoraRtcEngine
和 initialize
方法,传入获取到的 App ID,即可初始化 IRtcEngine
。
你还可以根据场景需要,在初始化时注册想要监听的回调事件,如本地用户加入频道,及解码远端用户视频首帧等。
/**
create or return existing AgoraObject
*/
CAgoraObject *CAgoraObject::GetAgoraObject(LPCTSTR lpAppId)
{
if (m_lpAgoraObject == NULL)
m_lpAgoraObject = new CAgoraObject();
if (m_lpAgoraEngine == NULL)
m_lpAgoraEngine = (IRtcEngine *)createAgoraRtcEngine();
if (lpAppId == NULL)
return m_lpAgoraObject;
RtcEngineContext ctx;
ctx.eventHandler = &m_EngineEventHandler;
#ifdef UNICODE
char szAppId[128];
::WideCharToMultiByte(CP_ACP, 0, lpAppId, -1, szAppId, 128, NULL, NULL);
ctx.appId = szAppId;
#else
ctx.appId = lpAppId;
#endif
m_lpAgoraEngine->initialize(ctx);
return m_lpAgoraObject;
}
// 继承 IRtcEngineEventHandler 类中的回调与事件。
class CAGEngineEventHandler :
public IRtcEngineEventHandler
{
public:
CAGEngineEventHandler(void);
~CAGEngineEventHandler(void);
void SetMsgReceiver(HWND hWnd = NULL);
HWND GetMsgReceiver() {return m_hMainWnd;};
// 本地用户成功加入频道时,会触发该回调。
virtual void onJoinChannelSuccess(const char* channel, uid_t uid, int elapsed);
// 本地重新加入频道时,会触发该回调。
virtual void onRejoinChannelSuccess(const char* channel, uid_t uid, int elapsed);
virtual void onWarning(int warn, const char* msg);
virtual void onError(int err, const char* msg);
virtual void onAudioQuality(uid_t uid, int quality, unsigned short delay, unsigned short lost);
virtual void onAudioVolumeIndication(const AudioVolumeInfo* speakers, unsigned int speakerNumber, int totalVolume);
// 本地用户成功离开频道时,会触发该回调。
virtual void onLeaveChannel(const RtcStats& stat);
//以下还有多个扩展方法
/*
....
/*
private:
HWND m_hMainWnd;
};
3. 设置本地视图
如果你想实现一个语音通话,可以直接跳过这一步,查看下一步「加入频道」。
成功初始化 IRtcEngine 对象后,需要在加入频道前设置本地视图,以便在通话中看到本地图像。默认打开本地摄像头,参考以下步骤设置本地视图:
调用
enableVideo
方法启用视频模块。调用
setupLocalVideo
方法设置本地视图。
// 启用视频模块。m_lpAgoraObject->GetEngine()->enableVideo();// 设置本地视图。
//在文件AgoraTutorialDlg.cpp中
BOOL CAgoraTutorialDlg::OnInitDialog(){
VideoCanvas vc;
vc.uid = 0;
vc.view = m_wndLocal.GetSafeHwnd();
vc.renderMode = RENDER_MODE_FIT;
m_lpAgoraObject->GetEngine()->setupLocalVideo(vc);
//...
}
4. 加入频道
完成初始化和设置本地视图后(视频通话场景),你就可以调用 joinChannel
方法加入频道。你需要在该方法中传入如下参数:
channelName
: 传入能标识频道的频道 ID。输入频道 ID 相同的用户会进入同一个频道。token:传入能标识用户角色和权限的 Token。可设为如下一个值:
注:若项目已启用 App 证书,请使用 Token。
NULL
临时 Token。临时 Token 服务有效期为 24 小时。你可以在控制台里生成一个临时 Token,详情请在文档中心搜索「获取临时 Token」。
在你的服务器端生成的 Token。在安全要求高的场景下,我们推荐你使用此种方式生成的 Token。
uid
: 本地用户的 ID。数据类型为整型,且频道内每个用户的uid
必须是唯一的。若将uid
设为 0,则 SDK 会自动分配一个uid
,并在onJoinChannelSuccess
回调中报告。
更多的参数设置注意事项请参考声网文档中心 joinChannel
接口中的参数描述。
// 加入频道。在文件"AgoraObject.cpp"中
BOOL CAgoraObject::JoinChannel(LPCTSTR lpChannelName, UINT nUID,LPCTSTR lpToken)
{
int nRet = 0;
#ifdef UNICODE
CHAR szChannelName[128];
::WideCharToMultiByte(CP_UTF8, 0, lpChannelName, -1, szChannelName, 128, NULL, NULL);
char szToken[128];
::WideCharToMultiByte(CP_UTF8, 0, lpToken, -1, szToken, 128, NULL, NULL);
if(0 == _tcslen(lpToken))
nRet = m_lpAgoraEngine->joinChannel(NULL, szChannelName, NULL, nUID);
else
nRet = m_lpAgoraEngine->joinChannel(szToken, szChannelName, NULL, nUID);
#else
if(0 == _tcslen(lpToken))
nRet = m_lpAgoraEngine->joinChannel(NULL, lpChannelName, NULL, nUID);
else
nRet = m_lpAgoraEngine->joinChannel(lpToken, lpChannelName, NULL, nUID);
#endif
if (nRet == 0)
m_strChannelName = lpChannelName;
return nRet == 0 ? TRUE : FALSE;
}
5. 设置远端视图
视频通话中,通常你也需要看到其他用户。在加入频道后,可通过调用 setupRemoteVideo
方法设置远端用户的视图。
远端用户成功加入频道后,SDK 会触发 onFirstRemoteVideoDecoded
回调,该回调中会包含这个远端用户的 uid
信息。在该回调中调用 setupRemoteVideo
方法,传入获取到的 uid
,设置远端用户的视图。
// SDK 接收到第一帧远端视频并成功解码时,会触发该回调。// 在该回调中调用 setupRemoteVideo 方法设置远端视图。存在于文件“AgoraTutorialDlg.cpp”中
LRESULT CAgoraTutorialDlg::OnFirstRemoteVideoDecoded(WPARAM wParam, LPARAM lParam)
{
LPAGE_FIRST_REMOTE_VIDEO_DECODED lpData = (LPAGE_FIRST_REMOTE_VIDEO_DECODED)wParam;
VideoCanvas vc;
vc.renderMode = RENDER_MODE_FIT;
vc.uid = lpData->uid;
vc.view = m_wndRemote.GetSafeHwnd();
m_lpAgoraObject->GetEngine()->setupRemoteVideo(vc);//设置远端视图
delete lpData;
return 0;
}
6. 离开频道
根据场景需要,如结束通话、关闭 App 或 App 切换至后台时,调用 leaveChannel
离开当前通话频道。
/**
Leave the channel
*/
BOOL CAgoraObject::LeaveChannel()
{
m_lpAgoraEngine->stopPreview();
int nRet = m_lpAgoraEngine->leaveChannel();
return nRet == 0 ? TRUE : FALSE;
}
示例代码
你可以在 Agora-Windows-Tutorial-1to1 示例项目的 AgoraTutorialDlg.cpp 文件中查看完整的源码和代码逻辑。
基于 Agora SDK 实现 Windows 端的一对一视频通话(基于3.6.2版本)的更多相关文章
- 如何基于 ZEGO SDK 实现 Windows 一对一音视频聊天应用
互联网发展至今,实时视频和语音通话越来越被大众所依赖. 今天,我们将会继续介绍如何基于ZEGO SDK实现音视频通话功能,前两篇文章分别介绍了Android,Flutter平台的实现方式,感兴趣的小伙 ...
- 如何基于 ZEGO SDK 实现 Android 一对一音视频聊天应用
疫情期间,很多线下活动转为线上举行,实时音视频的需求剧增,在视频会议,在线教育,电商购物等众多场景成了"生活新常态". 本文将教你如何通过即构ZEGO sdk在Android端搭建 ...
- 如何基于 ZEGO SDK 实现 Flutter 一对一音视频聊天应用?
之前的文章发布了ZEGO SDK实现Android端音视频通话应用的开发教程,不少开发者反馈很实用,能不能也出一版Flutter的教程. 有求必应,这不小编来了- 我们封装了ZEGO Flutter ...
- 用C/C++开发基于VLC SDK的视频播放器
在windows系统如果开发万能播放器,一般都是基本DirectShow来开发,开发也很简单,但缺点也很多,一个文件格式是否能够播放完全取决于你 是否安装了正确的解析器和解码器,即使现在有了万能解器安 ...
- Redis的Windows端开发连接Linux端以及相应的代码实现
在Windows端开发连接需要进行配置文件的配置: 在redis.conf配置文件中 将protected-mode yes,修改为protected-mode no:不保护redis # By de ...
- 基于Tcp穿越的Windows远程桌面(远程桌面管理工具)
基于Tcp穿越的Windows远程桌面(远程桌面管理工具) 1.<C# WinForm 跨线程访问控件(实用简洁写法)> 2.<基于.NET环境,C#语言 实现 ...
- 如何基于ZEGO SDK 实现通话质量监测
如何基于ZEGO SDK 实现通话质量监测 1 功能简介 在进行视频通话过程中,用户有时候会出现网络不好的情况,比如在进行多人视频通话或者多人唱歌时,我们需要实时显示用户的网络质量. 示例源码 请参考 ...
- [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装
[原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...
- 使用Squirrel创建基于Electron开发的Windows 应用安装包
我们把自己开发的Electron应用发布之前,需要把app打包成简单的安装包,这样app更容易被获取,以此来发布我们的应用.我们可以参考Wix或其他的安装程序,但是对于Electron应用更好的打包程 ...
- Platform SDK、Windows SDK简介
Platform SDK及Windows SDK是由微软公司出品的一个软件开发包,向在微软的Windows操作系统和.NET框架上开发软件和网站的程序员提供头文件.库文件.示例代码.开发文档和开发工具 ...
随机推荐
- spider_爬取内涵吧的段子(二级深度爬取)
'''爬取内涵吧段子所有笑话(带标题,作者)总结:解码上,使用gbk2312编码的,我们可以采取gbk解码. 不会报错'''from fake_useragent import FakeUserAge ...
- WPF Binding表达式
前言: WPF BindingBinding表达式的使用,可以很方便的绑定参数和更新界面数据. 1.界面添加控件,并设置对应属性的Binding表达式,例如: <Window x:Class=& ...
- python基础篇 13-模块的导入 安装第三方模块
一.模块 一个python文件就是一个模块 标准模块(内置模块) 第三方模块 需要自己安装的 自己写的 需要导入的 import 一个模块的实质: 实际上就是把一个py文件从头到尾执行了一遍,main ...
- sql:常用:group by 多个字段
首先group by 的简单说明: group by 一般和聚合函数一起使用才有意义,比如 count sum avg等,使用group by的两个要素: (1) 出现在select后面的字段 ...
- Arthas 查询服务器内存数据
1.打开Arthas所在位置 eg:/home 2.java -jar arthas-boot.jar 运行jar包 3.选择要执行的java jar包 eg : 1 4.执行查看命令vmtool - ...
- pyahocorasick 安装和使用问题总结
因系统中用到了ahocorasick,但是程序跑起来有BUG,故而10.1假期研究了一下,趟过几个坑,分享一下. 一.安装过程中的坑 直接安装pip install pyahocorasick 是会 ...
- 12.21linux学习第二十天
今天老刘讲最后一章,第20章使用LNMP架构部署动态网站环境.定制安装17个安装包,编译安装要花很长时间,需要漫长的等待. LNMP动态网站部署架构是一套由Linux + Nginx + MySQL ...
- 基于vue2.0创建vue项目
一.安装node环境 1.下载地址为:https://nodejs.org/en/ 2.检查是否安装成功:如果输出版本号,说明我们安装node环境成功 3.为了提高我们的效率,可以使用淘宝的镜像:ht ...
- Training time_SSM
三阶段 MyBatis 1 三层架构介绍 2 MyBatis介绍 类库:对于现有技术的一个封装. 框架:对于一个问题的一整套解决方案. MyBatis是一个半自动的ORM持久层的框架.刚开始叫做iBa ...
- spring中事物是怎么实现的?
Spring容器事务 声明式和编程式 当需要用到事务操作的地方很少的时候,那么就可以使用编程方式 TransactionTemplate,它不会建立很多事务代理.但是,如果程序中用到大力的事务操作,声 ...