写点什么

从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧

  • 2019-10-08
  • 本文字数:3179 字

    阅读完需:约 10 分钟

从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧

Zoom 是一款受到广泛使用的在线会议软件。相信各位一定在办公、会议、聊天等各种场景下体验或者使用过,作为一款成熟的商业软件,Zoom 提供了稳定的实时音视频通话质量,以及白板、聊天、屏幕共享、PPT 放映等常用功能。但是在当今浏览器成为端上主流的时代,实时音视频又怎甘于落后呢?相比于需要安装包的 Zoom,直接在网页上开发一款类似的会议软件肯定会受到更多的关注。当需要开会的时候,直接通过一个链接,大家就可以接入并开始会议了。现在,使用七牛实时音视频的 Web SDK,我们可以将您的想法轻松变为现实。


首先,让我们梳理一下一款 Web 的在线会议产品需要哪些关键点需要攻破。


  • 浏览器兼容性要好,需要支持大部分主流桌面浏览器


七牛云实时音视频基于 Google 在 Chrome 上推行的 WebRTC 协议,目前该协议已经正式写入 Web 标准之中,所有的现代浏览器对其都有很好的兼容性。


  • 通话质量要好,延迟低,清晰度高


不同于传统 WebRTC 采用用户和用户 P2P 的形式进行通信,我们使用了在全球范围内部署的节点作为低延迟的实时互动网络来和各个端上进行 P2P 通信,在保证延迟的同时也保证了通话的质量。


  • 会议功能要丰富,ppt 演示、白板、屏幕共享等等我都要


我们的 SDK 提供了丰富的功能列表,满足绝大多数会议场景的需求,理论上使用 SDK 可以完全复刻一个 Web 版本的 zoom。


  • 说了这么多,接入难不难?有没有示例和文档?


当然!目前就可以体验我们 Web 的 Demo(在桌面浏览器下打开)


Demo 的源码开源在 Github 上供各位参考


这个 Demo 实现了绝大多数 SDK 直接提供的功能,集成白板/ PPT 共享/聊天等场景的 Demo 目前还在准备上线中,敬请期待。关于接入的具体过程我们下面将简单地介绍一遍,详细的说明和参考可以移步我们的文档站

开发流程

一个简单的会议产品,一般是通过如下流程:


  • 用户注册/登陆 (开发者自己集成,SDK 只需要用于区分用户的 userID)

  • 创建一个会议房间/加入一个会议房间

  • 采集自己的摄像头/麦克风数据

  • 将采集到的媒体数据发布到房间中

  • 订阅房间里其他人的媒体数据并实时播放

  • 处理用户加入/离开,发布/取消发布


这里简化到 SDK 的各个功能,其实就是 加入房间-采集本地媒体流-发布媒体流-订阅媒体流-事件处理,SDK 对每个步骤都做了简单的封装,使用几行代码即可搞定。

01 引入 SDK

推荐使用 npm 引入我们的 SDK,直接 npm i pili-rtc-web 即可,或者可以选择直接引入打包好的 js 文件

02 异步处理

实时音视频是一个强异步的场景,各种各样的操作因为涉及到网络都是异步相关的,为了让开发者能够更好地控制代码编写过程中的异步逻辑。SDK 没有使用繁琐的 callback 模式,而是使用了现代 Javascript 的 async/await 或者是 Promise 特性来编写异步代码,尽量避免了开发过程中回调地狱的情况(以下所有 await 代码都假定在一个 async 函数包裹之下)。

03 加入房间

准备完毕后,第一步,加入房间。说是加入房间,抽象后的说法其实是「什么用户以什么身份加入什么房间」。这里有 3 个未知量:用户标识、身份标识(权限)、房间标识。其实整个加入房间的过程需要的未知量还有很多,比如房间隶属于哪个 APP(应用,不同应用中房间独立),APP 隶属于哪个七牛账户等等。在这里我们将这些值统一进行编码签名,变成一个 roomToken 提供给前端,端上就只需要通过这个 token 即可加入房间。(token 的生成可以在七牛控制台完成,也可以使用服务端 SDK 根据需要动态生成)


const myRTC = new QNRTC.QNRTCSession(); // 初始化await myRTC.joinRoomWithToken(ROOM_TOKEN); // 加入房间
复制代码

04 采集本地媒体流

一般采集都会同时采集音频和视频,即麦克风和摄像头,但是根据需求 SDK 也支持纯音频采集或者纯视频采集的模式。调用方法也很简单,更改一下 options 即可。


const DOM_ELEMENT = ... // 页面上准备用来播放流的 dom 元素// 采集本地流const localStream = await QNRTC.deviceManager.getLocalStream({    video: { enabled: true },    audio: { enabled: true },});// 播放采集到的流localStream.play(DOM_ELEMENT)
复制代码

05 发布媒体流

直接将刚刚拿到的流对象作为参数,调用 publish 方法即可:


await myRTC.publish(localStream);
复制代码

06 订阅媒体流

当加入房间成功后,随时可以通过访问 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);    } });
复制代码

07 事件处理

SDK 暴露了丰富的事件列表来满足绝大多数场景的需求,事件的处理也很简单,以「有其他用户发布」这个事件为例:


// 监听事件myRTC.on('user-publish', handleUserPublish);// 只监听一次myRTC.once('user-publish', handleUserPublish);// 取消某个监听函数myRTC.off('user-publish', handleUserPublish);// 取消所有监听函数myRTC.removeAllListeners('user-publish');
复制代码


具体的事件列表可以参考

特色功能

除了这些基本的功能,SDK 还提供了很多强大的高级功能,进一步满足各行各业的使用需求。

01 屏幕共享

除了直接采集摄像头,SDK 还支持进行屏幕采集(或者窗口采集)来实现共享屏幕进行会议。并且在屏幕共享和摄像头采集之间支持无缝切换,保证用户的使用体验。


// 屏幕共享await QNRTC.deviceManager.getLocalStream({    screen: { enabled: true },    audio: { enabled: true },});
复制代码

02 直播转推

对于一个在线会议而言,参与会议讨论的可能只有十个人左右,而却有大部分的人需要实时地观看这场会议(但不参与实时讨论)。这就是实时音视频和直播两大块场景的交集,将少数有实时互动需求的用户分配到超低延迟( 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,可以访问我们的牛课堂体验


以上只是列举了一款会议软件常用的功能场景,将这些基本功能和用户自身的场景集成,一款简单的会议软件就能够轻松完成。如果您已经打算开始尝试并体验一下,访问我们的 Demo(见上)会是一个很好的选择。如果您打算将自己的产品接入到我们实时音视频中,这里有一份更详细的实时音视频应用开发实践,从 html/css 到 js,从每一行代码到每一个功能都有详细的解释和示例,帮助您快速接入。


本文转载自公众号七牛云(ID:qiniutek)。


原文链接:


https://mp.weixin.qq.com/s/_acp9l5FEm94TZRO9XDLhA


2019-10-08 23:032569

评论 1 条评论

发布
用户头像
使用七牛云/RTC服务可联系微信GJ333333333,注:(9个3)
2021-06-02 11:00
回复
没有更多了
发现更多内容

手把手教你使用Studio Lite + Digtal car!助力智能汽车场景、轻应用开发更轻松!

SOA开发者

互斥锁、自旋锁、读写锁...理清它们的区别和应用

行云创新

云计算 编程 开发 应用

如何让文件共享 SDK 支持使用 Uri 上传文件

ZEGO即构

文件存储 分区存储 文件共享

JVM g1 gc 学习笔记二

风翱

GC 9月日更

【Flutter 专题】138 图解自定义国旗渐变头像

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 10月月更

003云原生之架构原则

穿过生命散发芬芳

云原生 10月月更

行云创新:云原生技术助力企业数字化转型

行云创新

技术 云原生 转型 数字化 平台

北鲲云超算平台如何将云计算与高性能计算结合

北鲲云

在线GIF图片帧修改工具

入门小站

工具

【实战】基于TensorRT 加速YOLO系列以及其他加速算法实战与对比

cv君

AI 引航计划

翻译积累 - Java正则表达式Pattern类

小马哥

翻译 日更

金九银十不要怕!有了腾讯这本2021年最新Java面试手册,offer手到擒来!

Java 程序员 架构 面试 后端

重磅来袭,虚拟化技术分类

hanaper

音视频终端引擎优化实践

百度开发者中心

最佳实践 音视频 实践案例 智能视频 行业深度

通俗易懂!306页图解计算机网络,涵盖所有基础知识

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

强烈推荐!88页《Redis学习文档》完整版,PDF开放下载

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

Docker OOM Killer

AiDaddy

Docker JVM trouble shooting

[27]智慧金融--AI目前最被看好的落地领域

Databri_AI

人工智能

打造“大国重器”高性能计算,联想与英特尔如何携手点亮数字经济加速度?

脑极体

华为大牛总结的超全Linux学习笔记,看这一篇就够了!

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

一文了解「模块化」 区块链的当前形势:执行、安全性及数据可用性

CECBC

手把手教学基于深度学习的遥感影像倾斜框算法训练与分析

cv君

AI 引航计划

以匠心正道,以决心致远:毫末智行的自动驾驶之路

脑极体

FunTester框架Redis性能测试之map & INCR

FunTester

redis 性能测试 测试框架 测试开发 FunTester

CTF压轴题解题思路和过程

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

002云原生之架构定义

穿过生命散发芬芳

云原生 9月日更

智能网联汽车行业信息安全现状与威胁

SOA开发者

5G三年成厦,泛在千兆为应用造榫卯

脑极体

linux线上CPU100%排查

入门小站

Linux

谈 C++17 里的 State 模式之二

hedzr

c++ 算法 设计模式 Design Patterns 有限状态机

自动驾驶混战,剑气二宗谁能笑傲江湖?

白洞计划

从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧_文化 & 方法_张显阳_InfoQ精选文章