3. H265推流卡顿问题排查与解决:网络带宽不足与抖动引发的卡顿

推流卡顿,十有八九跟网络有关。H265 虽然压缩率高,省带宽,但它对网络的「脾气」也更敏感。说白了,H264 能凑合跑的网络环境,换 H265 可能就卡成幻灯片了。这一章,咱们就专门聊聊网络带宽不足和抖动这两个「罪魁祸首」。

3.1 带宽不足:不是算力不够,是路太窄

很多人一卡顿就怀疑编码器参数没调好,或者服务器性能不行。我刚开始排查卡顿问题时,也犯过这个错。后来发现,很多时候问题出在「路」上——你的上行带宽根本扛不住码率。

3.4.1 怎么判断是带宽不足?

别靠感觉,看数据。我个人习惯先看三个关键指标:

  • 发送缓冲区积压:如果编码器输出队列持续堆积,说明数据发不出去。
  • RTT(往返时延)飙升:带宽满载时,RTT 会从几十毫秒跳到几百甚至上千毫秒。
  • 丢包率突增:UDP 推流时,丢包率超过 1% 画面就开始花了。
我的小技巧: 在推流端用 iftop 或 nethogs 实时看带宽占用。如果码率设置是 4 Mbps,实际占用却一直在 4 Mbps 附近打满,那基本就是带宽瓶颈了。

3.4.2 带宽不足的典型表现

现象 可能原因 排查方向
画面突然卡住,几秒后恢复 带宽瞬间被占满,缓冲区溢出 检查上行带宽是否被其他进程抢占
码率波动剧烈,忽高忽低 编码器在自适应调整,但网络跟不上 查看码率曲线,确认是否频繁降码率
推流端 CPU 不高,但画面卡 网络层丢包重传导致延迟 用 Wireshark 抓包看重传率

3.2 网络抖动:比带宽不足更隐蔽的杀手

带宽不足还好查,码率设低点就行。但网络抖动——时延忽大忽小——才是真正让人头疼的。我在项目中遇到过好几次:带宽明明够用,码率也没打满,但画面就是一顿一顿的。查了半天,发现是运营商网络在高峰期有微小的抖动。

3.2.1 抖动是怎么产生的?

网络抖动说白了就是数据包到达时间不均匀。原因很多:

  • 路由拥塞:中间某个路由器负载高了,排队时间变长。
  • 无线网络干扰:Wi-Fi 信号不稳定,4G/5G 基站切换。
  • 运营商 QoS 策略:某些 ISP 会限流或优先级调整。

你想想看,编码器辛辛苦苦按 30fps 输出帧,每帧间隔 33ms。结果网络一抖,前两帧间隔 10ms,后两帧间隔 80ms。播放端收到的数据不均匀,缓冲区要么空要么满,卡顿就来了。

3.2.2 抖动的量化指标

业内常用 Jitter 来衡量抖动。计算公式不复杂:

Jitter = |(RTP timestamp 差) - (实际到达时间差)|

一般建议 Jitter 控制在 20ms 以内。超过 50ms,播放端就要开始丢帧或插帧了。

注意: 我曾经遇到一个案例,Jitter 只有 15ms,但画面依然卡。后来发现是播放端的 jitter buffer 设置太小,只有 30ms。网络稍微波动一下,缓冲区就空了。所以,排查时一定要两端都看。

3.3 核心排查流程:从现象到根因

下面这张图是我自己总结的排查流程,每次遇到卡顿问题,我就按这个顺序来。省时省力。

H265推流卡顿排查流程图 H265 推流卡顿排查流程 发现卡顿现象 带宽是否打满? 是 降低码率 否 检查抖动 验证效果 分析根因 问题解决 / 继续监控 排查要点: 1. 先看带宽利用率,再看抖动指标 2. 带宽不足 → 降码率或切编码参数 3. 抖动大 → 检查网络路径、增加 jitter buffer 4. 改完一定要验证,别凭感觉

3.4 实战解决方案

排查出问题后,怎么解决?我分享几个自己用过的方法。

3.4.1 带宽不足:降码率 + 动态调整

最直接的办法就是降低码率。但别一刀切,我建议用 ABR(自适应码率) 策略:

// 伪代码示例:基于带宽反馈动态调整码率
if (send_buffer_size > THRESHOLD_HIGH) {
    target_bitrate = current_bitrate * 0.8;  // 降 20%
} else if (send_buffer_size < THRESHOLD_LOW) {
    target_bitrate = min(max_bitrate, current_bitrate * 1.1);  // 升 10%
}
encoder_set_bitrate(target_bitrate);

嗯,这里要注意:降码率别降太猛,否则画面质量会断崖式下跌。我一般每次降 10%-20%,观察 2-3 秒再决定下一步。

3.4.2 网络抖动:增大 jitter buffer + FEC

抖动问题,播放端可以做一些补偿:

  • 增大 jitter buffer:从默认的 50ms 调到 100ms-200ms。代价是延迟会增加,但卡顿会明显减少。
  • 开启 FEC(前向纠错):发送端多传一些冗余包,接收端即使丢几个包也能恢复。H265 推流时,FEC 开销建议控制在 10%-15%。

我曾经踩过的坑: 有一次把 jitter buffer 调到 300ms,延迟太大,用户反馈「画面不卡,但声音对不上」。后来改成动态 jitter buffer:网络好时自动缩小,网络差时自动扩大。效果好了很多。

3.4.3 终极方案:切传输协议

如果 UDP 推流实在扛不住抖动,可以考虑切到 SRT 或 RIST 协议。这两个协议有内置的丢包重传和抖动控制机制。我在跨国推流项目中用过 SRT,效果比裸 UDP 好太多了。

协议 抗抖动能力 延迟 适用场景
UDP + FEC 中等 低(50-100ms) 内网或优质公网
SRT 强 中(100-300ms) 跨国、弱网环境
RIST 强 中(100-300ms) 广播级、多路聚合

3.5 避坑指南

最后,分享几个我亲身踩过的坑,希望能帮你少走弯路。

  • 别只看平均带宽:峰值带宽才是关键。我曾经遇到一个客户,平均带宽 10 Mbps,但峰值只有 2 Mbps。码率设 4 Mbps,必卡。
  • Wi-Fi 推流要小心:Wi-Fi 的抖动比有线大 3-5 倍。如果必须用 Wi-Fi,建议把码率降低 30%。
  • 别忘了看对端:有时候卡顿不是推流端的问题,而是接收端带宽不够。我遇到过推流端一切正常,但播放端在下载大文件,导致画面卡。

网络问题排查起来确实费时,但只要按流程来,一步步缩小范围,总能找到根因。嗯,这一章就到这里。记住:先看带宽,再看抖动,最后调参数。