流媒体技术:直播网站是如何实现的?

如今,年轻人热衷于刷 B 站和抖音,空闲时还会去拉勾教育观看大厂面试、热门技术分享直播以及各类游戏直播。不知你是否思考过,我们日常看到的众多音视频内容是如何从采集端最终呈现在手机 App 上的呢?若公司要提供直播服务,你能否给出技术方案呢?为应对这些应用场景,本讲以“直播网站是如何实现的”为例,系统探讨直播、点播、视频网站等基于流媒体技术的应用。

一、流媒体的概念

在流媒体技术尚未发达的时期,数据多以单个文件形式存在。例如,十多年前人们想在互联网上观看一部电影,需将电影文件下载到本地。当时网速仅有十多 K 每秒,下载一部电影往往要耗费一整晚。

如今,我们将所有数据抽象为流,文件格式也发生了变化。那么如何将一个视频抽象成流呢?其实就是传输一部分即可播放一部分。在实际操作中,我们设计了一种类似目录的格式,将音视频数据进行切片。利用现有工具 FFmpeg 可轻松实现这一功能。在你的机器上安装 FFmpeg 后,使用以下指令处理一个 MP4 文件,便可生成许多切片和一个目录文件。

ffmpeg -i input.mp4 -c:v libx264 -c:a aac -strict -2 -f hls output.m3u8

上述指令将 input.mp4 切割成 HTTP Live Streaming 可播放的切片(大多数浏览器中的播放器都能播放)。最终会生成大量的切片文件(例如每个 256k)以及一个目录文件 output.m3u8。m3u8 文件如同目录,记录了每个视频切片文件(ts)对应的视频时间范围。用户播放视频时,会先下载 m3u8 文件。当用户调整视频播放滑块选择播放时间时,播放器便根据 m3u8 的内容下载对应的 ts 文件。

二、基于流媒体的架构

了解了上述基本原理后,我们来思考一个基础架构。视频录制完成后,可能是 MP4 等格式。首先,将视频上传至服务器进行编码,产生如上文提到的切片文件。切片文件存储于流媒体服务器中,当用户需要时,便从流媒体服务器中读取视频目录(即 m3u8 文件),然后在各个终端播放。进行编码时,可以根据不同的清晰度编码多个版本,以应对用户在不同网络环境下的情况。

三、直播技术

从这个角度出发思考,直播技术仍可复用上述架构。录制端不断上传视频内容,视频内容经编码后由流媒体服务器负责分发。若观看人数较多,可使用 CDN 回源至流媒体服务器。对于直播,m3u8 文件可看作一个动态文件,能够不断产生新的数据。因此,在直播技术中,可以考虑将获取 m3u8 文件设计成一个接口,由播放器不断请求新的 m3u8 文件。

四、其他音视频网站架构

对于其他音视频网站,架构也是类似的。将视频编码后(含切片),再利用 CDN 分发目录和切片文件,即可播放。

五、视频的编码和解码

由于通常视频文件较大,因此在传输前通常需要压缩,播放前还需解码。视频的压缩技术并非普通的文件压缩技术,而是针对视频特征进行特别处理的压缩技术。

可以将流畅的视频理解为连续播放的图片,这也是视频呈现的原理,主要依靠人类视觉的残留效应。视频的压缩算法亦是如此,本质上是对图片的压缩。因为视频的前一画面和后一画面衔接紧密,若将它们看作两张图片,这两张图片中往往只有部分内容发生了变化。此外,在连续的多张图片中,也会有重复出现的事物,如一座桥、一间教室都可能多次出现。因此,视频压缩可根据这些特性进行抽象。

对视频进行压缩时,视频文件格式与压缩算法息息相关,我们统称为视频的编码。视频需要编码,包括如何描述目录、如何描述切片、如何存储声音等,这些都是编码要考虑的。一个完整的解决方案,我们称为一套视频的编码。例如,H264 就是国际标准化组织在推广的一种编码格式。当然,所有特性的核心是在减少视频体积(网络传输)的基础上,尽可能提供更高的画质;另一方面就是要尽可能减少中间编码/解码的时间成本(机器资源)。

六、宏块的概念

这里顺带提及一个非常重要的概念——宏块。在包括 H264 在内的许多视频编码技术中,都有一个叫作宏块的概念。宏块是将画面分成大小不等的区域,如 8x8、16x16 等。

当播放两个连续的画面时,可以理解为两张图片。但如果基于图片分析,那么播放的就是很多个宏块。在这连续的两帧画面中,并非所有的宏块都发生了变化。特别是在观看一些教学 PPT 讲稿时,视频前后两帧的宏块基本没有变化。因此,往往相同画质、相同时长的教学视频体积会远小于电影视频的体积。

七、点到点视频技术

接下来讨论点到点视频技术。在视频会议、面对面聊天等场景下,我们需要点到点的视频技术。理论上,此时可以复用之前提到的架构。

一个客户端将本地录制的视频用二进制上传,在服务端编码后分发到另一个客户端。数据在另一个客户端解码并播放。

这样做的缺点是链路较长,因此在实际操作过程中,如果是一对一的视频聊天,可以考虑实现点到点的服务。但事情并非那么简单,因为不同的主机可能处于不同的私有网络。例如,Host1 在百度的办公室,Host2 是百度的某位合作伙伴。此时,整个设计中需要一个 NAT 路由器,这样客户的数据才能回传到拉勾内网的机器。而实际情况更为复杂,在 NAT 通信中,往往需要在内网的主机发起连接。此时 NAT 模块会识别发起的端口并记录。换句话说,如果某客户的机器是公网 IP,那么拉勾内部的主机可以找到这个客户,找到之后,双方建立连接。但是,如果某位客户想主动发起向拉勾内网某台机器的连接,这实际上是做不到的。

像下图这种两个主机都在内网中,都需要 NAT 的场景,其实是无法通信的:

在这种情况下,内网发起连接,对方的 NAT 路由会因为自己内网的机器没有发起过请求而拒绝;反之,如果客户发起请求,会被内网的 NAT 拒绝。这种情况类似于多线程中的“死锁”问题,无法解决。此时,就需要一台第三方服务器作为 NAT 模块的辅助功能,帮助双方的 NAT 模块设置本地数据,让双方的 NAT 模块都认为对方已经和自己发起过通信。这个解决方案也叫作 NAT 穿透(NAT 穿墙)。

例如,在著名的 WebRTC 协议中,可以提供网页版的一对一聊天,对于多数家庭到家庭的网络来说,是可以正常工作的。如果需要连接两个内网的机器,此时就需要自己架设第三方服务,或者使用某个收费的第三方服务。

对于在线会议的场景,如果人数较少的情况下,仍然可以使用点到点技术,只不过传输量会随着人数的上升而呈爆发式增长。所以在人数较多的时候,就需要更多的优化策略。其中一种方案是放弃点到点技术,而直接采用类似直播架构的中心化服务。另一种策略是利用边缘计算,让距离相近的参会者利用共同的离自己最近的服务器交换数据。

流媒体,即将多媒体数据抽象成为流进行传输。视频本质上是一张张图片在播放,因此非常适合流传输。要知道,流是随着时间产生的数据。通常在一个网络中,等价成本下吞吐量、丢包率和延迟三者不能兼得。也就是说,像直播这种吞吐量非常大的视频应用,可能就要牺牲延迟。比如之前 B 站直播没有优化前,用户看到的直播画面会比真实时间慢近半分钟。

另一方面,像在线会议这类对延迟要求较高的场景,就可能需要降低视频质量,或者部署边缘服务。如果是内网视频会议,或者跨地区的公司视频会议,很容易找到边缘节点帮助交换数据和计算;如果是来自天南地北的用户,那么就需要投入更多成本。对于社交网站而言,需要维护几个人同时语音、视频聊天,因为人数较少,就可以使用点对点技术(但要解决 NAT 穿墙的问题)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱娃哈哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值