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协议传输,会出现比较严重的卡顿。
参考
- https://medium.com/@eyevinntechnology/using-ffmpeg-and-srt-to-transport-video-signal-to-the-cloud-7160960f846a
- https://github.com/runner365/read_book/blob/master/SRT/srt_protocol.md