1 背景
直播延迟是指从推流端到播放端的端到端延迟,目前业界的直播延迟普遍在3秒以上,这主要有两方面原因:
- 提供直播加速的各大云厂商为实现“秒开”功能,普遍在服务端缓存了一个GOP(两个I帧之间的数据),一个GOP大小普遍在3秒以上,播放器拿到GOP以后如果没有倍速播放等追赶功能,会保持3秒以上的播放延迟;
- 传统直播主要使用RTMP或者HTTP协议,都是基于TCP的协议,一旦出现弱网拥塞,将转变为延迟。
2 目标
本方案的目的是在支持传统直播“秒开”功能的前提下,通过在拉流端引入WebRTC技术,将播放延迟降低到200ms以内。通过播放器客户端内部的“追赶”机制来降低延迟,通过服务端的“丢帧”策略来降低客户端的追赶时间来实现用户对倍速播放的无感知,通过优化拥塞控制算法来提升弱网下的QOS以达到甚至超过传统RTMP直播的体验。
3 技术方案
3.1 RTMP到WebRTC的转封装
为了实现无侵入地对接当前的直播CDN系统,最大程度地复用当前直播系统上的转码、鉴权、鉴黄等业务,需要在直播CDN系统的中心节点或者边缘节点部署转封装服务,该服务负责从当前节点拉取RTMP流,并通过FFmpeg将RTMP协议转换成RTP协议,通过RTC分发系统发送给RTC媒体服务,以对接最终用户。也就是说推流端为RTMP协议,经过转封装、分发等服务后,最终用户通过WebRTC协议拉流播放。
如图3.1.1,转封装服务作为直播CDN系统到RTC系统的网关,负责RTMP协议到RTP协议的转换。
图3.1.1
3.2 客户端倍速播放追赶
客户端使用WebRTC协议拉取直播流,服务端接收到拉流请求后会立刻发送缓存的1个GOP数据,这些数据在客户端的接收时间间隔比在以正常码率传输数据时的接收时间间隔要小,基于这个特性可以通过WebRTC的音频NetEQ模块和视频JitterBuffer模块的配合进行延迟追赶,以快速消费客户端接收缓冲中的数据。
对音频来说,NetEQ会通过音频接收时间间隔以直方图算法和峰值检测算法估算音频目标延迟,在音视频同步后的音频当前延迟比音频目标延迟大的情况下,通过一定的压缩算法压缩解码后的音频同步缓冲中的波形,达到加速播放的效果。
对视频来说,JitterBuffer计算出的视频帧的视频渲染时间的间隔比正常速率要小,这段时间的渲染帧率要提高,直到接收帧率和推流帧率持平后视频渲染时间间隔会趋于正常。
如图3.2.1、图3.2.2、图3.2.3,首GOP瞬间发送,数据到达间隔小,音频NetEQ、视频JitterBuffer模块分别根据音、视频到达间隔对音、视频数据做延迟追赶并进行同步。
图3.2.1 首GOP数据间隔
图3.2.2 音频延迟追赶
图3.2.3 视频延迟追赶
3.3 服务端首GOP内丢帧和时间戳重写
如上述,客户端追赶算法是实现低延迟的根本算法,但是如果推流端设置的GOP过大,或者用户侧下载速度不足,会导致追赶过程持续较长时间,而追赶过程中可能会出现快进、跳帧、卡顿等较差的用户体验,为了降低用户对这个过程的感知,需要通过在首GOP内丢帧的方式减少第一次发送给客户端的数据量。
基于I帧、P帧之间的参考关系,首GOP内丢帧的基本原则是不能从GOP前面开始丢帧,不能从中间跳跃丢帧,只能丢GOP末尾的连续帧。同时还必须保证丢帧以后发送的视频帧时间戳的连续,具体做法为:设置一个时间窗口TW(TW<GOP),该时间窗口为首GOP内需要发送的视频帧时间总长度,将GOP末尾TW时间长度内的视频帧的时间戳按顺序设置为GOP头部TW时间长度内的视频帧的时间戳,在发完首GOP内TW时间长度的视频帧后,立刻开始发送下一个GOP,以保证发送视频帧时间戳的连续。而在首GOP还未完整的情况下,则需要通过收帧来驱动时间戳的设置。
如图3.3.1,服务端只发送首GOP开头TW时间窗口内的视频帧,并将GOP末尾TW时间窗口内的视频帧的时间戳设置到GOP开头TW时间窗口内的视频帧,保证发送视频帧时间戳的连续。
图3.3.1 首GOP丢帧和时间戳重写
3.4 WebRTC NetEQ对AAC的兼容
如上述,客户端的NetEQ模块需要解码音频数据并压缩波形以实现对音频的快进播放,传统直播的音频编码一般为AAC,而WebRTC系统的音频编码一般为OPUS,不支持AAC,并且NetEQ支持的音频采样率必须为8K的倍数,不支持AAC的44.1K采样率。针对这些兼容性问题有两个解决方案,一是服务端将AAC转码成OPUS,并重采样成48K,但是会增大服务端的压力;二是本方案采取的办法,修改客户端NetEQ模块以支持AAC的解码并重采样到8K的倍数,优点为服务端只需要转发不影响性能,但是提高了客户端复杂度。
如图3.4.1,RTP包进入NetEQ之前需要经过44.1K采样率到48K采样率的时间戳映射,然后经过AAC解码、重采样,得到48K的PCM数据由NetEQ进行处理。
图3.4.1 NetEQ支持AAC
3.5 优化拥塞控制算法
WebRTC协议使用基于UDP的RTP协议传输媒体数据,在弱网下需要对拥塞控制算法做一定的优化以达到甚至超过RTMP的指标。这里主要分成两部分,一个是NACK、FEC等冗余数据的发送,在低延迟丢包场景下基于评估的RTT和丢包率按照一定比例增大NACK的发送量,在高延迟丢包场景下按照一定比例提高FEC的发送量;二是在带宽受限等拥塞场景下,对码率进行波形的整形,对以GOP为周期的I帧位置的码率峰值进行削峰,平滑发送码率,以达到拥塞避免的目标。
如图3.5.1,通过NACK、FEC发送冗余数据对抗丢包,通过Pacer Sender平滑发送对抗拥塞。
图3.5.1 拥塞控制
4 架构
如下图4所示,转封装服务采用SRS,提供回源拉流、转封装、GOP缓存等功能,RTC媒体服务采用基于Janus的SFU,实现WebRTC接入,提供NACK、FEC、Pacer Sender等拥塞控制能力,低延迟直播客户端的功能封装在libctrts.so动态库中,以播放器插件的形式接入播放器,可以达到业务的无侵入对接。
图4
5 技术要点
- 客户端通过WebRTC的音频NetEQ、视频JitterBuffer对直播流进行倍速播放以实现播放延迟追赶;
- 服务端通过首GOP丢帧、重写时间戳以压缩客户端追赶过程;
- 客户端WebRTC NetEQ对传统直播AAC编码以及1K采样率的兼容;
- 在拥塞控制优化中使用NACK、FEC等算法,在参数调整、阈值设置,以及平滑码率发送中采用一系列自动控制算法;
- 实现服务端回源拉流、客户端通过播放器插件无侵入对接现有直播系统。
6 优势
通过使用本方案,在传统直播业务系统的基础上叠加了稳定可靠的超低延迟直播的能力:
- 超低播放延迟
可以达到200ms的播放延迟,极限环境可以达到120ms,基本做到实时。
- 用户无感知
通过首GOP丢帧压缩了快进追赶的时间,基本做到了用户无感知。
- 无侵入接入
服务端通过拉流转封装服务接入现有直播系统,客户端通过播放器插件化的SDK接入,可以做到无侵入的业务对接。
- 不降低QOS性能
通过优化的拥塞控制算法,QOS性能可以达到甚至超过传统RTMP直播的性能指标。