流信息卡顿监控
流直播卡顿监控
一、背景
流直播业务中多场大型直播(蔡徐坤、TFBOYS)出现用户投诉直播画面卡顿问题,但客户端在直播时无法更快更直接定位问题,因此针对已知问题增加debug页面,输出关键信息,方便快速响应。
二、问题汇总
在当前业务中,直播视频数据流程是如下:
- ①直播现场麦克风、摄像头进行音视频数据采集,上传后台
- ②后台进行编码和封装成HLS(进行TS切片和M3U8更新)
- ③后台分发到各CDN
- ④客户端定时请求M3U8文件,并进行播放
因此结合音视频理论和多次直播实践,总结出以后可能会碰到的问题:
- 流信息异常(流程①、②出错)
- 后台(上游)编码缓慢(流程②耗时长)
- 数据请求失败(流程③后台、运维出错;流程④客户端请求逻辑出错)
- 播放器读取数据不及时(流程④客户端网络问题)
- 播放器音画不同步(流程④客户端性能问题)
三、问题监控
针对上述问题,在直播页面增加了debug页面,对关键信息输出:
- 当前音视频AVPacket的pts信息(监控问题1)
- 当前M3U8请求包、M3U8内容信息(监控问题2)
- 当前ts分片请求包信息(监控问题3)
- 播放器音视频读取AVPacket的时间戳、AVFrame解码前后、当前展示帧的对应时间戳;当前解码帧率;(监控问题4、5)
四、监控原理
(一)流信息异常
- 播放器根据码流中的音视频的pts来做渲染以及音画同步
- 若码流中的音视频时间戳出现错误,会影响到播放画面的渲染时机。
以上述为例,该流的视频pts时间戳在部分时间内出现了数据量较大的“倒退”。播放器会进行丢帧等待或强制渲染导致跳帧。
针对该问题,记录了流中音视频每一个AVPacket的pts时间戳
通过观察该时间戳是否在递增来判断流是否异常。
(二)、后台(上游)编码缓慢
- 后台在直播过程中会持续编码,在编码出新的TS分片后,会更新M3U8文件,返回最新的N个TS分片地址。
- 客户端会定期请求最新的M3U8文件,拿到最新的TS分片地址进行播放。
- 若后台编码或分发TS分片缓慢,会导致客户端无法请求到最新数据而进而loading等待(发生二次缓冲)
针对该问题,记录了每次后台返回M3U8文件的内容:
- EXT-X-MEDIA-SEQUENCE 是否在合理时间内正常递增
- EXTINF 以及 TS分片地址 是否在合理时间内正常更新
通过比对前后M3U8内容来监控后台编码进度。
(三)、数据请求失败
- 在直播过程中,后台需要一直编码生成TS分片。为了减少成本,后台会维持一个TS分片的缓存池,若TS分片时间太旧则会淘汰删除。
- 若后台最新的M3U8中带有已经删除的TS分片,或客户端因逻辑问题请求了旧的TS分片,则会有HTTP 404问题。
针对该问题,记录了客户端每次请求TS分片的信息:
- 请求时间点
- 响应头信息(code、header error)
通过对比TS分片的请求信息来定位后台TS存储(404)问题。
(四)、播放器读取数据不及时、音画不同步
- 客户端会对流信息数据进行解协议、解封装和解码,经过音画同步模块处理后渲染上屏。
- 若客户端网络情况恶劣,数据读取不及时,会导致发生二次缓冲。
- 若客户端CPU性能不足,解码需要耗时过长时,会导致音画不同步或丢帧跳帧。
针对以上问题,记录了客户端音视频当前解封装、解码、渲染的帧时间戳:
- 发生二次缓冲时,比较当前音频解封装数据和解码数据,可以定位播放器数据读取情况
- 比较当前音频展示帧pts和视频展示帧pts,可以得到音画不同步的程度
- 比较音视频解封装数据和解码数据时间戳可以量化出音视频解码性能
- 计算音视频单位时间内展示的帧数,来量化出音视频流的当前FPS
通过以上数据,实时监控到播放器当前请求、解码数据量以及音画不同步的程度,来帮助判断用户当前网络环境、CPU性能对卡顿的影响。
五、附录:
(一)DTS和PTS(IBP帧、GOP)
1、PTS和DTS
- DTS:Decoding Time Stamp,用于解码
- PTS:Presentation Time Stamp,用于输出
在没有B帧的情况下,DTS和PTS输出顺序是一样的,但是大多数的编码标准码(H.264的编码顺序和输入顺序是不一致)B帧会打乱了解码和显示的顺序。
FFmpeg中,会使用AVPacket结构来描述解码前(和编码后)的压缩数据,用AVFrame来描述解码后的原始数据。AVFrame就是视频的一帧图像,通过它的PTS来决定什么时候显示。AVPacket的DTS代表需要在什么时候解码。
2、GOP
- I帧:自身可以通过视频解压算法解压成一张单独的完整的图片。
- P帧:需要参考其前面的一个I帧或者B帧来生成一张完整的图片。
- B帧:则要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的图片。
- GOP:两个I帧之间形成的一组图片。其中编码参数gop_size代表的是两个I帧之间的帧数目。必须从I帧开始解码。
一个GOP中容量最大的帧是I帧,gop_size越大,质量越高。
PS:在提供视频质量的技术中,其中一个是多使用B帧,因为I帧的压缩率是7,P是20,B可以到50,使用B帧能大量的空间,节省出来的空间可以用来更多地保存I帧,这样子就能在相同码率下提供更好的画质。
3、结合
(二)直播M3U8文件
1、直播HLS实现
本质:以HLS点播方式实现了直播
- HLS协议在服务器端将直播数据流存储为TS分片文件,并会将最新的直播数据生成新的TS分片
- 客户端则只要不停地按顺序下载和播放请求返回的最新的TS文件,就能实现直播
2、直播M3U8区别
直播M3U8中
- 没有EXT-X-ENDLIST标签,因为实时流不会有结束。
- 返回最新的TS分片地址,会有TS分片个数限制
3、细节
(1)后台:
- 不断更新TS内容和EXT-X-MEDIA-SEQUENCE标签,以步长为1进行递增(类似滑动窗口)
- 在更新M3U8时每个TS信息和播放时长在更新前后保持一致
- 为了减少成本,仅存储最近一段时间内的TS分片,淘汰删除较老旧的
PS:业界新方案:不将TS切片文件存到磁盘,而是存在内存当中。(这种技术使得服务器的磁盘上面不再会有“数以吨计”的文件碎片,极大减少了磁盘的I/O次数,延长了服务器磁盘的使用寿命,极大提高了服务器运行的稳定性。也使得终端请求数据时直接从服务器的内存中获取,极大提高了对终端数据请求的反应速度,优化了视频观看体验。)
(2)客户端:
解析到M3U8中没有EXT-X-ENDLIST标签,会触发定时请求逻辑,并设置定时请求的间隔。
定期请求M3U8的间隔:首次以#EXT-X-TARGETDURATION作为间隔,后续以最后一个TS分片的播放时长作为间隔。(不同播放器请求策略也有所不同)
(3)M3U8示例:
时间:19:56:31,分片信息为12024_shuping-1535457300到12024_shuping-1535457304
1 | #EXTM3U |
时间:19:56:40,分片信息为12024_shuping-1535457302到12024_shuping-1535457306
1 | #EXTM3U |
相当于滑动了2个TS位置。