前言:
在直播拉流的时候,经常会遇到这样的情况,画面会比声音延迟个几秒,往往会先听到声音后才看到画面,或者是声音和画质明显对不上,这样就造成了我们常说的音视频画面不同步的情况。那问题原因是什么呢?我们应该如何避免?接下来我们以腾讯云直播为例来分析下这个问题。
原因定位及解决方案
首先需要了解造成声音画面不同步的原因有哪些。众所周知,播放器在渲染和播放完全是依靠音视频数据携带的时间戳信息来同步,如果从媒体源端拉取的音视频数据本身自带的时间戳就有问题的话,那么播放器往往也无能为力了,因此音视频不同步不光要考虑推流端的的问题也要考虑播放的的问题。
播放原理:
解码播放是通过解码器处理最底层播放相关的逻辑。它将不同封装格式的视频进行解包,并将其内容解码,然后将解码后的视频帧交给系统进行渲染,最终让终端用户看到。
播放端是根据DTS和PTS来进行渲染播放的,PTS(Presentation TimeStamp)是渲染用的时间戳,也就是说,我们的视频帧是按照 PTS 的时间戳来展示的。DTS(Decoding TimeStamp)解码时间戳,是用于视频解码的。
那为什么有了 PTS 还要有 DTS呢?这就与音视频的 I/B/P帧有关了。如果我们的视频中没有B帧,那显示的帧的顺序与存放的帧的顺序是一样的,此时PTS与DTS 的值就是一样的,也就没有存在两个时间戳的必要了。
详细描述:
有了B帧之后,就不是这个样子了。比如一个视频流实际应该展示的帧的顺序是 I, B, B, P 帧解码后的视频帧。 但实际上,这些帧到达之后,在缓冲区里就按照第二行的样子存放的。为什么会这样呢?这是由于P帧参考的是 I帧,B帧是双向参考帧。也就是说,如果 I帧和P帧没有解码的话,B帧是无法进行解码的。基于此,为了解决这个问题就出现了 PTS和DTS两个时间戳。 第三行是视频帧真正的解码顺序,先解 I帧,然后是P帧,然后是第一个B帧,最后是第二个B帧。 最终的展示顺序是 I帧解码后的视频帧,第一个B帧解码后的视频帧,第二个B帧解码后的视频帧,最后是P帧解码后的视频帧。
第一行,实际应展示的顺序:I B B P 第二行,实际解码存放顺序:I P B B 第三行,按实际顺序号展示:1 4 2 3 DTS 第四行,按实际顺序号展示:1 2 3 4 PTS
已经了解了播放原理,那就根据原理多方面去排查原因。接下来从以下几方面分析下原因:
1、设备问题
(1)很多情况在进行直播的时候都会安装各种外设采集设备,但有些设备在采集处理的时候可能会出现不稳定的情况,都知道摄像头和麦克风在采集音视频数据后会经过硬件的信号处理模块进行处理,如果处理的时候不稳定,导致获取的时间戳有误差,那么就会出现音视频不同步的情况。
解决方法
检查分析采集设备的数据信息,做一些抖动的效正。
(2)在拉流播放时候会发现有些设备播放是正常的,有些设备音视频画面是不同步的,所以要根据情况具体排查,首先有些设备播放是正常的,能判断一个问题,那就是推流端通过采集上传到流媒体服务端的音视频时间戳是正常的,那么我们就要从播放端去找问题了。
通过排查测试了PC端、安卓、苹果部分手机的播放,发现了通过安卓端播放的时候会出现音视频流不同步的情况,声音的时间戳比视频靠前了很多,苹果和PC端这边的播放是没有问题的。
大概判断可能是手机设备性能的原因,在检查obs推流设置的码率和FPS后发现,FPS设置为60帧,码率为7000kb,因此可以判断是FPS和码率过高,导致低性能设备的处理能力和内存跟不上的时候,抛弃了原有的时间戳,使用了当前的时间,所以就会出现音画面不同步的情况。
解决方法
降低FPS和码率,修改FPS为25,码率为2000kb左右,然后在有问题的安卓设备去播放后,发现一切都正常了.
2、时间戳问题
(1)时间戳采集后发生变化
都知道音视频时间戳是在设备同时采集时候获取的,但是如果这些时间戳在后面进行了变化,而推流端这边重新获取了变化后的时间戳的话,则也会很大概率出现音视频不同步的情况。比如设备在采集音视频数据后,视频进行了高级美颜、滤镜,转码、重新编码后更新了处理后的时间戳的话,那么就可能会出现音视频时间戳不同步的情况。
解决方法 由于视频压缩算法变得越来越复杂,解码过程是一个需要密集计算的过程,并且为了保证解码性能和流畅的播放体验,解码过程需要强依赖于操作系统和硬件。现在的大部分解码都依赖于 GPU 加速解码的帮助。如果没有 GPU 的加速,解码一个 1080P 的视频就会占去 70% 左右的 CPU 计算量,并且丢帧率还可能很严重。而高级美颜、滤镜、特效都功能对手机性能的要求都会比较高一些,我们可以开启硬件加速,减少不必要美颜特效的使用。
对比转码前后的时间戳,看下是不是经过转码后时间戳进行了变化。
(2)时间戳没有逐步递增
在拉取音视频不同步的时候会发发现该码流的时间戳是没有单数递增的,出现了频繁的回退,这样的流回调导致播放的时候频繁的卡顿,当出现小于主时针的视频帧后,会出现丢弃的情况,这样就会出现卡顿引起的画面不同步。
解决方法
检查推流端的时间戳是不是正常的单数递增,是否是采集时候出现问题还是采集后经过了其他重新编码的操作出现问题
3、网络传输问题
由于网络传输的延迟、丢包等原因,同一时间的音视频流数据包不能同时到达播放端进行解码播放的话,可能也会出现不同步的问题。
解决方法
在拉流端时刻监测播放的网络下载数据、音视频缓存数据、音视频渲染时间差,通过日志信息发现问题,立刻调整解决问题。
总结
在遇到音画不同步问题的时候,可以根据不同情况去分析问题,先判断出是源流的问题,还是播放端的问题,同时在播放端去加一些校正时间戳的优化,结合上述的解决方案,相信遇到音画不同步的问题就可以迎刃而解了。