接上篇 直播 (上) -- 底层逻辑浅析
随着近些年技术及基础设施的迅猛发展,网络直播的核心技术体系已经趋于成熟,通过简单购买第三方厂商的服务,可以快速搭建起一个直播系统。
透过厂商们的兴旺,可以发现他们主要在解决三个问题:
简单推演整个过程,可以总结为几大流程:
1~3 和 6~8 两组过程互逆, [流程 4] 推的内容和 [流程 5] 拉到的内容一样,通过网络传递数据。各个流程依次进行,流程间相互独立,各自分离,依赖不同的技术。
整个过程涉及了庞大的工业体系,每一个环节深入下去都是浩瀚的协议、算法,几十年沉淀的智慧结晶。
视频播放的本质,是一张张图片的连续滚动,1 张图片也被称做 1 帧,当每秒变化的图像数达到 24 帧/秒时,人眼就会认为是连续的画面。
视频的拍摄也就是每秒拍照 24 次以上,将照片依次播放即可看到“画面”被原样记录下来了。其中每秒拍摄的频率越高,播放时画面越流畅逼真。这是帧率 [1] 的含义。
现代数码相机 [2],通过组合光敏二极管 [3] 构成感光元件,元件包含很多像素点,当光照打在感光元件上时,每个像素点会因为光照强度不同而产生不同强度的电流,借此就将光信号转换为电信号,同时在感光元件前置红绿蓝滤光片可以记录颜色 [4],一缕光照可记录为一组包含光照强度和颜色的数字信号,即为一张照片。
其中每张图片的清晰度可以用像素密度 (PPI)[5] 来衡量,PPI 表示每英寸图像内有多少个像素点,像素点越多,图片越精细,对细节的还原度越高。每个像素点会被填充一种颜色,颜色值可由 RGB 二进制数据来表达。总之越精细,数据体越大。
帧率和 PPI 决定了视频的品质,品质高也意味着占用空间大。
音频作为一种模拟量,需要先进行数字化后才能进行保存和传输。声音是振动产生的声波,通过介质进行传播,将话筒置于声音之下,话筒中的线圈或电容会随着声波振荡,进而产生电信号。以固定频率采集电信号的值,即可记录声波的形态,进而将声波数字化,实现对模拟量进行采样 [6],输出为一串数字序列。
采样的频率越高,对声音的还原度也越高。将数字信号输入功放,通过数字量的变化控制喇叭鼓膜的震动幅度,即可还原出声波。
直播内容的采集,也就是对视频和音频的采集。由摄像头和话筒分别进行,可分别保存为二进制数据,这得益于已经成熟多年的技术。
简而言之,就是将人类能理解的自然信号 (音频、视频) 进行数字化,目的是进行储存和传输。
一般基于美颜、水印、连麦、滤镜、降噪、其他干预等等需求,会对采集到的原始数据进行加工处理,最常见的有美颜和连麦两个场景。
直播的兴起很大程度上是因为有了美颜,把一些本来不能看的脸瞬间变成了颜值担当,一方面丰富了观众端的观看体验,也极大抚慰了主播对美的心里需求。
美颜主要是通过 [磨皮 + 美白 ] 来达到整体的效果。磨皮的技术术语是 [去噪],也即对图像中的噪点进行去除或者模糊化处理,常见的去噪算法有均值模糊、高斯模糊和中值滤波等。由于面部画面的复杂性,脸上的斑可能呈现出类似眼睛的形状,对整张图像 [去噪] 时可能会误伤眼睛,因此这个环节中需要使用到人脸和皮肤识别,这一般由深度学习和计算机视觉来搞定。
连麦是多个主播或用户之间的互动,一般直播画面里面只有一个主播。在商业上的考量,有时会创造两个主播 PK 的场景,此时观众端能在画面中同时看到超过一个主播或用户,而他们并没有在一起录制。
这其实是将多路直播的数据流在一处汇集,分别进行编解码后,按照标准进行实时合成,一般是各占半屏。然后将合并后的数据推送到数据中转站,用户看到的画面是经过合并处理后的内容。
相较于常规直播,这多了一次加工和传输的步骤,在音视频同步、实时合成数据、低延迟传输上有不小的挑战,一般都是有专业的第三方公司提供服务。
将采集处理后的二进制数据通过网络传输给观众,终端用硬件设备将视频和音频分别播放出来,这就是直播的过程。
然而直接录制的音视频数据体积很大,一小段高清视频可以有几百 M,网络传输负担非常大,这直接会影响播放体验,所以在进行网络传输前,需要将数据极力压缩,在保证质量的前提下让网络传输的数据最小。由此诞生了众多精妙光辉的编码算法,目前 H.264/H.265[7] 就是广泛使用的编解码标准之一。
相机拍摄视频中的每一帧都是一幅高清的图片,在播放过程中,相邻的帧之前有大部分画面内容是相似的,这就有很多数据的冗余。编码压缩的本质就是将冗余的数据移除,只保留关键的部分,有两个方向:
H.264 非常复杂,其基本点是认为,一段时间内相邻的图像之间内容是相似渐变的,所以没有必要对每帧数据都进行完整记录,可以有一个参考点 (完整的一张图片),后面的帧数据只记录变化的偏移量,基于参考点,叠加上偏移量和预测值,即可还原出真实的画面。
对一段时间内变化不大的画面可以组成一个序列,序列头部有一个基准图片,后面的帧数据基于基准进行还原。当画面数据差异大到一定程度时,可以新起另一段序列,其中又包含一个新的基准图片和偏移数据,依次重复。
每个序列可以理解为一个画面组 (GOP),也就是一段内容变化不大的画面。一个 GOP 中即是一组帧数据,其帧数量可以自由定义。其中帧的分类有三种:
一组 GOP 的帧序列可以类似:IBBPBBPBBPBB,P 帧只依赖左边的 I 帧或 P 帧,B 帧则左右都依赖,还原中间状态的帧数据,这将视频数据压缩率极大提高。
播放端会收到一组组的 GOP 数据,对于每组数据,都将 I 帧加载到缓冲之中,后面的帧数据都基于此进行还原,当下一组 GOP 到来时,将缓冲区清空,换成下一组的 I 帧,依次递进。
基于 IDR 帧的关键地位,所以也被称为关键帧。 秒开的本质就是当用户端第一次拉流时,CDN 保证给的第一帧数据必须是 IDR 帧,这样播放端就可以立即将其加载到缓冲,并顺序还原后面的帧数据,并播放出来。
因为用户打开页面拉流的时机是完全随机的,大概率第一次拉流时是非 IDR 帧,拉到 IDR 帧的概率仅为:1/GOP 帧的数量。当拉到非 IDR 帧时,其后面的帧数据由于没有基准点,就会是一堆无用的数据,无法进行还原,此时页面就会黑屏,直到下一组 GOP 到来。
秒开地址为了解决这个黑屏问题,会在本地缓冲最近一组 GOP 中的 IDR 帧和 P 帧,当某个用户首次打开秒开地址时,会将缓冲的帧数据合并到当前的数据中,这样保证了第一次打开拉到的肯定是 IDR 帧,这样便解决黑屏问题,实现了“秒开”。(或者二次解码重新设置很小的 GOP,这样下一个 IDR 帧会很快到来)
音视频数据通过不同的硬件进行采集,并经过不同编码处理后,需要将两者打包到一起。合并有多个好处:
合并后的数据被称为多媒体容器,一个多媒体的内容集合,天然就包含了音视频数据。多媒体容器有很多不同的实现,反正就是将音视频数据打包在一起,各有千秋。而对这些容器的命名就是我们常常听说但又不甚了解的 .avi/.mp4/.flv/.rmvb 等等。
直播是典型的一对多的场景。一般一个主播创造数据,却有海量的用户在观看,而且分散在大江南北。这在网络传输上就需要一个中转站 [13],主播将数据推流到中转站,由中转站对数据进行转储分发,为海量用户提供服务。不像参与者有限的视频会议,可以简单多端直连。
主播端推流一般使用 RTMP[9] 协议,由于其的开放性和 CDN 厂商的广泛支持,普及度非常高。其基于 TCP 协议,有着复杂的协议配置,可以将数据分成一个个小块实时传输到 CDN 节点,CDN 服务器一般会对数据进行处理:
为多种终端提供差异化拉流服务,在 H5 或苹果终端上可以直接使用 HLS[10] 协议直接播放,它通过隔段时间下载一份视频索引文件,然后依次下载文件播放,这也使得延时较高,一般可以达到 10s 以上。
由于 Flash Player 及其广泛的存在和 HTTP 协议 (80 或 443 端口) 不容易被防火墙拦截的特点,HTTP-FLV[11] 目前被广泛使用,它通过 HTTP 长连接实时传输 FlV 文件,也使得延时可降低到 1~3 秒,播放端通过 HTTP 实时拉取到 FLV 文件后,通过 Flash Player 即可直接播放,接受度很高。
由于用户的海量性和分散性,让大部分用户低延迟、流畅地看到直播画面是相当大的挑战,需要根据网络拓扑进行优化,这是众多 CDN 厂商的核心价值。
要想直播数据更快、更稳定地传送到天南地北的用户端,无非两点:
理想的场景是让用户连接上离自己最近、网络情况最好的 CDN 节点,然后 CDN 节点内部根据网络状况选择最佳路径或专线互联,避开各种拥堵的路线。
同时,CDN 节点之间传输数据时,可以将 TCP 传输窗口调到最大,用相对激进的方式传输数据,发挥以太网的传输能力。避免普通公网由于网络拥堵触发拥塞避免策略 [12],TCP 窗口上不去,传输缓慢的问题。[13]
传统的 DNS 策略,对一个域名如果本地有缓存则直接使用对应的 IP,如果没有缓存,则向 DNS 服务器获取 IP,然后向 IP 发起请求。在 CDN 策略下,这个过程稍有不同。
对于某个公司的直播域名,如 www.live.com,在权威 DNS 服务器上,它不会直接指向某个 IP,而是会 CNAME 到一个新的域名,类似 www.cdn.live.com,这是 CND 服务商自己的域名,整个过程如下:
对于直播的海量流式数据,当新的数据产生时,CDN 也会选择主动将数据推送到边缘节点,用户可以直接从离自己最近的边缘节点获取数据,避免全流程回源,得到低延迟稳定的服务。这比静态资源访问策略稍微复杂些,不像 js/css 这种资源可以简单逐层缓存,直播的每一份数据时效性都非常低,过时即焚。
CDN 厂商散部在大江南北乃至全球的边缘节点,和其内部节点网络间优质的连通策略和路径,就是最核心的竞争力。因为对 CDN 网络的依赖,很多基于 UDP 的自建协议来提高网络传输效率的方案很难实施,因为标准不统一,要让各家 CDN 厂商支持,难度极大。
接下来就是直播的最后一步:播放,现代播放器 [14] 也是个超级复杂的东西,它主要做三件事情:
其核心流程可以归纳为:
可以看出上面的过程就是采集、编码、封装的逆过程。将数字化的东西转换为视觉、听觉信号,供人类观看。
行文至此,可以看到直播的这些技术,本质上是在打破自然界光线、声音传播的绝对性约束(音速、光线散射),将一个时空中的人类信号,变换到另一个时空进行重放,并在此基础上叠加上商业的元素,对原本简单朴素的东西 (主播侧的内容) 进行无限价值放大。
这只有人类能够做到。
由于整个体系庞大复杂,个人水平有限,即糙述至此,建议到参考资料中深入了解。