一、延时的产生
直播延时,对于任何一个接触过直播的人都不会陌生。延时产生的环境是复杂的,整个直播流程从内容采集→处理→编码→封包→推流→传输→转码→分发→解码→播放,每个阶段都会产生延时。我们可以用一张图来概括延时的产生:
目前业界常用的是采用读秒的方式来大体统计端到端延时:
统一的计时器
- 同步的源时间和播放时间快照
如下图所示,可以捕获本地时间推流,然后计算播放时间和推流时间的偏差就能大体统计出端到端的延时。
但这种方法存在很大的偶然性,不适合统计大型平台整体的延时情况,目前很多大型平台也都缺乏有效的统计手段。
二、FLV统计延时方案
HTTP-FLV 一直是直播的首选方案,FLV 主流上封装了 H.264/AVC 编码的码流,H264 提供了一种在码流里加入自定义数据的能力(自定义SEI)。
前端播放 FLV 的流程如下:
在整个播放流程中,音视频数据流对我们完全透明,前端有解析音视频码流原始数据的能力。基于这两点,我们设计了一套统计大盘延时的方案,如下图所示:
首先推流侧和客户端需要保证时钟同步,前端我们使用云函数开发了一个对时服务。推流侧将采集编码的数据在发送之前通过自定义 SEI 的方式将当前时间戳写入 H264 码流。
前端对 FLV 解封装并探测 H264 码流是否含有相关的 SEI 数据,如果有就计算延时偏差。
另外需要注意一点,这里计算的偏差并不是最终的延时,因为浏览器内部也会有一段时间的播放缓存,两者相加就是最终的端对端延时。
经过实践检验,该方案简单可行,并且可以完整统计整个播放链路延时。
三、WebRTC统计延时方案
其实,腾讯企鹅电竞很早就开始研究如何使用 WebRTC 降低直播延时,提升用户的观看体验。WebRTC 较 HTTP-FLV 给我们带来的最大收益就是更低的延时,但是真实的用户延时到底降低了多少我们其实无法直接获知,那么 WebRTC 有统计延时的办法吗?
App 端可以自己编译 WebRTC, 如果播 H264 码流的话可以复用 SEI 统计延迟的方案,通过修改源码获取原始码流数据。
Web 端统计 WebRTC 延时的难点在于实时音视频播放流程复杂,整体被浏览器接管,没有为开发者暴露底层数据的接口,无法获取客户端播放的数据流。
为了统计现网大盘的延时数据,我们发明了一套 Web 端大体统计 WebRTC 延时的方案,流程如下图所示:
通过将 WebRTC 的播放流程分解,我们将 WebRTC 直播延时分为 5 大阶段:
第一阶段是上行延时,是从推流到达 WebRTC Server 的延时,这里使用 SEI 统计的方案。
第二阶段是 WebRTC Server 到浏览器的延时,这里通过测量 RTT 可以得到。
第三阶段是 WebRTC 内部抖动缓冲区的延时,计算方法为:jitterBufferDelay / jitterBufferEmittedCount 。
第四阶段是解码缓冲区的延时,计算方法为:(framesReceived - framesDecoded - framesDropped) / framesPerSecond 。
第五阶段是渲染缓冲区延时,使用 Media Stream 时 Video 的 Buffer 长度为 0,可以忽略解码帧到绘制的延时。
五大阶段相加就是整个链路的延时。详细数据依赖 RTCPeerConnection.getStats API 。
四、结语
不管是主播还是用户,对直播低延时的要求越来越高,统计现网大盘的延时数据变得越来越重要。延时统计方案的实施使我们有了衡量大盘数据的标准,为后续的延时优化及衡量收益奠定了基础。
本文分别介绍了在使用 FLV 和 WebRTC 直播技术下的现网大盘延时统计方案,希望能给大家带来一些启发,也欢迎大家在留言区与我一同交流探讨更多直播延时统计方面的话题~