Python 子进程调用 ffmpeg(命令行)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25955322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:52:06  来源:igfitidea点击:

subprocess call ffmpeg (command line)

pythoncommand-lineffmpegsubprocess

提问by user3295674

I have been incorporating subprocess calls in my program. I have had no issues with subprocess calls for other commands, but I am having trouble getting the command line input

我一直在我的程序中加入子进程调用。我对其他命令的子进程调用没有任何问题,但在获取命令行输入时遇到问题

ffmpeg -r 10 -i frame%03d.png -r ntsc movie.mpg

To work inside a subprocess.call()

在 subprocess.call() 中工作

I tried the following with no success:

我尝试了以下但没有成功:

subprocess.call('ffmpeg -r 10 -i %s frame%03.d.png - r ntsc movie.mpg')

Any thoughts? Do I separate out different commands, do I specify string, integer etc. with %s, %d?

有什么想法吗?难道我分离出不同的命令,我指定字符串,整数等用%s%d

采纳答案by user3295674

I found this alternative, simple, answer to also work.

我发现这个替代的,简单的,答案也有效。

subprocess.call('ffmpeg -r 10 -i frame%03d.png -r ntsc '+str(out_movie), shell=True)

回答by tdelaney

When you use subprocess, your command must either be a string that looks exactly like what you would type on the command line (and you set shell=True), or a list where each command is an item in the list (and you take the default shell=False). In either case, you have to deal with the variable part of the string. For instance, the operating system has no idea what "%03d" is, you have to fill it in.

当您使用 subprocess 时,您的命令必须是一个与您在命令行上键入的内容完全相同的字符串(并且您设置了 shell=True),或者是一个列表,其中每个命令都是列表中的一个项目(并且您将默认外壳=假)。无论哪种情况,您都必须处理字符串的可变部分。例如,操作系统不知道“%03d”是什么,你必须填写它。

I can't tell from your question exactly what the parameters are, but lets assume you want to convert frame 3, it would look something like this in a string:

我无法从你的问题中确切地说出参数是什么,但假设你想转换第 3 帧,它在字符串中看起来像这样:

my_frame = 3
subprocess.call(
    'ffmpeg -r 10 -i frame%03d.png -r ntsc movie%03d.mpg' % (my_frame, my_frame),
    shell=True)

Its kinda subtle in this example, but that's risky. Suppose these things were in a directory whose name name had spaces (e.g., ./My Movies/Scary Movie). The shell would be confused by those spaces.

在这个例子中它有点微妙,但这是有风险的。假设这些东西在一个名字有空格的目录中(例如,./My Movies/Scary Movie)。外壳会被这些空间混淆。

So, you can put it into a list and avoid the problem

所以,你可以把它放在一个列表中,避免这个问题

my_frame = 3
subprocess.call(['ffmpeg', '-r', '10', '-i', 'frame%03d.png' % my_frame,
    ['-r',  'ntsc', 'movie%03d.mpg' % my_frame])

More typing, but safer.

更多打字,但更安全。

回答by PM 2Ring

'ffmpeg -r 10 -i frame%03d.png -r ntsc movie.mpg'should be fine. OTOH, If you don't need the power of frame%03d.png, frame*.pngis a bit simpler.

'ffmpeg -r 10 -i frame%03d.png -r ntsc movie.mpg'应该没事。OTOH,如果你不需要的功率frame%03d.pngframe*.png是有点简单。

If you want to "see the syntax for it if I replace 'movie.mpg' with a variable name", it looks something like this:

如果你想“如果我用变量名替换 'movie.mpg' 来查看它的语法”,它看起来像这样:

cmd = 'ffmpeg -r 10 -i "frame%%03d.png" -r ntsc "%s"' % moviename

cmd = 'ffmpeg -r 10 -i "frame%%03d.png" -r ntsc "%s"' % moviename

We need to escape the %with an extra %to hide it from Python's % substitution machinery. I've also added double quotes ", to cope with the issues that tdelaney mentioned.

我们需要%用一个额外的方法来逃避%Python 的 % 替换机制。我还添加了双引号",以解决 tdelaney 提到的问题。

回答by jfs

import shlex
import pipes
from subprocess import check_call

command = 'ffmpeg -r 10 -i frame%03d.png -r ntsc ' + pipes.quote(out_movie)
check_call(shlex.split(command))