用户提供的脚本用于将HLS流通过RTMP推流到指定地址。根据你的消息,可能遇到了推流地址参数处理的问题。以下是关键点分析和解决方案:
问题分析
- 参数未正确转义:
- 当RTMP URL包含
&
等特殊字符时,在命令行中直接传递会导致参数被截断。 - 例如,未加引号的URL中的
&
会被Shell解释为后台运行命令的分隔符。
- 当RTMP URL包含
- 鉴权参数问题:
wsSecret
和wsTime
通常是CDN(如腾讯云、阿里云)的鉴权参数,需确保其值正确且未过期。
解决方案
- 正确传递URL参数:
- 在命令行中使用引号包裹整个RTMP URL,确保参数完整传递:
python script.py "rtmp://example.com/live?dyPRI=0&origin=hw&...&wsTime=681ec49e"
- 在命令行中使用引号包裹整个RTMP URL,确保参数完整传递:
- 检查鉴权参数有效性:
- 确保
wsSecret
是通过服务端算法生成的合法签名。 - 确认
wsTime
为Unix时间戳且未过期(如未来1小时内有效)。
- 确保
- 代码改进(防御性处理):
- 添加URL编码处理,防止特殊字符破坏命令行:
from urllib.parse import quote def send_stream(rtmp_url): encoded_url = quote(rtmp_url, safe=':/?&=') cmd = [..., encoded_url] subprocess.run(cmd)
- 添加URL编码处理,防止特殊字符破坏命令行:
- 检查输入流路径:
- 确保
/dev/shm/fflive/hls/live.m3u8
存在且FFmpeg有权限读取。
- 确保
完整修复代码
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_url): """推流到指定地址(自动处理特殊字符)""" # 对URL进行编码,保留必要符号 encoded_url = quote(rtmp_url, safe=':/?&=') cmd = [ 'ffmpeg', '-re', '-i', get_pipe_path('live.m3u8'), '-c', 'copy', '-f', 'flv', '-protocol_whitelist', 'file', encoded_url # 使用编码后的URL ] subprocess.run(cmd) if __name__ == "__main__": parser = argparse.ArgumentParser(description='RTMP推流器') parser.add_argument('rtmp_url', help='推流地址(支持tee协议多地址)') args = parser.parse_args() send_stream(args.rtmp_url)
操作步骤
- 运行脚本时引用URL:
python script.py "你的完整RTMP地址含所有参数"
- 验证鉴权参数:
- 联系CDN服务商确认
wsSecret
和wsTime
生成方式是否正确。
- 联系CDN服务商确认
- 监控FFmpeg输出:
- 查看是否有权限错误或输入流无法读取的提示。
通过以上调整,推流脚本能正确处理复杂URL参数并确保鉴权有效性。