【网络通信 -- 直播】WebRTC -- 多人音视频通讯架构与主流服务器简介
发布日期:2021-05-07 20:53:02 浏览次数:29 分类:精选文章

本文共 5777 字,大约阅读时间需要 19 分钟。

【网络通信 -- 直播】WebRTC -- 多人音视频通讯架构与主流服务器简介

【0】WebRTC 一对一通信流程

WebRTC 本身提供的是 1 对 1 的通信模型,在 STUN/TURN 的辅助下,若能实现 NAT 穿越,那么两个浏览器便可以直接进行媒体数据交换;若不能实现 NAT 穿越,那么只能通过 TURN 服务器进行数据转发的方式实现通信;

在 1 对 1 通信中,WebRTC 首先尝试两个终端之间是否可以通过 P2P 直接进行通信,若终端之间无法直接通信,则会通过 STUN/TURN 服务器进行中转;若端与端之间可以直接通信,那么 STUN/TURN 服务器的作用便只是用于各终端收集 reflx 类型的 Candidate;

图示可以分为 4 部分

  • 两个 WebRTC 终端,负责音视频采集、编解码、NAT 穿越、音视频数据传输;
  • 一个 Signal(信令)服务器,负责信令处理,如加入房间、离开房间、媒体协商消息的传递等;
  • 一个 STUN/TURN 服务器,负责获取 WebRTC 终端在公网的 IP 地址,以及 NAT 穿越失败后的数据中转;

大致交互流程概述

  • 当一端(WebRTC 终端)进入房间之前,首先会检测自己的设备是否可用;若此时设备可用,则进行音视频数据采集;采集到的数据一方面可以做预览,另一方面,可以将其录制下来保存成文件,等到视频通话结束后,上传到服务器供用户回看;
  • 在获取音视频数据就绪后,WebRTC 终端要发送 “加入” 信令到 Signal 服务器;Signal 服务器收到该消息后会创建房间;在另外一端,也要做同样的事情,只不过它不是创建房间,而是加入房间;待第二个终端成功加入房间后,第一个用户会收到 “另一个用户已经加入成功” 的消息;
  • 此时,第一个终端将创建 “媒体连接” 对象,即 RTCPeerConnection,并将采集到的音视频数据通过 RTCPeerConnection 对象进行编码,最终通过 P2P 传送给对端;
    • 在进行 P2P 穿越时很有可能失败,当 P2P 穿越失败时,为了保障音视频数据仍然可以互通,则需要通过 TURN 服务器进行音视频数据中转;
  • 当音视频数据来到对端后,对端首先将收到的音视频数据进行解码,最后再将其展示出来,这样就完成了一端到另一端的单通;
  • 若双方要互通,两方都要通过 RTCPeerConnection 对象传输自己一端的数据,并从另一端接收数据;

【1】多人音视频通讯架构

【1.1】Mesh 方案

Mesh 方案,即多个终端之间两两进行连接,形成一个网状结构;比如 A、B、C 三个终端进行多对多通信,当 A 想要共享媒体(比如音频、视频)时,A 需要分别向 B 和 C 发送数据;同样的道理,B 想要共享媒体,就需要分别向 A、C 发送数据,依次类推;该方案对各终端的带宽要求比较高;

在上图中,B1、B2、B3、B4 分别表示 4 个浏览器,它们之间两两相连,同时还分别与 STUN/TURN 服务器进行连接;

优势

  • 不需要服务器中转数据,STUN/TUTN 只是负责 NAT 穿越,这样利用现有 WebRTC 通信模型就可以实现,而不需要开发媒体服务器;
  • 充分利用了客户端的带宽资源;
  • 节省了服务器资源,由于服务器带宽往往是专线,价格昂贵,这种方案可以很好地控制成本;

劣势

  • 共享端共享媒体流时,需要给每一个参与人都转发一份媒体流,这样对上行带宽的占用很大;并且占用较大的 CPU、Memory 等资源;
    • 一般来说,客户端的机器资源、带宽资源往往是有限的,资源占用和参与人数呈线性相关;导致多人通信的规模非常有限;
  • 在多人通信时,若存在部分人不能实现 NAT 穿越,但还想让这些人与其他人互通,就显得很麻烦,需要做出更多的可靠性设计;

【1.2】MCU(Multipoint Conferencing Unit)方案

MCU(Multipoint Conferencing Unit)方案,该方案由一个服务器和多个终端组成一个星形结构;各终端将自己要共享的音视频流发送给服务器,服务器端会将在同一个房间中的所有终端的音视频流进行混合,最终生成一个混合后的音视频流再发给各个终端,这样各终端就可以看到 / 听到其他终端的音视频;实际上服务器端就是一个音视频混合器,这种方案服务器的压力会非常大;

MCU 方案的模型是一个星形结构,如下图所示

  • B1 与 B2 同时共享音视频流,它们首先将流推送给 MCU 服务器,MCU 服务器收到两路流后,分别将两路流进行解码,之后将解码后的两路流进行混流,然后再编码,编码后的流数据再分发给 B3 和 B4;
  • 对于 B1 由于其是其中一个共享者,因此 MCU 给 B1 推的是没有混合其共享流的媒体流,此例中是直接推 B2 的流给 B1
  • 对于 B2 来说 MCU 给 B2 发的是 B1 的共享流;

MCU 主要的处理逻辑如下图所示

处理过程

  • 1. 接收共享端发送的音视频流;
  • 2. 将接收到的音视频流进行解码;
  • 3. 对于视频流,要进行重新布局,混合处理;
  • 4. 对于音频流,要进行混音、重采样处理;
  • 5. 将混合后的音视频进行重新编码;
  • 6. 发送给接收客户端;

优势

  • 1. 技术成熟,在硬件视频会议中应用非常广泛;
  • 2. 作为音视频网关,通过解码、再编码可以屏蔽不同编解码设备的差异化;
  • 3. 将多路视频混合成一路,所有参与人看到的是相同的画面;

劣势

  • 1. 重新解码、编码、混流,需要大量的运算,对 CPU 资源的消耗很大;
  • 2. 重新解码、编码、混流还会带来延迟;
  • 3. 由于机器资源耗费很大,所以 MCU 所提供的容量有限,一般十几路视频就是上限了;

【1.3】SFU(Selective Forwarding Unit)方案

SFU(Selective Forwarding Unit)方案,该方案由一个服务器和多个终端组成,SFU 不对音视频进行混流,收到某个终端共享的音视频流后,就直接将该音视频流转发给房间内的其他终端,实际上是一个音视频路由转发器;

图中,B1、B2、B3、B4 分别代表 4 个浏览器,每一个浏览器都会共享一路流发给 SFU,SFU 会将每一路流转发给共享者之外的 3 个浏览器

优势

  • 1. 由于是数据包直接转发,不需要编码、解码,对 CPU 资源消耗很小;
  • 2. 直接转发也极大地降低了延迟,提高了实时性;
  • 3. 带来了很大的灵活性,能够更好地适应不同的网络状况和终端类型;

劣势

  • 1. 由于是数据包直接转发,参与人观看多路视频的时候可能会出现不同步;相同的视频流,不同的参与人看到的画面也可能不一致;
  • 2. 参与人同时观看多路视频,在多路视频窗口显示、渲染等会带来很多麻烦,尤其对多人实时通信进行录制,多路流也会带来很多回放的困难;

【1.3.1】SFU -- Simulcast 模式

所谓 Simulcast 模式就是指视频的共享者可以同时向 SFU 发送多路不同分辨率的视频流,SFU 可以将接收到的三路流根据各终端的情况选择其中某一路发送出去;Simulcast 模式对移动端的终端类型非常有用,可以灵活而又智能地适应不同的网络环境;

【1.3.2】SFU -- SVC 模式

SVC 是可伸缩的视频编码模式,其在视频编码时将视频分成多层,即核心层、中间层和扩展层;上层依赖于底层,而且越上层越清晰,越底层越模糊;在带宽不好的情况下,可以只传输底层,即核心层,在带宽充足的情况下,可以将三层全部传输过去;

图示,PC1 共享的是一路视频流,编码使用 SVC 分为三层发送给 SFU;SFU 根据接收端的情况,发现 PC2 网络状况不错,于是将 0、1、2 三层都发给 PC2;发现 Phone 网络不好,则只将 0 层发给 Phone;从而可以适应不同的网络环境和终端类型;

【2】主流服务器简介

【2.1】LicodeLicode

源码地址,

LicodeLicode 既可以用作 SFU 类型的流媒体服务器,也可以用作 MCU 类型的流媒体服务器;一般情况下,用于 SFU 类型的流媒体服务器;

Licode 不仅仅是一个流媒体通信服务器,而且还是一个包括了媒体通信层、业务层、用户管理等功能的完整系统,并且该系统支持分布式部署;
Licode 是由 C++ 和 Node.js 语言实现,其中,媒体通信部分由 C++ 语言实现,而信令控制、用户管理、房间管理用 Node.js 实现;
整体框架

  • Nuve 是一个 Web 服务,用于管理用户、房间、产生 token 以及房间的均衡负载等相关工作;它使用 MongoDB 存储房间和 token 信息,但不存储用户信息;
  • ErizoController,用于管理控制,信令和非音视频数据都通过它接收;它通过消息队列与 Nuve 进行通信,即 Nuve 可以通过消息队列对 ErizoController 进行控制;
  • ErizoAgent,用于音视频流媒体数据的传输,可以分布式布署;ErizoAgent 与 ErizoController 的通信也是通过消息队列,信令消息通过 ErizoController 接收到后,再通过消息队列发给 ErizoAgent,从而实现对 ErizoAgent 的控制;

劣势

  • 1. 在 Linux 下目前只支持 Ubuntu 14.04 版本,在其他版本上很难编译通过;
  • 2. Licode 不仅包括了 SFU,而且包括了 MCU,其代码结构比较重,学习和掌握比较复杂;
  • 3. Licode 的性能一般

【2.2】Janus-gatewayJanus

源码地址,

Janus-gatewayJanus 是一个非常有名的 WebRTC 流媒体服务器,它是以 Linux 风格编写的服务程序,采用 C 语言实现,支持 Linux/MacOS 下编译、部署,但不支持 Windows 环境;

整体框架

插件层/应用层

插件层又称为应用层,每个应用都是一个插件,可以根据用户的需要动态地加载或卸载掉某个应用;

在 Janus 中默认支持的插件包括

  • SIP:这个插件使得 Janus 成了 SIP 用户的代理,从而允许 WebRTC 终端在 SIP 服务器(如 Asterisk)上注册,并向 SIP 服务器发送或接收音视频流;
  • TextRoom:该插件使用 DataChannel 实现了一个文本聊天室应用;
  • Streaming:允许 WebRTC 终端观看 / 收听由其他工具生成的预先录制的文件或媒体;
  • VideoRoom:实现了视频会议的 SFU 服务,实际就是一个音 / 视频路由器;
  • VideoCall:这是一个简单的视频呼叫的应用,允许两个 WebRTC 终端相互通信;
  • RecordPlay:可以将发送给 WebRTC 的数据录制下来,可以通过 WebRTC 进行回放;

传输层

  • 媒体数据传输层主要实现了 WebRTC 中需要的流媒体协议及其相关协议,如 DTLS 协议、ICE 协议、SDP 协议、RTP 协议、SRTP 协议、SCTP 协议等;
  • 信令传输层用于处理 Janus 的各种信令,支持的传输协议包括 HTTP/HTTPS、WebSocket/WebSockets、NanoMsg、MQTT、PfUnix、RabbitMQ;

【2.3】Mediasoup

源码地址,

Mediasoup 由应用层和数据处理层组成;应用层通过 Node.js 实现;数据处理层由 C++ 语言实现,包括 DTLS 协议实现、ICE 协议实现、SRTP/SRTCP 协议实现、路由转发等;

整体架构

Mediasoup 把每个实例称为一个 Worker,在 Worker 内部有多个 Router,每个 Router 相当于一个房间;在每个房间里可以有多个用户或参与人,每个参与人在 Mediasoup 中由一个 Transport 代理;即对于房间(Router)一个 Transport 就相当于一个用户;

  • WebRtcTransport 用于与 WebRTC 类型的客户端进行连接,如浏览器;
  • PlainRtpTransport 用于与传统的 RTP 类型的客户端连接,通过该 Transport 可以播放多媒体文件、FFmpeg 的推流等;
  • PipeTransport 用于 Router 之间的连接,即一个房间中的音视频流通过 PipeTransport 传到另一个房间;

在每个 Transport 中可以包括多个 Producer 和 Consumer

  • Producer 表示媒体流的共享者,它分为两种类型,即音频的共享者和视频的共享者;
  • Consumer 表示媒体流的消费者,它分为两种类型,即音频的消费者和视频的消费者;

【2.4】MedoozeMedooze

源码地址,

MedoozeMedooze 是一款综合流媒体服务器,它不仅支持 WebRTC 协议栈,还支持很多其他协议,如 RTP、RTMP 等;

整体架构

核心层

  • Medooze 支持 RTP/RTCP、SRTP/SRCP 等相关协议,可以实现与 WebRTC 终端进行互联;
  • Medooze 可以接入 RTP 流、RTMP 流等,可以使用 GStreamer/FFmpeg 向 Medooze 推流;
  • Medooze 还支持录制功能,以便后期回放;

控制逻辑层

  • Medooze 的控制逻辑层通过 Node.js 实现,Medooze 通过 Node.js 对外提供了完整的控制逻辑操作相关的 API,通过这些 API 可以很容易的控制 Medooze 的行为;

缺点

  • Medooze 使用的异步 IO 事件处理的 API 是 poll,poll 在处理异步 IO 事件时,与 Linux 下最强劲的异步 IO 事件 API epoll 相比要逊色不少

参考致谢

本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。

【1】

【2】

【3】

上一篇:【网络通信 -- 直播】音视频常见封装格式 -- MEPG2 TS
下一篇:【C/C++基础进阶系列】C/C++ 常见知识点总结

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年04月09日 15时51分16秒