You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现FFmpeg输出接入管道报错,求正确实现方案

问题:Python调用FFmpeg并将结果写入管道失败

问题背景

有一条可正常运行的Shell命令,用于将FFmpeg处理后的视频流追加到名为push的管道:

ffmpeg -re -i '2023-02-16_21:02:50.mp4' -f mpegts -c:v copy -c:a aac -vbsf h264_mp4toannexb pipe:1.ts | cat >> push

但用Python的subprocess模块实现时,出现错误:

cat: '>>': No such file or directory

对应的Python代码如下:

command = [
    'docker',
    'run',
    '-v',
    f'{cwd}:{cwd}',
    '-w',
    f'{cwd}',
    'jrottenberg/ffmpeg',
    '-re',
    '-i', f'{video_path}',
    '-f', 'mpegts',
    '-c:v', 'copy',
    '-c:a', 'aac',
    '-vbsf', 'h264_mp4toannexb',
    'pipe:1.ts',
]

pa = subprocess.Popen(
    command,
    stdout = subprocess.PIPE,
    stderr = error_file
)

command = [
    'cat',
    '>>',
    f'{pipe_name}'
]

with pa.stdout:
    pb = subprocess.Popen(
        command,
        stdin = pa.stdout,
        stdout = error_file,
        stderr = error_file
    )

错误原因

>>是Shell的重定向语法,不是cat命令的参数。当你把>>放进subprocess的命令列表时,cat会将其视为要读取的文件名,自然找不到这个文件,从而报错。

解决方案

方案1:跳过cat,直接用Python写入管道

这是最安全且高效的方式,不需要依赖Shell的重定向,直接在Python中处理FFmpeg的输出:

command = [
    'docker',
    'run',
    '-v',
    f'{cwd}:{cwd}',
    '-w',
    f'{cwd}',
    'jrottenberg/ffmpeg',
    '-re',
    '-i', f'{video_path}',
    '-f', 'mpegts',
    '-c:v', 'copy',
    '-c:a', 'aac',
    '-vbsf', 'h264_mp4toannexb',
    'pipe:1',  # 移除多余的.ts后缀,直接输出到标准输出
]

pa = subprocess.Popen(
    command,
    stdout=subprocess.PIPE,
    stderr=error_file
)

# 以追加二进制模式打开管道,将FFmpeg输出分块写入
with pa.stdout, open(pipe_name, 'ab') as pipe_file:
    # 按4KB块读取输出,避免内存占用过高
    for chunk in iter(lambda: pa.stdout.read(4096), b''):
        pipe_file.write(chunk)
pa.wait()
  • 调整FFmpeg的输出目标为pipe:1,这是标准输出的管道标识,.ts后缀是多余的。
  • 使用ab模式打开管道,实现和Shell中>>相同的追加写入效果。

方案2:启用Shell解析重定向(不推荐)

如果一定要保留cat >> pipe的逻辑,可以让subprocess调用Shell来解析重定向语法:

command = [
    'docker',
    'run',
    '-v',
    f'{cwd}:{cwd}',
    '-w',
    f'{cwd}',
    'jrottenberg/ffmpeg',
    '-re',
    '-i', f'{video_path}',
    '-f', 'mpegts',
    '-c:v', 'copy',
    '-c:a', 'aac',
    '-vbsf', 'h264_mp4toannexb',
    'pipe:1',
]

pa = subprocess.Popen(
    command,
    stdout=subprocess.PIPE,
    stderr=error_file
)

# 启用shell=True,让Shell处理>>重定向
with pa.stdout:
    pb = subprocess.Popen(
        f'cat >> {pipe_name}',
        stdin=pa.stdout,
        stdout=error_file,
        stderr=error_file,
        shell=True
    )
pb.wait()
pa.wait()
  • 注意:shell=True存在安全风险,如果pipe_name包含不可信输入,可能会触发命令注入漏洞,因此优先推荐方案1。

内容的提问来源于stack exchange,提问作者Eric Palmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 01:55:34