使用子进程将 stderr 和 stdout 从 ffmpeg 重定向到 Python 中的文件

Redirect stderr and stdout from ffmpeg to a file in Python with subprocess

我正在尝试将 ffmpeg 命令的 stderr 和 stdout 重定向到一个文件,并在执行 Python 脚本时抑制它们。这是我的代码:

import subprocess, shlex

cmd = 'ffmpeg -hide_banner -i input.mp4 -c:v libx264 -b:v 2M -c:a copy enc_out.mp4'

with open("ffmpeg_out.txt", 'w') as log:
    ffmpeg_cmd = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
    ffmpeg_stdout = ffmpeg_cmd.communicate()
    for i in range(len(ffmpeg_stdout) - 1):
        log.write(str(ffmpeg_stdout[i]) + "\n")

所以总的来说我想做一些类似于ffmpeg -hide_banner -i input.mp4 -c:v libx264 -b:v 2M -c:a copy enc_out.mp4 &> ffmpeg_out.txt的事情。所以目前在 ffmpeg_stdout 中我只有 (b'', None) 并且在执行脚本时会打印 stdout 和 stderr。

ffmpeg 可以自行将 stderr 重定向到一个文件,并且由于在大多数情况下它不会向 stdout 打印任何必要的内容,因此这将是一个有用的解决方法

my_env = os.environ.copy()
my_env["FFREPORT"] = "file=ffmpeg_out.txt:level=32"
subprocess.Popen(shlex.split(cmd), env=my_env)

oguzismail's answer 在这种特殊情况下可能更好,但仅作记录,一点也不难。

with open("ffmpeg_out.txt", 'w') as log:
    ffmpeg_cmd = subprocess.run(shlex.split(cmd), 
        stdout=log, stderr=log)

还要注意 preference for subprocess.run() over raw Popen.(可能还要添加 check=True。)