直播延迟从 30 秒压到 3 秒:LL-HLS、GOP 和去 B 帧的实战调优
做过低延迟直播的都知道,RTMP 推到 CDN 再到观众,动辄 10~30 秒延迟,连麦根本没法用。把延迟压下来不是改一个参数,是一串取舍。这篇记我压到 3 秒左右踩过的点。
延迟从哪来
直播链路:采集 → 编码 → 推流 → 服务器缓冲 → 切片/分发 → 播放器缓冲。每一环都在攒延迟。想低延迟,得每环都砍。
编码端:GOP 短、去 B 帧
B 帧需要前后参考,天然增加延迟。直播关掉它:
ffmpeg -i in.mp4 -c:v libx264 -preset veryfast -x264-params "bframes=0" -g 30 -keyint_min 30 -sc_threshold 0 -tune zerolatency out.flv
bframes=0:去 B 帧;-g 30:GOP 长度(按帧,30fps 即 1 秒一个关键帧),越短切得越碎、延迟越低,但压缩率降;tune zerolatency:x264 的零延迟调优,牺牲一点压缩换速度。
分发端:LL-HLS 或低延迟协议
传统 HLS 一片 6 秒、缓冲 3 片,光分发就 18 秒。改法:
- LL-HLS(低延迟 HLS):切片拆成更小的 part(如 0.5 秒),播放器边下边播。nginx 或 SRS 支持;
- 选协议:真要秒级,上 WebRTC(延迟 <1s,但接入复杂)或 SRT(抗丢包,适合推流段);RTMP 本身延迟不高,高的是下游 HLS 分发。
播放器端:别自己加缓冲
播放器默认会预缓冲 3~5 秒防卡。低延迟场景用 ffplay 的 nobuffer:
ffplay -fflags nobuffer -flags low_delay -i "http://.../index.m3u8"
坑:延迟低了容易卡
GOP 太短、缓冲太小,网络一抖就花屏/卡顿。我最后定在 GOP=1s、LL-HLS part=0.5s、播放缓冲 1.5s,综合延迟约 3 秒、弱网卡顿可接受。别盲目追求 1 秒,体验崩了更糟。
选型小结
- 连麦/会议:WebRTC;
- 赛事/秀场要低延迟又稳:LL-HLS 或 SRT+LL-HLS;
- 普通点播回放:别折腾,常规 HLS 最稳。
前面直播协议那篇讲了 RTMP/WebRTC/SRT 区别,这篇是"怎么把延迟按下去"的实操。