最近在研究直播系统的架构,在学习的过程中发现直播系统的结构很复杂,一方面是音视频传输过程中的协议不兼容,例如RTSP在现代播放器的不兼容,需要转码才能进行播放。另一方面则是附属功能的复杂,例如礼物,公屏互动等等。
还有一方面则是多个拉流会导致拥塞情况,CDN的分发需要考虑高并发。所以准备一边做这个项目,一边从架构角度梳理一下直播系统的搭建过程中应该考虑的问题。

协议解析

RTSP协议栈

RTSP协议栈通常与live555 共同出现,在这个协议栈中包括RTP传输,RTCP质量评估,以及RTSP交互。已经有很多文章提到了,这里不再赘述

RTMP

  • 连接:类似握手过程(三次)。
  1. C0+C1: 客户端向服务器发送 C0(1字节,表明 RTMP 版本)和 C1(1536字节,包含时间戳等随机数据)两个数据块。

  2. S0+S1+S2: 服务器收到 C0/C1 后,立刻回复 S0(版本号)、S1(服务器版的时间戳和随机数据)和 S2(将客户端发来的 C1 数据原样返回)三个数据块。

  3. C2: 客户端收到 S1 后,回复一个 C2 块(将服务器发来的 S1 数据原样返回)。

  • 数据传输:TCP
  1. connect: 客户端向服务器发起connect命令,请求连接到服务器上的一个指定应用(Application)。例如rtmp://server.com/live这里的live就是应用名。这个消息里会包含一些参数,如 Flash 版本、编码信息等。

  2. connect response: 服务器验证通过后,会返回一个成功响应,告知客户端可以继续。

  3. createStream: 客户端发送createStream命令,请求服务器创建一个逻辑上的“流通道”,服务器会返回一个唯一的 Stream ID。后续的音视频数据都会在这个 ID 上传输。

  4. publish: 客户端发送publish命令,并携带一个“流名称”(也叫 “stream key” 或 “secret”),告知服务器:“我准备好要往这个流通道上推送数据了,流的名字是 room123。

  5. 开始推流: 服务器验证publish命令成功后,客户端就可以正式开始发送音视频数据了。

在传输过程中,RTMP使用了基于chunk的流式结构,为了在一条 TCP 连接上同时传输音频、视频和控制信令而不互相阻塞,RTMP 会把大的数据(如一整个视频帧)拆分成小的“块”(Chunk)。每个 Chunk 都有一个自己的小头部,包含了这个块属于哪个流 (Stream ID)、消息类型、长度等信息。默认的 Chunk 大小是 128 字节。每个完整的音视频帧或元数据,在被拆分成 Chunk 之前,会被打包成一个带有“标签 (Tag)”的数据单元。这个 Tag 的结构(包括 Tag 类型是音频/视频/脚本数据、时间戳等)和 FLV 文件中的 Tag 结构是一模一样的。

RTMP是过去Flash时代常用的标准,但是由于与现在的浏览器不兼容,所以流的制作方面使用会变少。但是在内容推送方面还是用的最广。延迟相较于HLS低,但是没有WebRTC低。目前点播平台的主流方案就是RTMP推流,HLS负责分发。在这个过程中核心是媒体服务器,诸如SRS\Nginx-RTMP\Wpwza。它的职责就是接收来自推流端的唯一一路 RTMP 流,然后将其实时转封装 (transmux) 成包含多个码率的 HLS 切片和清单文件,供海量观众通过 CDN 拉取播放。

另外分发端方案还有Flv。由于flv和RTMP流的数据载体在结构上几乎是一致的,这种设计使得媒体服务器可以极其高效地在 RTMP 和 FLV 之间进行转换。由于没有 HLS 那样的切片和缓冲机制,HTTP-FLV 的延迟可以稳定在 2-5 秒,非常接近 RTMP。 由于它运行在标准的 HTTP 协议之上,可以轻松穿透防火墙,并且不需要像 RTMP 那样使用特殊的 1935 端口。借助flv.js这个强大的库,可以在所有支持 Media Source Extensions (MSE) 的现代浏览器中直接播放 HTTP-FLV 直播,无需 Flash 插件。而HLS兼容CDN,CDN对于HTTP文件下载的支持很完善,因此HLS的兼容性比HTTP-FLV 要好很多;同样HTTP-FLV的延迟比HLS要低很多,基本上可以做到3的5秒左右延迟,而HLS的延迟一般是8到10秒以上。

HLS & MPEG-DASH

  • 信令:HTTP
  • 数据传输:基于TCP的HTTP
  • 媒体容器:MPEG-2 TS(用于 HLS)、ISO BMFF (MP4)(用于 DASH 和更新的 HLS)。

有很多优点,但是流的延迟很大,在网上看到的资料大约都是10s左右。这个协议是将流切片,通过HTTP服务器提供发送服务,分片下载。也是比较适合点播,由于依靠标准的web服务器,和CDN能够轻松的扩展几百万的观众,TCP又可以确保可靠交付。还具备自适应比特率,防火墙遍历。

webrtc

基于Webrtc的开发一方面延迟极低,另一方面网络拥塞等控制也会很好。它并不是一个单一的协议,而包括了一系列的API和协议,是一个综合性的框架。

SRT

  • 数据传输:UDP,但是在数据包级别实现了自己的ARQ机制(自动重复请求),保证了可靠性

目前准备替代RTMP的协议,基本上只要在网上搜索RTMP实现直播,那么一定会有人说RTMP的不兼容和服务器端转协议问题。而与之相对应的就是SRT的流行。

SRT使用的封装是TS封装,因此对于新的Codec天然就支持。而SRT基于UDP协议,因此对于延迟和弱网传输,也比RTMP要好不少。 一般RTMP延迟在1到3秒以上,而SRT的延迟在300到500毫秒,而且在弱网下表现也很稳定。在广播电视l领域,由于长距离跨国跨地区 传输,或者户外广播时,网络不稳定,因此SRT比RTMP的优势会更明显。

SRT是SRS的核心协议,SRS早在2020年即支持了SRT协议,并且在2022年实现了SRT协程化,从而大幅提高了SRT和其他核心协议的一致性。 比如回调和API的支持,SRT和RTMP保持了非常高的一致性。

架构分析

推流端

推流端可以使用OBS,推送到对应的端口。采用的协议可以是RTSP、RTMP、SRT。

服务器

用来接收OBS的推流,可以使用Nginx来做架构。如果拉流端不兼容协议。服务器还需要对流本身进行转换。

拉流端

如果选用浏览器,内嵌了播放器,需要向媒体服务器请求流并进行播放。采用的协议有HLS,DASH,HTTP-FLV,WebRTC

实现路线

SRS (Simple Realtime Server): 支持RTMP, HLS, HTTP-FLV, WebRTC, SRT等多种协议。

Nginx + nginx-rtmp-module: 可以将接收到的RTMP流轻松转换为HLS或作为HTTP-FLV分发。但模块已多年未更新,对DASH、WebRTC等新协议支持不足。


本站由 Edison.Chen 创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

undefined