在FFmpeg中,tee
协议用于将输出同时分发到多个目的地,特别适用于需要将直播流推送到多个RTMP服务器的场景。以下是具体用法和代码示例:
核心语法
ffmpeg -i input -f tee "[f=flv]rtmp://地址1|[f=flv]rtmp://地址2"
[f=flv]
:指定每个输出的封装格式(RTMP必须用flv
)|
:分隔不同输出地址
在你的Python脚本中集成tee
修改后的代码支持多地址推流:
import os
import subprocess
import argparse
from urllib.parse import quote
MEM_PIPE_DIR = "/dev/shm/fflive/hls"
def get_pipe_path(name):
return os.path.join(MEM_PIPE_DIR, name)
def send_stream(rtmp_urls):
"""同时推流到多个地址"""
# 生成tee协议参数: "[f=flv]url1|[f=flv]url2"
tee_segments = []
for url in rtmp_urls:
encoded_url = quote(url, safe=':/?&=')
tee_segments.append(f"[f=flv]{encoded_url}")
tee_output = "|".join(tee_segments)
cmd = [
'ffmpeg',
'-re',
'-i', get_pipe_path('live.m3u8'),
'-c', 'copy',
'-f', 'tee',
'-map', '0', # 映射所有流
tee_output
]
subprocess.run(cmd)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='RTMP多路推流器')
parser.add_argument('rtmp_urls', nargs='+',
help='推流地址列表(用空格分隔),例: "rtmp://地址1" "rtmp://地址2"')
args = parser.parse_args()
send_stream(args.rtmp_urls)
使用示例
# 推送到两个平台(参数用空格分隔)
python script.py "rtmp://s1.com/live/streamkey" "rtmp://s2.com/live/streamkey"
关键细节说明
- 参数分隔方式:
- 使用
nargs='+'
接受多个地址参数 - 命令行中用空格分隔不同URL(无需手动处理
|
)
- 使用
- URL编码防御:
encoded_url = quote(url, safe=':/?&=')
保留URL中的必要符号(
: / ? & =
),避免破坏推流地址结构 - 流映射参数:
'-map', '0' # 包含输入中的所有视频、音频、字幕流
如果输入是纯音频/视频流,可改用:
复制'-map', '0:v', # 只映射视频 '-map', '0:a' # 只映射音频
常见错误处理
错误现象 | 解决方案 |
---|---|
Unrecognized option 'f' |
确认[f=flv] 写在引号内部 |
URL截断 | 检查是否漏掉参数中的引号 |
协议不支持 | 确保输出地址使用rtmp:// 前缀 |
通过这种实现方式,你的脚本可以灵活支持多平台同步推流需求。