【问题标题】:subprocess not creating output file of ffmpeg command子进程未创建 ffmpeg 命令的输出文件
【发布时间】:2021-05-10 12:59:34
【问题描述】:

我正在尝试运行一个 ffmpeg 命令来记录我的屏幕并在 python 中创建一个记录的 .mp4 文件。该命令在我的 shell 中运行时有效,但在我使用子进程在 Python 脚本中运行时无效。

问题是使用子进程运行时,没有创建 output.mp4 文件。

命令如下: timeout 10 ffmpeg -video_size 1920x1080 -framerate 60 -f x11grab -i :0.0+0,0 -f alsa -ac 2 -i pulse -acodec aac -strict experimental output.mp4

这是python代码:

os.chdir('/home/user/Desktop/myProject/')

subprocess.run('timeout 5 ffmpeg -video_size 1920x1080 -framerate 60 -f x11grab -i :0.0+0,0 -f alsa -ac 2 -i pulse -acodec aac -strict experimental out.mp4')

是否需要添加额外的配置以便子进程可以写入输出文件?

【问题讨论】:

  • 工作示例中的timeout 与失败示例中的不同;如果命令花费的时间超过 5 秒但不到 10 秒,这就是解释。
  • 在您的示例中,ffmpeg 完全负责编写输出文件。您可以轻松地将 stdout 参数添加到 subprocess 以写入您选择的文件句柄,但这不是问题所在。

标签: python ffmpeg subprocess


【解决方案1】:

subprocess.run 返回一个CompletedProcess 对象。您应该将其分配给一个变量,然后打印出命令的所有输出和错误(因为我认为,ffmpeg 给出了一个错误并且根本不尝试写入文件,但您没有看到)。
此外,您必须将关键字参数shell 设置为True,或者使用shlex.split,否则该命令的格式将不正确。 shlex.split 是首选方式,您可以阅读here

提供一系列参数通常是首选,因为它允许 该模块负责任何需要的转义和引用 参数(例如,允许文件名中有空格)。

而且您不想手动将字符串转换为参数列表!

并且没有必要从外部停止 ffmpeg(您的文件可能不会被写入的另一个原因)。为此使用内置命令行option -t

import shlex
import subprocess
import os

os.chdir('/home/user/Desktop/myProject/')

p = subprocess.run(shlex.split("ffmpeg -video_size 1920x1080 -framerate 60 -f x11grab -i :0.0+0,0 -f alsa -ac 2 -i pulse -acodec aac -strict experimental -t 00:00:05 out.mp4"), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print(p.stdout)

【讨论】:

    【解决方案2】:

    您可以使用-t 选项,而不是使用timeout 发布的here

    添加-t 00:00:05 参数,并删除timeout

    subprocess.run('ffmpeg -video_size 1920x1080 -framerate 60 -f x11grab -i :0.0+0,0 -f alsa -ac 2 -i pulse -acodec aac -strict experimental -t 00:00:05 out.mp4')
    

    我认为使用命令参数比使用timeout 终止进程更优雅。

    【讨论】:

      【解决方案3】:

      在 Windows 上,出于歇斯底里的原因,您可以传入一个不带shell=True 的字符串,它会起作用。对于可移植代码,您需要指定shell=True,或重构代码以避免它(即generally recommended wherever feasible)。

      另请注意,subprocess.run() 具有关键字参数,用于设置超时和指定子进程的工作目录。

      subprocess.run(
          ['ffmpeg', '-video_size', '1920x1080', '-framerate', '60',
                     '-f', 'x11grab', '-i', ':0.0+0,0', '-f', 'alsa',
                     '-ac', '2', '-i', 'pulse', '-acodec', 'aac',
                     '-strict', 'experimental', 'out.mp4'],
          cwd='/home/user/Desktop/myProject/',   # current working directory
          timeout=5,                             # timeout
          check=True                             # check for errors
          )
      

      使用check=True,如果命令失败,您将得到异常,如果命令超时,超时将引发异常,无论您是否有check=True

      如果没有更多关于失败原因的信息,就很难具体说明如何解决您的问题;但是有了这个,希望您至少应该在错误消息中获得足够的信息来指导您。

      【讨论】:

        猜你喜欢
        • 2016-02-24
        • 2021-12-10
        • 2014-11-15
        • 1970-01-01
        • 2022-01-22
        • 2013-08-27
        • 2011-09-30
        • 1970-01-01
        相关资源
        最近更新 更多