tee-Muxer多路输出分析
作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音
我们通常会遇到这样的需求,例如把 YUV 数据编码之后,推送到多个直播地址。但如果调多次 ffmpeg 命令,会编码多次。编码是非常消耗计算资源。
那有没有一种方法,能编码一次,然后基于现有的编码数据进行 多次封装,推送到多个直播地址?
这个也是有的,命令如下:
ffmpeg.exe -re -i juren-30s.mp4 -map 0 -c:v h264 ^
-f tee "[f=flv]rtmp://192.168.0.88/live/livestream|[f=flv]rtmp://192.168.0.99/live/livestream"
上面的命令,把编码后的 h264 数据直接推送到 两个 IP 地址,192.168.0.88 与 192.168.0.99
你也可以使用不同网络协议的,不是一定要一样的,例如可以一个是 TCP 流,一个是 UDP 流,如下:
ffmpeg.exe -re -i juren-30s.mp4 -map 0 -c:v h264 ^
-f tee "[f=mpegts]tcp://192.168.0.88:1234|[f=mpegts]udp://192.168.0.99:1234"
你也可以一边推流,一边把编码后的数据保存到 本地的 mp4 文件里面,如下:
ffmpeg.exe -re -i juren-30s.mp4 -map 0 -c:v h264 ^
-f tee "[f=mp4]./juren_out.mp4|[f=flv]rtmp://192.168.0.99/live/livestream"
你还可以 把编码后的数据 同时保存成 mp4 与 ts ,如下:
ffmpeg.exe -re -i juren-30s.mp4 -map 0 -c:v h264 ^
-f tee "[f=mp4]./juren_out.mp4|[f=mpegts]./juren_out.ts"
上面的命令,都使用了 -f tee 选项,所以 tee 实际上是一个 Muxer,只不过他也是一个 伪复用
tee muxer 的实现在 libavformat/tee.c 里,如下:
AVOutputFormat ff_tee_muxer = {
.name = "tee",
.long_name = NULL_IF_CONFIG_SMALL("Multiple muxer tee"),
.priv_data_size = sizeof(TeeContext),
.write_header = tee_write_header,
.write_trailer = tee_write_trailer,
.write_packet = tee_write_packet,
.priv_class = &tee_muxer_class,
.flags = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
};
本章主要分析 tee Muxer 的实现原理,使用的调试命令如下:
./ffmpeg -i juren-30s.mp4 -map 0 -c copy -f tee "[f=mp4]./juren_out.mp4|[f=mpegts]./juren_out.ts"