FFmpeg tee功能无法实现推流复用,求优化多平台推流方案
解决FFmpeg推流复用(Tee功能)与资源优化问题
嘿,我明白你现在的痛点——跑两个FFmpeg实例分别推流到Facebook和Twitch,硬件资源吃满不说,操作还麻烦。其实用FFmpeg的tee模块就能实现单实例复用推流,只做一次视频叠加和编码,直接把流同时送到两个平台,我来给你一步步拆解正确的用法,还有常见的坑怎么避。
正确的Tee模块命令示例
先给你直接能用的完整命令,之后再解释细节:
ffmpeg -i rtmp://localhost/app/streamkey -i logo.png \ -filter_complex "[0:v][1:v] overlay=0:0" \ -c:v libx264 -preset veryfast -bufsize 4000k \ -c:a aac -b:a 160k -ar 44100 \ -f tee "[f=flv]rtmp://live-api.facebook.com:80/rtmp/fb_streamkey|[f=flv]rtmp://live.twitch.tv/app/twitch_streamkey"
关键细节解释:
- 只执行一次
-filter_complex叠加操作:之前两个实例会重复处理视频叠加,现在只做一次,直接节省一半的视频处理资源 tee的语法规则:用|[f=容器格式]推流地址来分隔多个输出目标,这里必须明确指定f=flv(因为两个平台都用FLV容器接收RTMP流),很多人就是漏了这个格式指定导致tee失效- 编码参数统一设置:所有视频、音频编码参数只写一次,两个输出共用同一套编码结果,CPU只做一次编码,资源占用直接砍半
常见Tee功能失效的排查点
如果你之前用tee失败,大概率是踩了这些坑:
- 忘记指定输出容器格式:必须给每个推流地址加上
[f=flv],否则FFmpeg无法识别输出格式,直接报错退出 - 特殊字符转义问题:如果你的streamkey里包含
?、&这类特殊字符,一定要用单引号把整个tee参数包起来,避免shell解析出错:-f tee '[f=flv]rtmp://live-api.facebook.com:80/rtmp/fb_key?param=1|[f=flv]rtmp://live.twitch.tv/app/twitch_key' - 推流不稳定/丢包:可以给每个输出加上缓冲参数,提升推流稳定性,调整后的tee部分如下:
-f tee "[f=flv:buffer_size=4000k]rtmp://live-api.facebook.com:80/rtmp/fb_streamkey|[f=flv:buffer_size=4000k]rtmp://live.twitch.tv/app/twitch_streamkey"
进一步降低资源占用的技巧
如果想再压榨一下性能,试试这些优化:
- 启用硬件加速编码:如果你的CPU支持Intel Quick Sync或者NVIDIA NVENC,直接用硬件编码替代
libx264,CPU占用能降70%以上:- Intel平台替换编码参数:
-c:v h264_qsv - NVIDIA平台替换编码参数:
-c:v h264_nvenc
注意硬件编码的preset命名和libx264略有不同,比如NVIDIA用-preset fast即可
- Intel平台替换编码参数:
- 复用原始音频流:如果原始RTMP流的音频已经符合平台要求(AAC 160kbit/s、44100Hz),可以直接复制音频,不用重新编码:把
-c:a aac -b:a 160k -ar 44100改成-c:a copy,节省音频编码的资源 - 调整编码预设:
veryfast已经是兼顾速度和画质的选择,如果还想省资源,可以换成superfast或ultrafast,画质损失几乎可以忽略
替代方案:用Nginx RTMP模块中转推流
如果你实在搞不定tee,也可以用Nginx来做中转,让FFmpeg只推一次流到Nginx,再由Nginx转发到两个平台:
- 修改Nginx的
nginx.conf,添加两个RTMP应用:rtmp { server { listen 1935; # 接收FFmpeg推过来的叠加后流 application processed_stream { live on; } # 负责转推到两个平台 application multi_push { live on; push rtmp://live-api.facebook.com:80/rtmp/fb_streamkey; push rtmp://live.twitch.tv/app/twitch_streamkey; # 把processed_stream的流relay过来 pull rtmp://localhost/processed_stream/stream; } } } - FFmpeg只需要推流到Nginx的
processed_stream应用:ffmpeg -i rtmp://localhost/app/streamkey -i logo.png \ -filter_complex "[0:v][1:v] overlay=0:0" \ -c:v libx264 -preset veryfast -bufsize 4000k \ -c:a aac -b:a 160k -ar 44100 \ -f flv rtmp://localhost/processed_stream/stream
这样Nginx会自动把流转发到两个平台,FFmpeg只做一次编码和叠加,资源占用同样很低。
内容的提问来源于stack exchange,提问作者Jorge Vértiz
相关产品推荐
相关产品推荐

