直播推流时间戳跳变问题修复的一条偏方

2019-12-11 00:50:45 浏览数 (1)

简介

直播推流时,对于视频帧和音频帧,都记录着一个时间戳,用于表示该帧播放的相对时间,可以用ffprobe命令查看,其中pkt_pts表示该帧需要在xx时间上播放(相对时间)

获取方法(注意:该命令会不断输出直播流的frame,执行一秒钟后可以中断,然后查看其中一个frame即可)

代码语言:javascript复制
ffprobe.exe -show_frames http://5815.liveplay.myzijiebao.com/live/5815_89aad37e06ff11e892905cb9018cf0d4_900.flv
一个frame的示例一个frame的示例

直播中,理论上pts是需要单调递增的,但经常会遇到:

1、由于推流设备对音视频帧做编码时,写入的时间戳异常,导致pts突然变得很大;

2、对音视频录制时,由于推流设备异常,使得时间戳跳变,导致录制出来的视频时长异常变大(几分钟的视频,被记录成几百个小时)

这里举个例子,正常情况下,推流设备源源不断地推流,而录制模块原封不动地把各个音视频帧记录下来,如下图

左边是推流,右边是录制左边是推流,右边是录制

则拿到一个时长为7的录制文件,但如果推流设备异常,写入的时间戳异常跳变,如下图

左边是推流,右边是录制左边是推流,右边是录制

由于在第5帧开始,时间戳跳变成20,录制模块也原封不动地录制,导致最后记录的录制文件时长是22,这明显和实际情况不一致;

直播播放时是否异常?

这种情况下,直播推流播放时,未必会出现异常,因为播放器是接收到什么内容就播放什么内容,只要pts是递增的;

如果出现下图情况,则播放时出现异常

时间戳跳变后又恢复了时间戳跳变后又恢复了

播放器在播放完pts=22的视频帧之后,收到了pts=8的视频帧,由于该帧的pts比当前的pts小,认为收到的帧是已经过时的,则丢弃后面的8、9、10、11这几帧,直到pts>22;

对于观众来说,可能会出现一段时间的黑屏,但此时重新拉流,又自动恢复了。

录制是否异常

对于直播录制来说,一般云厂商是原封不动地录制,用最大pts减去最小pts,则最后形成了一个时间异常的录制文件;

时间戳跳变有恢复时间戳跳变有恢复

如何修复录制文件

常见的方案有两种:

1、剔除异常帧

2、对记录的每个视频帧重新设置pts

对于方案1,会出现数据丢失的情况,一般不推荐,但是成本较低,如果录制成hls,还可以在m3u8文件中,简单地把部分ts索引删除,完成异常帧丢弃。

对于方案2,,常见的就是用ffmpeg做视频转码,如下图,对decoded后的frames,重新设置pts

对于hls格式的录制文件来说,可以用ffmpeg把每个ts分片合成一个mp4文件,即可解决当前问题,当然该偏方并不是万能的,如果你的推流设备严重异常,该偏方也未必能解决,不过不妨一试。

彻底解决方案,还是得优化推流设备,比如使用腾讯云的移动直播SDK

0 人点赞