快来,视频会议要开始了
Posted DataFlow范式
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快来,视频会议要开始了相关的知识,希望对你有一定的参考价值。
温习下面的几张图片,感受一下今天将带来的主题氛围。
笔者早在好几年前,做过一段时间的音视频流媒体技术的开发,当然大部分都是自娱自乐,没有实际的生产项目。那么多年过去了,音视频技术成熟度提升很大,而且由于今年的特殊原因,加快了实时音视频应用的爆发。
今天,笔者希望和读者一起重新回顾一下音视频实时互动的流媒体技术。由于音视频流媒体涉及的技术太广,包括但不限于:
C/C++ 底层开发
高性能网络服务器
TCP/UDP/RTP/RTCP/SRTP/SRTCP/DTLS/STUN/SDP 等协议
WebRTC 协议栈
异步 I/O 事件处理
音视频编解码器 H.264/H.265/VP8/VP9 等
媒体协商
信令控制
音视频互动技术的 Mesh/MCU/SFU 架构模型
流媒体服务器 Mediasoup、Janus 等
...
不过,笔者会站在小白用户的角度,从介绍基础内容,再涉及现在流行的 WebRTC,最后通过本地实战部署音视频实时互动项目,实现自家的笔记本、手机、ipad 等实时互动,达到自言自语的目的,让大家体会到成就感。
流媒体
音视频,大家应该都很清楚,通俗来讲就是声音和视频。
引入一个专业术语,流媒体是什么呢?
其实流媒体不是一种新的媒体,而是一种新的媒体传送方式,比如有声音流、视频流、文本流、图像流、动画流等。流媒体和大数据生态中的流数据类似,只是一种传递的方式。
那么流媒体技术又是做什么的呢?举个栗子:
在多人实时互动的会议中,大家共享音视频,那么你的声音和视频是如何推送给其他所有人的,其他人的音视频又是如何拉取到你的客户端的,网络传输的都是数据,其实这里面就会使用流媒体技术。简单总结就是,流媒体技术是将一连串的媒体数据(声音、视频等)压缩后,以流的方式在网络中分段传送,实现在网络上实时传输音视频以供客户端接收的一种技术。
既然涉及到数据实时传输,那么就需要对数据传输的协议进行规范化。
流媒体传输的网络协议
流媒体协议比较多,笔者挑几个基础的来讲,大家就会明白的。
对于实时音视频流媒体来说,用户期望音视频数据能够及时地从一端传输到另一端,比如网络直播等,其实对于少量的丢包对于用户的观看体验效果影响不明显,但是如果出现较大的延迟和卡顿则严重影响观看体验。由于 TCP 的拥塞控制技术不太适用于这种快速而稳定的流媒体传输,并且重传机制(尤其在极端网络情况下)对于实时流媒体来说既影响效率又没必要,因此,这种情况下一般采用基于 UDP 的方式。
对于 UDP 协议来说,它提供了无连接通信,且不对传送的数据包进行可靠性保证,具有延迟小、数据传输效率高的优点,因此较多地应用于音视频的实时传输。
什么是 RTP
虽然协议这块比较枯燥,但是读者还是需要了解一下,否则总会感觉缺少点东西。但是笔者不会深入讲解协议的头结构、报文细节以及各字段含义,以及通信过程等复杂内容,所以剩下的内容还是值得了解的。
RTP,全名是 Real-time Transport Protocol(实时传输协议)。它是 IETF(国际互联网业界具有一定权威的网络相关技术研究团体,知道很牛就行了)提出的一个标准,对应的 RFC 文档为 RFC3550。RFC3550 不仅定义了 RTP,而且定义了配套的相关协议 RTCP(Real-time Transport Control Protocol,即实时传输控制协议)。
RTP 和 RTCP 各有用途:
RTP 用来为语音、视频等实时传输的多媒体数据提供端到端的实时传输服务。RTP 通常使用 UDP 来传送数据,并不保证服务质量,也不保证数据包的顺序可靠传递以及没有流量控制和拥塞控制,这些都依靠 RTCP 来提供服务。
RTCP 和 RTP 一起提供流量控制和拥塞控制服务,RTCP 根据实时统计信息,进行流量和拥塞控制。RTP 和 RTCP 配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特适合传送网上的实时数据传输。
我们总结一下 RTP 和 RTCP:
1. RTP/RTCP 为实际的实时流传输协议
2. 整个 RTP 协议由两个密切相关的部分组成:RTP 数据协议和 RTP 控制协议(即RTCP)
RTP 的应用环境
RTP 用在单播或多播网络中传送实时数据,典型的应用场景有简单的多播音频会议、音视频会议和翻译器和混合器等。
为啥又有 RTSP
RTP/RTCP 看起来已经很完善了,为啥又折腾出一个 RTSP 协议呢?
其实可以简单地这样理解:RTP/RTCP 属于偏底层的数据传输的协议(可以回想一下 CM 和 CDH 关系),但是缺少一个应用层的协议。那么笔者还是先讲解完 RTSP,然后大家应该会明白一些的。
RTSP,即实时流协议(Real Time Streaming Protocol),RTSP 通常工作于可靠的传输协议 TCP 之上,用于发起/结束流媒体传输,交换流媒体元信息。从整个体系结构来看,RTSP 位于 RTP 和 RTCP 之上,它可以使用 TCP 或 RTP 完成数据传输。
RTSP 实时流协议,作为一个应用层协议,提供了一个可供扩展的框架,主要用来控制具有实时特性的数据发送,但它本身并不传输数据,而是必须依赖于下层传输协议(TCP 或 RTP)所提供的某些服务。RTSP 可以对流媒体提供诸如播放、暂停、快进以及检索媒体、添加媒体、邀请加入等操作,它负责定义具体的控制消息、操作方法、状态码等,此外还描述了与 RTP 间的交互操作。
前面都是铺垫环节,下面来讲今天的主角 WebRTC。
WebRTC
简史
RTC(Real-time communication),实时通信。音视频实时通信发展很多年了,一直是一项具有挑战性的工作,涉及的技术太多,笔者在文章开头提到的只是一部分,而且上面只是讲解了部分流媒体协议。
回顾历史,由于网络带宽容量,以及业界的一些音视频技术不开源,开发出的产品昂贵,所以存在一段时间发展进度缓慢。
在 2011 年,Google 收购 GIPS 公司(GIPS 公司原是世界顶尖的互联网音视频方案提供商,一家从事音视频实时互动引擎开发的公司,其在音频编解码、网络传输方面具有多年的技术积累和优势),并将其技术重新组织,开源成为现在的 WebRTC。
那么 WebRTC 是什么?我们访问官网(https://webrtc.org),看到一句话,简明扼要:
Real-time communication for the web
借助 WebRTC,可以在基于开放标准的应用程序中添加实时通信功能。它支持在客户端之间发送视频、语音和通用数据,从而使开发人员能够构建功能强大的语音和视频通信解决方案。该技术可在所有现代浏览器以及所有主要平台的本机客户端上使用。WebRTC 背后的技术被实现为一个开放的 Web 标准,并在所有主要浏览器中均以常规 javascript API 的形式提供。对于本机客户端(例如android和ios应用程序),可以使用提供相同功能的库进行开发。WebRTC 项目是开源的,并得到 Apple,Google,Microsoft 和 Mozilla 等的支持。
总结一下,WebRTC 是一个免费、开放的项目,使 Web 浏览器(例如 Chrome、Firefox、Opera 等)通过简单的 JavaScript API 接口实现实时通信功能。
WebRTC 极大的降低了音视频技术的门槛,一个小的团队都可以基于开源的媒体服务器开发音视频交互应用产品。
可以做什么
WebRTC 提供了许多不同的用例(https://webrtc.github.io/samples/),从使用相机或麦克风的基本 Web 应用程序到更高级的视频通话应用程序和屏幕共享,收集了许多代码示例,以更好地说明该技术的工作原理以及可以使用它的目的。这一块价值非常大,可以参考实现服务端的开发需求。
补充
如今,理解 WebRTC 主要包含两层含义:
由 Google 开源的流媒体客户端,可以进行实时通信,主要应用在浏览器之间实时通信,当然也可以通过使用库来完成移动端、PC 端的通信。
WebRTC 定义了一套标准规范,对客户端进行规范定义,比如客户端行为、媒体协商、通信等。
但是对于服务端的服务,比如信令服务端、中继服务和多人实时互动等,WebRTC 并没有定义,需要由使用 WebRTC 厂商自己去定义和实现。
比较流行的方案是基于 WebRTC 和流媒体服务器结合,实现高性能的多方实时互动通信。
当前主流的流媒体服务器有 Licode、Janus、Medooze 和 mediasoup。在本篇文章,读者会介绍 mediasoup 以及对 mediasoup-demo 进行实战操作。
mediasoup
mediasoup 应用于先进的 WebRTC 视频会议。
mediasoup 特点是:
1. 强大的 SFU 开源实现
由于其通用性、性能和可伸缩性,mediasoup 成为构建多方视频会议和实时流应用程序的理想选择。它具有同步广播、SVC(Scalable Video Coding,可适性视频编码或可分级视频编码,使视频传输更能适应在异质的网络带宽)、传输 BWE(Bandwidth Estimation,WebRTC 和其他 VoIP 系统中用于确定给定会话可用带宽的机制)和许多更先进的功能。
2. Nodejs 模块
除了创建另一个自用服务器之外,mediasoup 是一个 Nodejs 模块,可以将其集成到更大的应用程序中。mediasoup 提供了一个低层 API,该 API 可以根据用户对应用程序启用不同的用例。
3. 客户端库
mediasoup 带有 mediasoup-client(JavaScript 库)和 libmediasoupclient(C ++ 库),用于构建使用统一 API 在任何浏览器或设备中运行的应用程序。或只使用 FFmpeg 或 GStreamer 等软件。
SFU
上面提到了 mediasoup 属于强大的 SFU 架构,即 mediasoup 是 SFU 的一种开源实现。这里笔者讲解什么是 SFU 架构。
SFU(Selective Forwarding Unit),选择性转发单元,是一种通过服务器来路由和转发 WebRTC 客户端音视频数据流的方法。
SFU 通信模型如下:
SFU 服务器最核心的特点是把自己伪装成一个 WebRTC 的 Peer 客户端,WebRTC 的其他客户端其实并不知道自己通过 P2P 连接过去的是一台真实的客户端还是一台服务器。除了伪装成一个 WebRTC 的 Peer 客户端外,SFU 服务器还有一个最重要的能力就是具备一对多通信的能力,即可以将一个 Client 端的数据转发到其他多个 Client 端。
这种网络拓扑结构中,无论多少人同时进行音视频互动,每个 WebRTC 的客户端只需要连接一个 SFU 服务器,上行一路数据即可,极大减少了多人视频通话场景下 Mesh 模型(完全使用 P2P 方式的网络拓扑)给客户端带来的上行带宽压力。
SFU 服务器作为纯粹的数据转发,将数据转发到客户端之后,可以接收到多客户端的数据,对数据进行各种控制或者操作。但是带了一个坏处,如果传输的音视频是采样率大或者高清视频,那么客户端与服务端之间带宽不够的话会导致大量的丢包并影响一些音视频的质量,不过 SFU 也有一系列的配套方案来解决这个问题,如降码率、SVC 分层方式(核心层、拓展层和边缘层)根据带宽来传输不同层的数据。
总结一下,SFU 服务器的优点:
设计具有更好的性能、更高的吞吐量和更少的延迟
具有高度的可扩展性
纯转发,无转码合流,所需资源少,对服务端压力小
灵活性更好,比如可选择性开关任意一路数据的上下行、进行个性化布局(如显示客户端流显示方式)
SFU 在业界比较受欢迎,大部分公司都选择 SFU 方案进行实时音视频架构,常见的开源 SFU 服务器方案有 Licode、Janus,mediasoup 等。
mediasoup 架构
首先看一下 mediasoup 整体架构:
mediasoup 流媒体服务器是由 Nodejs 和 Mediasoup(C++) 两部分组成。
Nodejs 负责 mediasoup 的信令接收与业务管理,比如创建/消毁房间、创建/关闭生产者以及创建/关闭消费者等。
Mediasoup(C++) 这是一个单独的程序,但该程序无法直接启动。因为它在内部会判断是否是 Nodejs 将它启动起来了。只有在 Nodejs 的 mediasoup 管理模块加载之后,再将 Mediasoup(C++) 启动起来,这样它才能正常工作。Nodejs 与 mediasoup 之间通过管道进行通信。
在众多的 WebRTC 流媒体服务器中,mediasoup 可以说是性能最优秀的 WebRTC 流媒体服务器。它使用 C++ 作为开发语言,底层使用 libuv 处理 I/O 事件。
但是,mediasoup 只是提供了一个底层的流媒体库,对于上层的业务逻辑需要我们自己实现,不过内部提供了一个 mediasoup-demo 程序,实现多人的实时音视频互动。
下面笔者带大家进入实战环节。
音视频实时互动实战
环境信息
Mac OS(Ubuntu、基于 Docker 部署等)
Nodejs v10.16.3
npm 6.4.1
gulp 2.2.0
这里只是笔者的环境版本,读者可以随意发挥,只要能跑通即可。
mediasoup-demo 部署
1. 下载源码
$ git clone https://github.com/versatica/mediasoup-demo.git
$ cd mediasoup-demo
$ git checkout v3 # 默认为 v3 分支
2. mediasoup-demo 整体分析
server
服务端 Demo,包括如下信息:
config.js
配置文件。
获取基本的配置信息,提供给 server.js 使用,比如根据服务器核数启动多进程程序,提供服务。
server.js
Demo 主程序。
首先从 config.js 获取到基本配置信息,启动一些服务,比如 https、websocket 等服务。启动完成后,接收信令数据。当客户端发送信令到服务端时,就会根据不同的信令数据做不同的逻辑处理。
connect.js
对后面 interactiveClient.js 文件的封装。
lib
server.js 要使用的库文件。包括以下几个文件:
Logger.js:打印日志。
Room.js:房间管理以及信令处理。
interactiveClient.js:作为交互的客户端,运行时内部信息查询客户端。
interactiveServer.js:作为交互的服务端,运行时内部信息查询服务端。
mediasoup 作为 C++ 部分
lib
js 文件组成,用于对 mediasoup 的管理工作。
worker
C++ 的核心代码。
app 目录
代表客户端代码。
broadcasters 目录
推流的广播模块。
3. 配置服务端
3.1 npm 安装项目依赖包
$ cd mediasoup-demo/server
$ npm --registry https://registry.npm.taobao.org install
错误修复(没有错误跳过)
1. npm install 过程中遇到错误:
NPM Error:gyp: No Xcode or CLT version detected!
首先尝试用如下命令进行修复
$ xcode-select --install
系统提示如下信息:
xcode-select: error: command line tools are already installed, use "Software Update" to install updates
而事实上并没有 Software Update 可以更新。如果前面修复不生效,可以使用如下解决方案:
$ sudo rm -rf $(xcode-select -print-path)
$ xcode-select --install
2. 还有可能会遇到如下问题:
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
报这个错误的原因是 xcode-select 不在默认的路径,解决方法如下:
(1) 找到 xcode-select 的当前路径终端命令行
$ xcode-select --print-path /Library/Developer/CommandLineTools
(2) 设置 xcode-select 到指定位置
$ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/
(3) 验证是否设置成功
$ xcode-select --print-path /Applications/Xcode.app/Contents/Developer
问题都修复成功后,再次执行:
$ npm --registry https://registry.npm.taobao.org install
请耐心等待,包含了 C++ 部分的编译。
3.2 配置文件
$ cd mediasoup-demo/server
$ cp config.example.js config.js
修改 config.js 中的 IP 地址:
config.js 中需要提供 TLS 证书和密钥,我们可以在本地生成:
$ req -x509 -nodes -days 365 -newkey rsa:2048 -subj /CN=Rui -keyout server.key -out server.crt
再次修改 config.js,
配置证书和密钥:
如果部署到服务器上提供公网访问,需要购买域名和证书。
4. 启动服务端
$ cd mediasoup-demo/server
// 如果没有 forever,请使用 npm 安装
$ forever start server.js
5. 启动客户端
$ cd mediasoup-demo/app
$ npm install
$ npm install -g gulp-cli
如果安装比较慢,使用国内镜像仓库,比如 https://registry.npm.taobao.org。
启动客户端:
6. 多用户音视频互动体验
gulp live 执行后,会弹出浏览器。请求访问麦克风和摄像头:
授权后,正常进入房间:
为了本地测试,我们把拷贝该地址(https://192.168.31.52:3000/?info=true&roomId=ezyqzldt),再打开两个窗口,就会出现该房间中有三个用户,如下:
当然在家中局域网内,可以使用手机和平板电脑等同时访问,进行自问自答,或者和小朋友互动。mediasoup-demo 也可以共享屏幕、开启和禁止音视频和文字聊天等功能,大家尽情的实战吧。
通过 Nodejs 实现 Web 服务(补充)
上面我们将 mediasoup-demo 运行在本地,但是如果想让多个人真正使用 mediasoup-demo 时,必须要部署到服务端。
mediasoup 包括三部分:
WWW 服务
信令处理服务
C++ 媒体流处理服务
如果 WWW 服务部署在服务器,没有可视化终端和浏览器,WWW 服务就不能通过 gulp live 命令行方式启动了,而是需要放到 Web 服务上,浏览器直接访问 Web 服务,将客户端代码下载下来,然后再连接信令服务器,最终进行音视频流的互通。
通过 Nodejs 实现 WWW 服务还是比较简单的,感兴趣的读者,可以参考官网实现,如果遇到困难,可以留言交流。
总结
我们来看一下现如今流媒体服务器的应用场景:
在线教育
音视频会议
直播连麦
即时通信
多终端融合
多协议融合
多人互动游戏
远程医疗
5G 时代,必将会加快推进实时互动音视频技术的发展和多元化应用。
参考
https://webrtc.org
https://mediasoup.org
https://github.com/versatica/mediasoup-demo
https://www.jianshu.com/p/651e5cf181fd
以上是关于快来,视频会议要开始了的主要内容,如果未能解决你的问题,请参考以下文章