subprocess not creating output file of ffmpeg command

痞子三分冷 提交于 2021-02-17 02:18:28

问题


I am trying to run an ffmpeg command that records my screen and creates an .mp4 file of the recording in python. The command works when I run it in my shell, but is not working when I am running it in a Python script using subprocess.

The issue is that when running it with subprocess, the output.mp4 file is not created.

Here is the command: 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

Here is the python code:

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')

Is there an additional configuration to add so that subprocess can write output files?


回答1:


subprocess.run returns an CompletedProcess object. You should assign that to a variable, and then print out all output and errors of the command (Because i think, ffmpeg gives an error and doesn't try to write the file at all, but you do not see that).
Additionally, you have to either set the keyword argument shell to True, or use shlex.split, else the command will not be formatted right. shlex.split is the preferred way, as you can read here:

Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names).

And you do not want to manually convert the string into a list of arguments !

And there is no need to stop ffmpeg from the outside (another reason why your file might not get written). Use the builtin command line option -t for that.

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:


Instead of using timeout you may use the -t option as posted here.

Add -t 00:00:05 argument, and remove the 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')

I think it's more elegant to use command argument than using timeout for terminating the process.




回答3:


On Windows, for hysterical reasons, you can pass in a single string without shell=True and it will work. For portable code, you need to either specify shell=True, or refactor the code to avoid it (which is generally recommended wherever feasible).

Note also that subprocess.run() has keyword arguments both for setting a timeout and for specifying the working directory for the subprocess.

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
    )

With check=True you will get an exception if the command fails, the timeout will raise an exception if the command times out, regardless of whether you have check=True.

Without more information about what failed, it's hard to specify how exactly to fix your problem; but with this, hopefully you should at least get enough information in error messages to guide you.



来源:https://stackoverflow.com/questions/66075915/subprocess-not-creating-output-file-of-ffmpeg-command

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!