使用FFmpeg测试SRT协议

SRT协议是基于udp的传输协议,致力于改善弱网环境下的流媒体传输。与quic类似,是在udp协议之上进行数据的可靠传输,可以说是在应用层实现差错控制。

ffmpeg从4.0版本开始支持srt协议,但是官方提供的ffmpeg工具不支持srt协议,所以需要编译一个带srt的ffmpeg进行测试。

编译SRT

不同的系统编译方法不一致,参考:SRT仓库。注意:最后要make install,centos6如果提示devtoolset-3安装不上请使用新版的devtoolset。

编译FFmpeg

克隆ffmpeg源码
git clone --depth=1 https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg

配置编译选项,注意要加上--enable-libsrt
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --prefix="$HOME/ffmpeg_build" \
  --pkg-config-flags="--static" \
  --extra-cflags="-I$HOME/ffmpeg_build/include" \
  --extra-ldflags="-L$HOME/ffmpeg_build/lib" \
  --extra-libs=-lpthread \
  --extra-libs=-lm \
  --bindir="$HOME/bin" \
  --enable-gpl \
  --enable-libsrt

make

FFmpeg作为SRT服务端

./ffmpeg -re -i video.mp4 -c copy -f mpegts "srt://0.0.0.0:12500?pkt_size=1316&mode=listener"

pkt_size是配置包大小,mpegts通常设置为1316(188*7),因为网卡的最大传输单元通常是1500,所以这个值需要比1500小,每个传输单元中IP和UDP头部字节数有28个,剩下的1472个字节中srt头占了16个,所以实际可承载的数据最大为1456个字节。 mode用于配置srt的工作模式,srt有三种工作模式,listener(用于服务端接收请求),caller(用于客户端发起请求),rendezvous(会和模式,双方等价),默认为caller

FFmpeg使用SRT拉流

./ffplay -fflags nobuffer "srt://服务端IP:12500/live/test?paket_size=1316&mode=caller"

为了让测试效果更明显。使用-fflags nobuffer关闭缓冲。

模拟丢包

可以使用tc命令模拟丢包

sudo tc qdisc add dev bond0 root netem loss 10%

最后记得关闭丢包

sudo tc qdisc del dev bond0 root

测试结果

在20%丢包的弱网情况下,播放流畅,但是画面会是不是出现部分花屏,应该是srt在丢包严重的情况下为了保证播放的流畅该丢的包还是会丢。作为对比在同等环境下使用基于tcp的rtmp协议传输,会出现比较严重的卡顿。

参考

  1. https://medium.com/@eyevinntechnology/using-ffmpeg-and-srt-to-transport-video-signal-to-the-cloud-7160960f846a
  2. https://github.com/runner365/read_book/blob/master/SRT/srt_protocol.md