简介
直播推流时,对于视频帧和音频帧,都记录着一个时间戳,用于表示该帧播放的相对时间,可以用ffprobe命令查看,其中pkt_pts表示该帧需要在xx时间上播放(相对时间)
获取方法(注意:该命令会不断输出直播流的frame,执行一秒钟后可以中断,然后查看其中一个frame即可)
代码语言:javascript复制ffprobe.exe -show_frames http://5815.liveplay.myzijiebao.com/live/5815_89aad37e06ff11e892905cb9018cf0d4_900.flv
直播中,理论上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