你可能会遇到这种情况:在一个偏远地区做直播,网络信号时好时坏,画面卡成PPT,声音断断续续,观众疯狂刷“主播卡了”。传统RTMP推流在丢包率超过5%时基本就废了,而SRT(Secure Reliable Transport)协议正是为了解决这种弱网环境下的传输问题设计的。SRS这个流行的流媒体服务器从4.0版本开始原生支持SRT,让我们可以在高丢包、高抖动的网络中依然保持流畅的视频传输。

SRT的核心竞争力在于它的丢包恢复机制和抗抖动策略,但默认配置往往不是最优的。比如在移动网络下,丢包率可能高达20%,如果参数调不好,SRT的效果甚至不如UDP裸传。所以我们需要根据自己的网络场景,手动调整那些关键参数。

二、丢包恢复参数调优:让SRT在坏网中也能“捡回”数据

SRT使用了一种叫做ARQ(自动重传请求)的机制,它不像TCP那样有复杂的拥塞控制,而是专注于快速重传丢失的包。但重传太多会占用带宽,太少又会导致画面花屏。下面详细说说怎么调。

2.1 理解核心参数:latency、maxbw 和 payloadsize

  • latency:这是SRT的“耐心”值,单位毫秒。它告诉SRT你愿意忍受多大的延迟来等待丢失的包被重传。网络差的时候,如果latency设得太小,重传次数不够,丢包无法恢复;设得太大,直播延迟会很高。
  • maxbw:最大带宽,单位bps。SRT会动态调整发送速率,但不会超过这个上限。设得太小会导致传输卡顿,太大又可能挤占其他应用网络。
  • payloadsize:每个UDP包携带的数据大小。设得太大,丢包影响范围广;设得太小,包头开销增加。通常取1316(一个TS包的大小)。

2.2 调优实验:从默认值开始一步步改

假设你正在用SRS搭建一个直播服务,目标是在30%丢包率下依然能保持流畅画面。下面是一个SRT推流配置的示例(技术栈:SRS,文件srt.conf)。

# SRT推流配置示例
listen 1935; # RTMP默认端口
srt_server {
    enabled on;          # 启用SRT支持
    listen 10080;        # SRT监听端口
    connect_timeout 5000; # 连接超时5秒
}
vhost __defaultVhost__ {
    srt {
        # ========== 丢包恢复核心参数 ==========
        latency 1200;      # 设置延迟1200毫秒(1.2秒),适应高丢包环境
        # 经验:丢包率10%时建议1000ms,20%时1500ms,30%时2000ms
        # 我们取1200ms作为平衡点

        maxbw 10000000;    # 最大带宽10Mbps,确保重传有足够带宽
        # 注意:实际可用带宽要大于这个值,否则重传会抢走视频数据带宽

        payloadsize 1316;  # 标准TS包大小,兼容性好
        # 如果丢包率特别高(>20%),可以适当缩小到1000字节

        # ========== 高级重传策略 ==========
        loss_max 30;       # 最大丢包率百分比,超过后强制重传所有后续包
        # 设置30,表示允许30%丢包,再高就直接丢弃

        passphrase "mysecret"; # 加密密码(可选)
        pbkeylen 16;       # 加密密钥长度
    }
}

上面的配置中,latency 是关键。如果你发现画面频繁花屏,说明重传没来得及,可以试着把 latency 增加200毫秒;如果感觉延迟太大,就减少200毫秒,但注意观察是否出现花屏。maxbw 应该设置成实际可用带宽的70%左右,留下余量给重传。

2.3 用命令模拟弱网环境测试

在调整参数后,你需要在真实弱网下验证。可以用 tc 命令(Linux上)模拟丢包和延迟(技术栈:Bash)。

# 在发送端模拟丢包20%和抖动50ms
sudo tc qdisc add dev eth0 root netem loss 20% delay 50ms 10ms distribution normal
# 参数说明:loss 20% 表示随机丢包20%,delay 50ms 10ms 表示基础延迟50ms,抖动10ms
# distribution normal 让延迟更接近真实网络

# 测试完后删除模拟规则
sudo tc qdisc del dev eth0 root

用这个环境推流,观察SRS日志中 SRT: RTT=xxxmsSRT: pkt-loss=xxx 的信息。如果发现 pkt-loss 始终在目标值以下,且 RTT 稳定,说明调优有效。

三、抗抖动配置经验:让画面不再“一卡一卡”

网络抖动指的是延迟突然变大或变小,比如从20ms跳到200ms又立刻回来。SRT通过 jitter buffer(抖动缓冲区)来平滑这种变化。但抖动缓冲区太大,延迟高;太小,画面会频繁跳动。

3.1 抖动缓冲区的内部机制

SRT的抖动缓冲区实际上由 latency 参数间接控制。当网络抖动发生时,SRT会尽量在 latency 时间内重传丢失的包。如果抖动幅度超过 latency 的一半,重传就可能失败。所以抗抖动的关键是让 latency 能覆盖抖动的峰值。

latency 是静态的,而抖动是动态的。我们需要配合 SRS 的 srt_latency 模块(从SRS 5.0开始支持)来动态调整。不过这里我们用一个更简单的方案:在推流端和播放端都设置合理的 latency,并启用 tsbpd(时间戳漂移纠正)功能。

3.2 推荐配置:兼顾低延迟和抗抖动

下面的配置适合移动网络这种高抖动场景(技术栈:SRS)。

# 抗抖动优化配置片段
vhost __defaultVhost__ {
    srt {
        latency 1500;       # 提高到1.5秒,能扛住20ms到300ms的抖动
        # 如果抖动范围更大(比如50ms~500ms),建议2000ms

        tsbpd on;           # 启用时间戳基准漂移纠正
        # 这个功能会调整时间戳,让播放器感觉不到网络抖动

        # 针对高抖动的额外参数
        mss 1500;           # 最大段大小,和MTU保持一致
        # 避免UDP分片导致额外丢包

        # 自动调整接收缓存(可选)
        rcvbuf 8388608;     # 接收缓存8MB,能容纳1秒的1080p视频
        # 缓存越大,抗抖动能力越强,但内存消耗增加
    }
}

注意:tsbpd 需要接收端也支持,SRS作为服务端,推流端客户端(如ffmpeg或OBS)也需要设置 tsbpdoffmode=off(默认)。如果你用ffmpeg推流,命令中加上 -pkt_size 1316 -buffer_size 65536 -f mpegts 'srt://server:10080?mode=caller&latency=1500&tsbpd=1',这样双方抖动缓冲区一致。

3.3 实际案例:从卡顿到流畅的调整过程

曾经有一个用户反馈,在4G网络下直播,画面每隔几秒就卡一次,延迟达到3秒。查看SRS日志发现 SRT: dRTT=300ms(抖动),而他的 latency 只设了500ms。我建议他把 latency 调到2000ms,并开启 tsbpd。调整后,卡顿消失,延迟增加到2.5秒,但从用户的角度看,稳定的画面比低延迟更重要。后来他又把 maxbw 从5M提高到8M,解决了偶尔的花屏问题。

四、SRT在弱网中的优缺点分析

优点

  • 丢包恢复能力极强,配合ARQ可以实现接近TCP的可靠性,但延迟远低于TCP。
  • 内置加密(AES-128/256),安全性优于RTMP。
  • 支持端到端的延迟控制,不像TCP那样被拥塞控制绑架。
  • SRS集成度高,配置简单,开箱即用。

缺点

  • 需要两端的客户端都支持SRT协议(比如ffmpeg、OBS、VLC等),不像RTMP那么普及。
  • 参数调优依赖于对网络状况的准确估计,调不好效果反而更差。
  • 高丢包率下重传会占用大量带宽,导致视频码率下降。
  • 延迟无法做到像UDP裸传那样极低(因为是可靠传输)。

五、注意事项:避开这些坑

  1. 不要盲目套用别人的配置:每个网络的丢包率、延迟、抖动特征不同。比如家庭宽带丢包率通常小于1%,而4G网络可能10%~40%。一定要根据实际测试结果调整。

  2. 留意带宽余额:如果 maxbw 超过实际可用带宽,重传包会和视频数据包争抢,导致新丢包增加。可以先用 iperf3 测试可用带宽,再设置 maxbw 为实测值的80%。

  3. 推流端和拉流端的参数要一致:比如 latency 如果一边设200ms,另一边设2000ms,会造成接收端缓存过多或过少,产生卡顿。最好在推流URL中显式指定。

  4. 关注CPU负载:SRT的加密和重传逻辑比较消耗CPU,尤其在弱网下大量重传时。SRS官方建议单核CPU支持不超过500Mbps的SRT流量,超过需要启用多线程。

  5. 日志异常排查:如果出现 SRT: NAK send failed,说明丢包率超出了重传能力,需要增大 latency 或降低码率。SRT: Too many retransmissions 表明带宽不足,需要增大 maxbw 或减小码率。

六、文章总结

今天我们从实际场景出发,深入聊了SRS中SRT协议的丢包恢复参数调优和抗抖动配置。核心思路很简单:根据网络丢包率调整 latency,根据可用带宽设置 maxbw,同时通过 tsbpd 和合适的接收缓存来对抗抖动。不要指望一锤子买卖,一定要动手测试——在你真实的弱网环境下,用 tc 模拟或者直接到信号不好的地方推流,观察SRS日志和画面质量,微调参数直到满意。SRT不是银弹,但配合正确的调优,它能在RTMP无法工作的网络里给你一条可靠的通路。希望这篇文章能让你少走一些我们踩过的坑。