从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧
zoom(zoom.us) 是一款受到广泛使用的在线会议软件。相信各位一定在办公、会议、聊天等各种场景下体验或者使用过,作为一款成熟的商业软件,zoom 提供了稳定的实时音视频通话质量,以及白板、聊天、屏幕共享、PPT放映等常用功能。但是在当今浏览器成为端上主流的时代,实时音视频又怎甘于落后呢?相比于需要安装包的 Zoom,直接在网页上开发一款类似的会议软件肯定会受到更多的关注。当需要开会的时候,直接通过一个链接,大家就可以接入并开始会议了。现在,使用七牛实时音视频的 Web SDK,我们可以将您的想法轻松变为现实。
首先,让我们梳理一下一款Web的在线会议产品需要哪些关键点需要攻破
- 浏览器兼容性要好,需要支持大部分主流桌面浏览器。
七牛实时音视频基于 Google 在 Chrome 上推行的 WebRTC 协议,目前该协议已经正式写入 Web 标准之中,所有的现代浏览器对其都有很好的兼容性。
- 通话质量要好,延迟低,清晰度高
不同于传统 WebRTC 采用用户和用户 P2P 的形式进行通信,我们使用了在全球范围内部署的节点作为低延迟的实时互动网络来和各个端上进行 P2P 通信,在保证延迟的同时也保证了通话的质量。
- 会议功能要丰富,ppt演示、白板、屏幕共享等等我都要
我们的 SDK 提供了丰富的功能列表,满足绝大多数会议场景的需求,理论上使用 SDK 可以完全复刻一个 Web 版本的 zoom。
- 说了这么多,接入难不难?有没有示例和文档?
当然!目前就可以去体验我们 Web 的 Demo(在桌面浏览器下打开)。https://demo-rtc.qnsdk.com。Demo 的源码也开源在 Github 上供各位参考 https://github.com/pili-engineering/QNRTC-Web
这个 Demo 实现了绝大多数 SDK 直接提供的功能,集成白板/PPT共享/聊天等场景的 Demo 目前还在准备上线中,敬请期待哦。关于接入的具体过程我们下面将会简单地介绍一遍,详细的说明和参考可以移步我们的文档站 https://developer.qiniu.com/rtn/sdk/4412/description-of-web-sdk
开发流程
一个简单的会议产品,一般是通过如下流程:
- 用户注册/登陆 (开发者自己集成,SDK 只需要用于区分用户的 userID)
- 创建一个会议房间/加入一个会议房间
- 采集自己的摄像头/麦克风数据
- 将采集到的媒体数据发布到房间中
- 订阅房间里其他人的媒体数据并实时播放
- 处理用户加入/离开,发布/取消发布
这里简化到 SDK 的各个功能,其实就是 加入房间-采集本地媒体流-发布媒体流-订阅媒体流-事件处理,SDK 对每个步骤都做了简单的封装,使用几行代码即可搞定。
引入 SDK
推荐使用 npm 引入我们的 SDK,直接 npm i pili-rtc-web
即可,或者可以选择直接引入打包好的 js 文件 https://github.com/pili-engineering/QNRTC-Web/blob/master/Release/pili-rtc-web.js
异步处理
实时音视频是一个强异步的场景,各种各样的操作因为涉及到网络都是异步相关的,为了让开发者能够更好地控制代码编写过程中的异步逻辑。SDK 没有使用繁琐的 callback 模式,而是使用了现代 Javascript 的 async/await 或者是 Promise 特性来编写异步代码,尽量避免了开发过程中回调地狱的情况(以下所有 await 代码都假定在一个 async 函数包裹之下)。
加入房间
准备完毕后,第一步,加入房间。说是加入房间,抽象后的说法其实是“什么用户以什么身份加入什么房间”。这里有 3 个未知量:用户标识、身份标识(权限)、房间标识。其实整个加入房间的过程需要的未知量还有很多,比如房间隶属于哪个 APP(应用,不同应用中房间独立),APP 隶属于哪个七牛账户等等。在这里我们将这些值统一进行编码签名,变成一个 roomToken 提供给前端,端上就只需要通过这个 token 即可加入房间。(token 的生成可以在七牛控制台完成,也可以使用服务端 SDK 根据需要动态生成)
const myRTC = new QNRTC.QNRTCSession(); // 初始化
await myRTC.joinRoomWithToken(ROOM_TOKEN); // 加入房间
采集本地媒体流
一般采集都会同时采集音频和视频,即麦克风和摄像头,但是根据需求 SDK 也支持纯音频采集或者纯视频采集的模式。调用方法也很简单,更改一下 options 即可。
const DOM_ELEMENT = ... // 页面上准备用来播放流的 dom 元素
// 采集本地流
const localStream = await QNRTC.deviceManager.getLocalStream({
video: { enabled: true },
audio: { enabled: true },
});
// 播放采集到的流
localStream.play(DOM_ELEMENT)
发布媒体流
直接将刚刚拿到的流对象作为参赛,调用 publish 方法即可
await myRTC.publish(localStream);
订阅媒体流
当加入房间成功后,随时可以通过访问 users 成员来获取当前房间内用户状态,如果房间内存在用户正在发布且不是自己,那么我们就可以发起订阅了
const users = myRTC.users;
users.forEach(async (user) => {
if (user.published && user.userId !== myRTC.userId) {
// 订阅房间其他用户返回的流数据
const remoteStream = await myRTC.subscribe(user.userId);
// 同样,直接调用 play 就可以播放流了
remoteStream.play(DOM_ELEMENT);
}
});
事件处理
SDK 暴露了丰富的事件列表来满足绝大多数场景的需求,事件的处理也很简单,以“有其他用户发布”这个事件为例
// 监听事件
myRTC.on('user-publish', handleUserPublish);
// 只监听一次
myRTC.once('user-publish', handleUserPublish);
// 取消某个监听函数
myRTC.off('user-publish', handleUserPublish);
// 取消所有监听函数
myRTC.removeAllListeners('user-publish');
具体的事件列表可以参考 https://developer.qiniu.com/rtn/sdk/4423/the-event-list-web
特色功能
除了这些基本的功能,SDK 还提供了很多强大的高级功能,进一步满足各行各业的使用需求。
屏幕共享
除了直接采集摄像头,SDK 还支持进行屏幕采集(或者窗口采集)来实现共享屏幕进行会议。并且在屏幕共享和摄像头采集之间支持无缝切换,保证用户的使用体验。
// 屏幕共享
await QNRTC.deviceManager.getLocalStream({
screen: { enabled: true },
audio: { enabled: true },
});
直播转推
对于一个在线会议而言,参与会议讨论的可能只有十个人左右,而却有大部分的人需要实时地观看这场会议(但不参与实时讨论)。这就是实时音视频和直播两大块场景的交集,将少数有实时互动需求的用户分配到超低延迟( 200ms )的实时音视频云上,将大部分只有实时观看需求的用户分配到低延迟( 2~3s )的直播云上,可以最大限度的减少成本满足需求。同时,实时视频流被转推到直播云上后,就可以使用七牛直播云的 API 将这些流数据储存到各个存储空间中进行长期的保存。完成了一个从 实时互动 到 直播观看 到最后 转为文件存储(用于点播等等)的完整业务流程。
首先,在实时音视频云的控制台页面上关联好相应的直播云空间,再打开合流转推的开关。
如果想推送到自定义的 RTMP 地址(不使用七牛直播云),也通过实时音视频云的后端 API 来配置(详细见文档)
之后的工作就是 SDK 上了,使用 SDK 开启直播转推也非常简单,加入房间后调用一行代码即可。
myRTC.setDefaultMergeStream(WIDTH, HEIGHT); // 这里的 width height 对应上文设置的合流输出尺寸
使用这个代码,SDK 将会默认将房间内的所有流平均布局,最终推送到目标 RTMP 地址实现合流转推。如果您想自定义画面布局,可以使用如下 API:
myRTC.setMergeStreamLayout("目标用户ID", { w: 100, h: 100, x: 0, y: 0, muted: false, hidden: false });
另外,我们还提供了网页实时白板的服务,就像 Zoom 一样,用户可以在页面上和房间里的其他用户共享一个白板进行辅助演示,同时白板也支持 PPT 和 PDF 的演示。关于这一块的演示 Demo,可以访问我们的牛课堂体验 https://edu-demo.qnsdk.com。
以上只是列举了一款会议软件常用的功能场景,将这些基本功能和用户自身的场景集成,一款简单的会议软件就能够轻松完成。如果您已经打算开始尝试并体验一下,访问我们的 Demo(见上)会是一个很好的选择。如果您打算将自己的产品接入到我们实时音视频中,这里有一份更为详细的实时音视频应用开发实践https://developer.qiniu.com/rtn/sdk/5043/rtc-application-development-process,从 html/css 到 js,从每一行代码到每一个功能都有详细的解释和示例,帮助您快速接入。
从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧的更多相关文章
- 了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化
本文原文由声网WebRTC技术专家毛玉杰分享. 1.前言 有人说 2017 年是 WebRTC 的转折之年,2018 年将是 WebRTC 的爆发之年,这并非没有根据.就在去年(2017年),WebR ...
- 实时音视频互动系列(上):又拍云UTUN网络详解
如何定义实时音视频互动, 延迟 400ms 内才能无异步感 实时音视频互动如果存在1秒左右的延时会给交流者带来异步感,必须将视频播放延迟限制在400ms以内,才能给用户较好的交互体验. 当延迟控制在4 ...
- 实时音视频互动系列(下):基于 WebRTC 技术的实战解析
在 WebRTC 项目中,又拍云团队做到了覆盖系统全局,保证项目进程流畅.这牵涉到主要三大块技术点: 网络端.服务端的开发和传输算法 WebRTC 协议中牵扯到服务端的应用协议和信令服务 客户端iOS ...
- 融云携新版实时音视频亮相 LiveVideoStack 2019
4 月 19 日,LiveVideoStack 2019 音视频大会在上海隆重开幕,全球多媒体创新专家.音视频技术工程师.产品负责人.高端行业用户等共襄盛会,聚焦音频.视频.图像.AI 等技术的最新探 ...
- 小程序升级实时音视频录制及播放能力,开放 Wi-Fi、NFC(HCE) 等硬件连接功能
“ 小程序升级实时音视频录制及播放能力,开放 Wi-Fi.NFC(HCE) 等硬件连接功能.同时提供按需加载.自定义组件和更多访问层级等新特性,增强了第三方平台的能力,以满足日趋丰富的业务需求.” 0 ...
- 云-腾讯云-实时音视频:实时音视频(TRTC)
ylbtech-云-腾讯云-实时音视频:实时音视频(TRTC) 支持跨终端.全平台之间互通,从零开始快速搭建实时音视频通信平台 1.返回顶部 1. 腾讯实时音视频(Tencent Real-Time ...
- BBR在实时音视频领域的应用
小议BBR算法 BBR全称Bottleneck Bandwidth and RTT,它是谷歌在2016年推出的全新的网络拥塞控制算法.要说明BBR算法,就不能不提TCP拥塞算法. 传统的TCP拥塞控制 ...
- 腾讯互动白板+即时通讯+实时音视频,Android学生端接入
腾讯互动白板+即时通讯+实时音视频,Android学生端接入 一.简介 线上教学方案:腾讯云互动白板(Tencent Interactive Whiteboard,TIW)+即时通信(Instant ...
- 微信小程序+腾讯云直播的实时音视频实战笔记
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
随机推荐
- java实现汉诺塔算法
package com.ywx.count; import java.util.Scanner; /** * @author Vashon * date:20150410 * * 题目:汉诺塔算法(本 ...
- 写给技术lead的招聘指南
工作这么久,面试过的工程师不下两三百人.大部份招到的人都比靠谱当然也有失败的例子.把亲身经历总结如下: 1. 什么人一定不能招: 理解能力差: 对你提出的问题,答不对题,重复提问.面试官可以在面试当中 ...
- Redis杂谈
这是2015年初应邀在南华智闻作技术交流时所作的Redis方面的一个presentation. 因为原件是Keynote格式,已经转成PDF,点击下面链接打开或者下载PDF: Redis 杂谈
- Java遍历HashMap并修改(remove)
遍历HashMap的方法有多种,比如通过获取map的keySet, entrySet, iterator之后,都可以实现遍历,然而如果在遍历过程中对map进行读取之外的操作则需要注意使用的遍历方式和操 ...
- 洛谷 P1163 银行贷款
题目描述 当一个人从银行贷款后,在一段时间内他(她)将不得不每月偿还固定的分期付款.这个问题要求计算出贷款者向银行支付的利率.假设利率按月累计. 输入输出格式 输入格式: 输入文件仅一行包含三个用空格 ...
- SEO 第二章
SEO第二章 1. 掌握搜索引擎工作原理(重点) 2. 了解百度算法 3. 关键词的分类 一.什么是搜索引擎? 搜索引擎是用来实现搜索服务的,说白了搜索引擎也属于一种网站. 浏览器是用来加载网站 ...
- $.noconflict() 有什么用处
jQuery默认使用"$"操作符,prototype等其他框架也是是使用"$",于是,如果jQuery在其他库之后引入,那么jQuery将获得"$&q ...
- https://www.runoob.com/python/python-variable-types.html
https://www.runoob.com/python/python-variable-types.html
- final关键字所修饰的类有什么特点
Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量. final类不能被继承,没有子类,final类中的方法默认是final的. final方法 ...
- VC无窗口控制台程序
VC无窗口控制台程序 #pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartu ...