最原始的直播系统其实并没有想象的那么复杂,无非就是主播端将音视频数据推送到服务器,观众端则从服务器拉取数据播放。
1.1.1 基础概念
观众端
流媒体数据的拉取,同样也需要通过约定的拉流协议来拉取。色彩空间这里我们只讲常用到的两种色彩空间。
因为人眼对亮度敏感,对色度不敏感,因此减少部分UV的数据量,人眼却无法感知出来,这样可以通过压缩UV的分辨率,在不影响观感的前提下,减小视频的体积。
采样率采样率即采样的频率。采样率要大于原声波频率的2倍,人耳能听到的最高频率为20kHz,所以为了满足人耳的听觉要求,采样率至少为40kHz,通常为44.1kHz,更高的通常为48kHz。
采样位数采样位数涉及到声波的振幅量化。波形振幅在模拟信号上也是连续的样本值,而在数字信号中,信号一般是不连续的,所以模拟信号量化以后,只能取一个近似的整数值,为了记录这些振幅值,采样器会采用一个固定的位数来记录这些振幅值,通常有8位、16位、32位。位数越多,记录的值越准确,还原度越高。 由于数字信号是由0,1组成的,因此,需要将幅度值转换为一系列0和1进行存储,也就是编码,最后得到的数据就是数字信号:一串0和1组成的数据。
声道数声道数,是指支持能不同发声(注意是不同声音)的音响的个数。 单声道 :1个声道 双声道 :2个声道 立体声道 :默认为2个声道 立体声道(4声道) :4个声道
码率码率,是指一个数据流中每秒钟能通过的信息量,单位bps(bit per second) 码率 = 采样率 * 采样位数 * 声道数
1.1.2 视频编码
编码可以大大减小音视频数据的大小,让音视频更容易存储和传送。视频编码格式有很多,比如H26x系列和MPEG系列的编码,这些编码格式都是为了适应时代发展而出现的。 其中,H26x(1/2/3/4/5)系列由ITU(International Telecommunication Union)国际电传视讯联盟主导。MPEG(1/2/3/4)系列由MPEG(Moving Picture Experts Group, ISO旗下的组织)主导。
1.1.3 音频编码
原始的PCM音频数据也是非常大的数据量,因此也需要对其进行压缩编码。 和视频编码一样,音频也有许多的编码格式,如:WAV、MP3、WMA、APE、FLAC等等。 在MP4视频中的音频数据,大多数时候都是采用AAC压缩格式。AAC是新一代的音频有损压缩技术,一种高压缩比的音频压缩算法。
1.1.4 音视频容器
我们熟悉的视频格式,如mp4、rmvb、avi、mkv、mov...,其实是包裹了音视频编码数据的容器,用来把以特定编码标准编码的视频流和音频流混在一起,成为一个文件。 例如:mp4支持H264、H265等视频编码和AAC、MP3等音频编码。
1.1.5 硬解码和软解码
在手机或者PC上,都会有CPU、GPU或者解码器等硬件。通常,我们的计算都是在CPU上进行的,也就是我们软件的执行芯片,而GPU主要负责画面的显示(是一种硬件加速)。
所谓软解码,就是指利用CPU的计算能力来解码,通常如果CPU的能力不是很强的时候,一则解码速度会比较慢,二则手机可能出现发热现象。但是,由于使用统一的算法,兼容性会很好。
硬解码,指的是利用手机上专门的解码芯片来加速解码。通常硬解码的解码速度会快很多,但是由于硬解码由各个厂家实现,质量参差不齐,非常容易出现兼容性问题。
通过下面这个数据流程图,能清晰地看到整个直播的过程。
可以看到, 主播客户端 处理的事情,其实就是 短视频开发 中最重要的内容:
唯一不一样的地方,短视频会将封装好的数据保存到本地,直播则是通过 推流协议
将数据推送到服务器。
在直播中,有几个非常重要的地方,会直接影响直播效果,导致用户流失。
1.3.1 首屏时间
首屏时间,即从观众打开直播,到看到画面呈现出来的时间。影响这个时间的是 H264
编码中的一个概念: GOP
。 GOP :Group of Picture,即一组帧组成的一个序列。在 H264
中,分别有 I帧、P帧、B帧 三种帧类型。 GOP
就是由一个 I帧
和多个 P帧
或 B帧
组成的一组相近的画面 。
在H264中,三种类型的帧数据分别为 I帧 :帧内编码帧。就是一个完整帧。 P帧 :前向预测编码帧。是一个非完整帧,通过参考前面的I帧或P帧生成。 B帧 :双向预测内插编码帧。参考前后图像帧编码生成。B帧依赖其前最近的一个I帧或P帧及其后最近的一个P帧。
解码器可以直接解码 I帧
,但是 P帧
和 B帧
必须依赖 I帧
,或者前后的 P或B
才能解码。首次连上直播间时,需要抛弃掉 P
和 B
帧,等待 I帧
。所以,影响首屏时间最重要的因素就是 I帧
,也就是两个 GOP
之间的间隔时间。
GOP 间隔的设置并非越小越好,太小则两个 I帧
之间的 P/B帧
越少,压缩率越低,画面质量越差,需要做好权衡。
1.3.2 稳定性问题
我们知道网络是不稳定的,经常会出现网速慢,甚至断网的问题,所以稳定性优化也是非常重要的。 比如以下几个方面:
1.3.3 全局负载均衡
随着业务的发展,如果主播和观众的数量越来越多以后,系统可能会面临高并发情景,直播卡顿,甚至系统奔溃,解决这种情况的一个好办法就是使用 CDN
。
CDN内容分发解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点加速、点播、直播。
加入 CDN 后,整个直播系统架构如下:
1.3.4 其他
除了以上提到的内容,当今的直播系统还要包括以下内容:录制、转码、鉴黄、截屏、权鉴防盗、回声消除、连麦 等等,整套下来,需要非常多的知识储备,以及大量的时间精力,才能完成。
直播协议包含了上面提到的 推流
和 拉流
协议。
1.4.1 RTP
**实时传输协议( Real-time Transport Protocol ,缩写RTP)**是一个网络传输协议,它是由IETF的多媒体传输工作小组1996年在RFC 1889中公布的。
RTP协议详细说明了在互联网上传递音频和视频的标准数据包格式。它一开始被设计为一个多播协议,但后来被用在很多单播应用中。RTP协议常用于流媒体系统(配合RTSP协议),视频会议和一键通(Push to Talk)系统(配合H.323或SIP),使它成为IP电话产业的技术基础。RTP协议和RTP控制协议RTCP一起使用,而且它是创建在 UDP 协议上的。
1.4.2 RTMP
**实时消息协议( Real-Time Messaging Protocol ,缩写RTMP)**也称实时消息传输协议,是最初由Macromedia为通过互联网在Flash播放器与一个服务器之间传输流媒体音频、视频和数据而开发的一个专有协议。Macromedia后被Adobe Systems收购,该协议也已发布了不完整的规范供公众使用。 RTMP协议有许多变种:
1.4.3 WebRTC标准
WebRTC是一个由谷歌、Mozilla和Opera等支持的开源技术。它通过简单的api为浏览器和移动应用程序提供实时通信(RTC)功能。为浏览器、移动平台和物联网设备开发丰富、高质量的RTC应用程序,并允许它们通过一组通用协议进行通信。 支持的浏览器和平台:
特点:
1.4.4 HLS
HTTP Live Streaming (缩写是HLS)是一个由苹果公司提出的基于HTTP的流媒体网络传输协议。它的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的extended M3U (m3u8) playlist文件,用于寻找可用的媒体流。 HLS只请求基本的HTTP报文,与实时传输协议(RTP)不同,HLS可以穿过任何允许HTTP数据通过的防火墙或者代理服务器。它也很容易使用内容分发网络(CDN)来传输媒体流。
目前 WebRTC 提供了在 Web、iOS、Android、Mac、Windows、Linux 在内的所有平台的 API,保证了 API 在所有平台的一致性。使用 WebRTC 的好处主要有以下几个方面:
P2P(peer to peer)对等通信。 即在p2p的网络中,所有网络节点都是同等地位,没有服务端和客户端之分,一个节点即是服务端也是客户端。客户端之间可以进行直接的通信,不需要在经过服务端的中转,从而提高网络传输速度和减小服务器压力,这是非常有用的。P2P虽然通信模式非常理想,但是有一些问题需要解决:
解决方案:
事实上,大部分的节点都处于常规网络的边缘,甚至在DNS所能查询的范围之外,所以在处于网络的边缘的节点不能直接通信的。
为了能让客户端在不同的网络之间通信,我们就需要穿过防火墙,而且我们还要面对ISP所设置的种种限制。所以为了绕开这些限制,以及在接收端的防火墙上打开一个口让媒体通过,我们就需要依赖STUN/TURN服务器,目的是找到一条正确的路径(STUN),或者是作为一个中继服务器用来传输媒体(TURN)
上图中的Relay server即为TURN中继服务器,而STUN server的作用是通过收集NAT背后peer端(即:躲在路由器或交换机后的电脑)对外暴露出来的ip和端口,找到一条可穿透路由器的链路,俗称“打洞”。STUN/TURN服务器通常要部署在公网上,能被所有peer端访问到。
WebRTC被认为是一种点对点技术,浏览器可以直接通信而无需任何类型的基础设施。此模型足以创建基本应用程序,但难以在其之上实现诸如组通信,媒体流记录,媒体广播或媒体转码之类的功能。因此,许多应用程序都需要使用媒体服务器。
从概念上讲,WebRTC媒体服务器只是一种“多媒体中间件”,从源到目的地时,媒体流量会通过该中间件。媒体服务器能够处理媒体流并提供不同的类型,包括组通信(将一个对等方生成的媒体流分配给多个接收方,即充当多会议单元,MCU),混合(将多个传入流转换为一个单一的复合流) ,转码(在不兼容的客户端之间适应编解码器和格式),录制(以持久的方式存储对等体之间交换的媒体)等。 媒体服务器的好处有如下几点:
当媒体服务器充当媒体中继时,它通常被称为SFU(Selective Forwarding Unit选择性转发单位),这意味着其主要目的是在客户端之间转发媒体流。还有一个MCU(Multipoint Conferencing Unit多点会议单元)的概念,MCU服务器不仅可以转发,而且可以对媒体流进行混合和编码压缩(比如把各个客户端的数据打包转发,和SFU相比,这样将大幅度降低转发数据的带宽需求,但对CPU有更高的要求)。
2.4.1 Mesh架构
每个端都与其它端互连。以上图最左侧为例,5个浏览器,二二建立p2p连接,每个浏览器与其它4个建立连接,总共需要10个连接。如果每条连接占用1m带宽,则每个端上行需要4m,下行带宽也要4m,总共带宽消耗20m。而且除了带宽问题,每个浏览器上还要有音视频“编码/解码”,cpu使用率也是问题,一般这种架构只能支持4-6人左右,不过优点也很明显,没有中心节点,实现很简单。
优点:
缺点:
2.4.2 MCU (MultiPoint Control Unit)
这是一种传统的中心化架构(上图中间部分),每个浏览器仅与中心的MCU服务器连接,MCU服务器负责所有的视频编码、转码、解码、混合等复杂逻辑,每个浏览器只要1个连接,整个应用仅消耗5个连接,带宽占用(包括上行、下行)共10m,浏览器端的压力要小很多,可以支持更多的人同时音视频通讯,比较适合多人视频会议。但是MCU服务器的压力较大,需要较高的配置。
以前在电信行业做视频会议一般都使用MCU(Multipoint Control Unit),也就是多方推流在MCU上进行合流,在拉流的时候只有一路合流,这样的好处是无论几方推流,拉流只有一路,下行带宽比较小。但是问题也比较多,只要推流方一多,MCU的压力就比较大,而且分布式的部署也比较难,成本又很高。
2.4.3 SFU(Selective Forwarding Unit)
上图右侧部分,咋一看,跟MCU好象没什么区别,但是思路不同,仍然有中心节点服务器,但是中心节点只负责转发,不做太重的处理,所以服务器的压力会低很多,配置也不象MUC要求那么高。但是每个端需要建立一个连接用于上传自己的视频,同时还要有N-1个连接用于下载其它参与方的视频信息。所以总连接数为5*5,消耗的带宽也是最大的,如果每个连接1M带宽,总共需要25M带宽,它的典型场景是1对N的视频互动。 SFU 服务器最核心的特点是把自己 “伪装” 成了一个 WebRTC 的 Peer 客户端,WebRTC 的其他客户端其实并不知道自己通过 P2P 连接过去的是一台真实的客户端还是一台服务器,我们通常把这种连接称之为 P2S,即:Peer to Server。除了 “伪装” 成一个 WebRTC 的 Peer 客户端外,SFU 服务器还有一个最重要的能力就是具备 one-to-many 的能力,即可以将一个 Client 端的数据转发到其他多个 Client 端。
这种网络拓扑结构中,无论多少人同时进行视频通话,每个 WebRTC 的客户端只需要连接一个 SFU 服务器,上行一路数据即可,极大减少了多人视频通话场景下 Mesh 模型给客户端带来的上行带宽压力。
SFU 服务器跟 TURN 服务器最大的不同是,TURN 服务器仅仅是为 WebRTC 客户端提供的一种辅助的数据转发通道,在 P2P 不通的时候进行透明的数据转发。而 SFU 是 “懂业务” 的, 它跟 WebRTC 客户端是平等的关系,甚至 “接管了” WebRTC 客户端的数据转发的申请和控制。
现在互联网行业比较流行的是SFU(Selective Forwarding Unit),简单说就是只负责转发流,不负责合流,压力很小。这样的模式可以依托CDN进行分布式的部署,不过拉流的方数限于客户端的带宽和处理能力。
2.4.4 为啥推荐选择 SFU ?
纯 mesh 方案无法适应多人视频通话,也无法实现服务端的各种视频处理需求,最先排除在商业应用之外。
SFU 相比于 MCU,服务器的压力更小(纯转发,无转码合流),灵活性更好(可选择性开关任意一路数据的上下行等),受到更广泛的欢迎和应用,常见的开源 SFU 服务器有:Licode,Kurento,Janus,Jitsi,Mediasoup等。
当然,也可以组合使用 SFU + MCU 的混合方案,以灵活应对不同场景的应用需要。
你是否深刻理解其代码?
代码版本是否足够新?
有谁在使用它?
它的文档是否齐全?
它可以debug吗?
它可以伸缩吗?
它使用哪种语言? 对于媒体服务器而言,这种语言的性能是否足够? 团队是否足够了解这门语言?
是否适应你现有的Signaling范式? 你在看的Media Server是否容易与你决定使用的STUN/TURN服务器集成
许可证是否适合你?
谁在提供支持? 很多成功的、被良好维护的开源项目背后都有一个商业模式,尤其是中小型的项目,这意味着有一个团队以此为谋生手段。 具备可选的付费支持意味着:
github.com/jitsi/jitsi Jitsi是一个免费的开源音频/视频和聊天通信器,它支持SIP、XMPP/Jabber、AIM/ICQ、IRC和许多其他有用的特性。
Jitsi不仅是WebRTC媒体服务器,而且还有一个完整的平台。 Jitsi系列产品包括Jitsi Videobridge(媒体中继,SFU),Jitsi Meet(会议网络客户端),Jicofo(Jitsi Conference Focus),Jigasi(Jitsi Gateway to SIP)和Jitsi SIP Phone。借助Jitsi我们能在几个小时之内迅速搭建一个完整可用的通信平台。 它还使用Jingle(XMPP)和功能齐全的Web界面实现自己的信令控制。 然而,令人遗憾的是,它对于媒体录制没有提供稳定易用的解决方案。
github.com/Kurento/kur… Kurento是WebRTC媒体服务器和一组客户端API,可简化针对WWW和智能手机平台的高级视频应用程序的开发。Kurento Media Server的功能包括组通信,音视频流的转码,记录,混合,广播和路由。
作为一项与众不同的功能,Kurento Media Server还提供了高级媒体处理功能,包括计算机视觉,视频索引,增强现实和语音分析。Kurento模块化体系结构简化了第三方媒体处理算法(即语音识别,情感分析,面部识别等)的集成,可以由应用程序开发人员透明地用作Kurento的其余内置功能。
Kurento Media Server通过称为Kurento API的RPC API公开其所有功能。可以通过任何与JSON兼容的客户端直接查询该API,但是推荐的使用方法是通过Kurento客户端库。目前为 Java , Browser Javascript 和 Node.js 提供了这些工具。
如果您喜欢其他编程语言,则可以遵循基于 WebSocket 和 JSON-RPC 的Kurento协议的规范来编写自定义客户端库。
Kurento被设计为可插入框架,Kurento中的每个插件都称为一个模块,可以使用新的自定义模块扩展Kurento Media Server。更多信息,请阅读Kurento模块部分。
Kurento模块分为三类:
主要模块与Kurento Media Server开箱即用合并:
内置模块Kurento团队开发的额外模块,用于增强Kurento Media Server的基本功能。到目前为止,有四个内置模块,分别是:
定制模块Kurento Media Server的扩展,提供了新的媒体功能。
github.com/lynckia/lic… Licode基于WebRTC技术。它与Google Chrome的最新稳定版本100%兼容。您的用户将无需安装任何内容即可通过其Web浏览器进行交谈。无需关心复杂的实时基础架构。它提供了基于HTML5的视频会议功能的快速开发,使它100%可扩展。Licode允许您在网络上包括电视会议室。但是您也可以实现流媒体,录制和您梦dream以求的任何其他实时多媒体功能!
主要模块及实现语言:
Erizo:这是WebRTC多点控制单元(MCU)。它是用C ++编写的,并且与WebRTC标准及其协议100%兼容。
ErizoAPI:Erizo的Node.js插件包装器。它可以从Node.js应用程序配置和管理Erizo的各个方面!
Erizo控制器:这是服务的核心。它向用户提供会议室以进行多方会议。它还提供了足够的安全性机制和附加功能:数据,用户列表,事件等。
Nuve:该视频会议管理API提供会议室管理,用户对第三方应用程序的访问控制和服务注册。它还为服务提供了云可扩展性。
github.com/meetecho/ja…
Janus是由Meetecho开发的WebRTC服务器,被认为是通用服务器。因此,除了实现与浏览器建立WebRTC媒体通信,与之交换JSON消息以及在浏览器与服务器端应用程序逻辑之间中继RTP / RTCP和消息的手段之外,它本身不提供任何功能。服务器端插件提供了任何特定的功能/应用程序,然后浏览器可以通过Janus与之联系,以利用它们提供的功能。此类插件的示例可以是诸如回声测试,会议桥,媒体记录器,SIP网关等应用程序的实现。
这样做的原因很简单:我们想要的东西将具有 small footprint
(因此是C实现),并且只能配备以前的东西 really needed
(因此可插入模块)。就是说,这使我们能够在云上部署成熟的WebRTC网关,或者使用小型的nettop / box来处理特定的用例。
其最显着的特征之一是其插件架构,可以增强服务的核心功能。有一些有趣的Janus用例,例如SIP Gateway,屏幕共享等。
github.com/versatica/m… 由于其多功能性,性能和可伸缩性,mediasoup成为构建多方视频会议和实时流应用程序的理想选择。它具有联播,SVC,传输BWE和其他更多先进功能。
除了创建另一个自带服务器之外,mediasoup是一个Node.js模块,可以将其集成到更大的应用程序中。mediasoup提供了一个低级API,该API支持您的应用程序使用不同的用例。
mediasoup带有mediasoup-client(JavaScript库)和libmediasoupclient(C ++库),用于构建使用统一API在任何浏览器或设备中运行的应用程序。或者只使用知名软件,例如FFmpeg或GStreamer。
设计目标mediasoup及其客户端库旨在实现以下目标:
架构
特征
它与其他媒体服务器的不同之处在于它被设计成一个用于Node的开发库,这允许它可以被容易的集成到更大的应用程序中。