音视频开发必懂知识—低延迟相关知识整理
1:了解延迟
在推流,拉流相关业务(如直播),从数据的采集发送到客户端接收到数据后播放,其实是有一定的播放延迟的。
如下图:使用 rtmp(是基于 tcp 进行传输的)进行推流,然后使用不同方式对 rtmp 拉流播放,延迟误差。
从图中可以看出:
===》使用 ffplay 进行播放时延迟是比较大的,默认是有缓存的。
===》如果去掉缓存,可以对延迟有一定的优化。
===》以及使用其他的一些方案,其实是可以把播放延迟进行降低的,那么降低延迟的方案有那些呢?
2:从直播的流程上进行分析:
下图从老师的课程中截取得图片,描述了直播从数据采集,处理,推流===》到流媒体服务器===》再到客户端进行拉流播放的流程。
如果要考虑直播延迟,其实是要根据这个流程从推流端,流媒体服务器,以及拉流端进行分析,同时要考虑网络抖动
3:从流程引入延迟分析
3.1:整体上分析延迟原因
3.1.1:延迟原因
音视频的直播一般流程是: 推流 ===》流媒体服务器 ===》拉流
影响音视频的原因一般有:
1:缓存 (有缓存就说明有数据的堆积,是延迟)
2:网络抖动(网络抖动会导致数据发送阻塞,或者一次性收到过多数据(需要做变速处理加快消费保证实时))
3.1.2:传输方案
udp 相对于 tcp,更适合音视频的低延迟传输。
rtmp 底层使用的是 tcp 传输,tcp 的可靠传输其实会丢失一定的实时性。
webrtc 基于 udp 进行传输的,相比 tcp,可以一定程度降低延迟。
除此之外,适用于音视频的另一套传输协议:quic(快速 UDP 互联网连接)
另外:现在市面上电商直播一般采用 rtmp h264+aac 因为 CDN 支持比较高,虽然 rtmp 使用 tcp 传输,有一定的延迟。
3.2:推流端延迟分析
推流端一般包括:音频的采集,音频处理,音频编码 和视频的采集,视频的处理,视频编码,以及最终的推流动作
3.2.1:音频流的处理延迟
3.2.1.1:采样数导致一次采样会耗时
音频流的采集:采样延迟与设置的一次采样样本数有关。
===》假设采样率是 44.1khz,设置一次采集 1024 个样本再处理,则采集等待耗时为 1024*(1/44100),耗时 23.2ms
===》如果采样率为其他,设置采样个数,其实采样上就已经有耗时。
2.2.1.2:音频处理会耗时
对采集到的音频做混音,降噪等处理,也是有延迟
2.2.1.3:音频编码也会有延迟
音频编码也有延迟 webrtc opus 延迟比较低,但是 aac 有 1~2 帧的延迟
3.2.2:视频流的处理延迟
视频采集:一般 25 帧,采集到一帧就去处理喽
视频处理:(水印,美颜,滤镜)相关处理耗时一定要跟得上(软件/硬件) opengl 比较快==》不要队列阻塞,处理耗时
视频编码: zero lantency(零延迟), 不要用 b 帧
3.2.3:推流策略会导致的延迟
推流涉及推流策略,消费采集处理后的音频帧和视频帧。
采样本来就是实时采集的,推流应该是有数据就立马推流,不要缓存,越快越好。 ==》有延迟啊
3.3:流媒体服务器分析延迟
流媒体服务器涉及功能: 读数据,以及把数据推出去
3.3.1:流媒体服务器读数据策略
读数据,可能同一个数据,需要写给多个端去发送(如直播场景,多个人看)如何转发数据?
==》1:只有一个队列,读数据后,直接遍历 fd 进行写(如果其中一个 fd 卡顿,会阻塞)
==》2:每个写端有一个自己的队列,负责自己的数据写入。 (每个 fd 有自己的队列不影响其他模块)
设计队列时,如果有队列过多,满了(写延迟,消费过慢),可以设置覆盖。
3.3.2:(推流到服务器)读数据导致的延迟(多次读和一次读(内核态/用户态切换影响))
合并读取数据有延迟(有 200ms 的数据,每 10ms 读一次,是需要切换用户态和内核态,需要 20 次)
如何合并数据读取,200 的数据读取一次,内核态/用户态切换 1 次 可以降低 cpu。
3.3.3:服务器内部缓存队列会不会导致延迟
这里一般不会导致延迟,但是涉及队列消费过慢,如客户端卡顿,会队列中数据有过多。
客户端出现卡顿,客户端卡了 5s,服务端对应的队列会缓存 5s,恢复要让其发出去
网络恢复,如果一次拉取过多 5s 的数据,如果不做音频变速处理,客户端队列一直有延迟了。
3.3.4:(从服务器拉流)服务器写数据延迟
写数据(合并写处理)
==》有 200ms 要写,20ms 写一次,与 200ms 写一次的问题。
==》效率高,更高吞吐量(带宽),但是有延迟,实时性差。
3.3.5:服务器配置(srs),gop cache 开启的影响(视频帧 i,b,p 帧)
视频帧有 i 帧,b 帧,p 帧的差异:gop 就是两个 i 帧的差距
如果开启 gop cache:服务器缓存一个 gop,客户端从这个缓存的 gop 中 i 帧开始播放
===>最优场景: 客户端链接,gop 中刚好获得 i 帧
===>最差场景: 客户端链接,gop 中刚好从上一个 i 帧开始,客户端拉到上一帧的数据快速显示(如果不做变速播放,这里就会有延迟了,总是差一个帧)
===》开启 gop cache 的优点:可以快速显示画面。
===》开启 gop cache 的缺点:GOP 可能直接至少延迟一个 cache(网络抖动渲染等其他延迟)
如果不开 Gop cache,也有最优和最差:(p 帧和 b 帧是不现实画面的,黑屏)
===》最优:拉到 i 帧,直接解码显示
===》最差:刚好错过 i 帧,错过 i 帧,画面至少黑屏一个 gop 的时长,等到下一个 i 帧才能显示
webrtc 有一个优化技术:
客户端有请求连接时,服务器端先立马回复一个 i 帧的技术。
3.4:拉流端延迟分析
从上图可以看到拉流数据的流程:
拉取到服务器端的流后,音频流和视频流分别由专门的队列做缓存处理,去解码播放。
3.4.1:拉流端现象
1:缓存数据过多,要实时计算缓存队列的数据能播放的时长
===》帧间隔*帧数
===》最大的 pts-最小的 pts (pts 显示时间戳)
2:为什么打开有些播放器后,能听到声音的快速播放,如我在腾讯课堂听直播时就感受过
==》变速播放,为了快速消耗缓存中的数据 (直播场景,缓存其实就是延迟)
3.4.2:拉流端解决延迟(加速播放策略)
拉流端的延迟主要是:拉流后,缓存队列中数据有堆积,一直得不到消费(缓存导致了延迟)
==》尽快处理,加速消费就好了~
可以设置策略,使用加速播放来进行处理:
==》一些参数:缓存时间(触发变速),抖动值(回复正常参数),以及变速系数(控制变速速度)
起播:
========>检测缓存大于设置的缓存时间,开始播放,做变速处理,
========>如果缓存小于设置的缓存时间,则恢复正常播放
播放过程中:
==》抖动值:因为网络传输是有抖动的,抖动带来的缓存,如果按起播一样处理,就会陷入频繁的变速恢复中。
==》如果音频缓存大于 抖动值+设置的缓存时间 ==》触发变速播放
==》检测到小于设置的缓存时间,恢复正常播放。
注意:设置队列的缓存时间和设置抖动值,可以根据网络场景进行自己设置。
4:总结
推流 ==》服务器转发 ==》拉流
1:推流:注意采集延迟,音效处理,视频特效处理,编码延迟,有数据则直接推流,不要等待。
=========> 可以对队列帧数进行检测,根据帧数,判断网络,可以通过调整码率进行网络适配
2:服务器转发:
=========>合并读,数据队列,合并写
3:拉流
==========>数据队列,变速播放(sonic),变速触发和恢复机制的设置
技术参考:
音视频流媒体服务器高级开发学习地址:
FFmpeg/WebRTC/RTMP/RTSP/HLS/RTP播放器-音视频流媒体高级开发学习
音视频流媒体服务器高级开发学习视频资料点击 音视频学习资料 进去自取
评论