我在python中有一个脚本调用子进程来编码
下面的视频文件 args1 = ["ffmpeg", "-i", "my niece.mkv"]
args2 = MyConfig.DefaultFFMPEGParam + " " + crf + " " + output + ""
args = args2.split(' ')
args1.extend(args)
print "EncodeReal : " + uniqueno + " : Try Encode"
print " ".join(args1)
subprocess.call(" ".join(args1), shell=True)
print语句成功打印出以下命令
ffmpeg -i "/home/Downloads/my niece.mkv" -tune animation -keyint_min 12 -sc_threshold 45 -bf 8 -b_strategy 2 -refs 10 -qmin 10 -qmax 51 -qcomp 0.6 -direct-pred auto -me_range 24 -me_method umh -subq 9 -trellis 2 -vcodec libx264 -crf 28.0 /home/Downloads/output.mkv
如果在脚本中运行此命令它运行良好,但如果它由subprocess.call运行,则会遇到
ffmpeg version git-2013-12-30-61d43a2 Copyright (c) 2000-2013 the FFmpeg developers
built on Dec 30 2013 11:02:28 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-4)
configuration: --prefix=/root/ffmpeg_build --extra-cflags=-I/root/ffmpeg_build/include --extra-ldflags=-L/root/ffmpeg_build/lib --bindir=/root/bin --extra-libs=-ldl --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libx264
libavutil 52. 59.100 / 52. 59.100
libavcodec 55. 47.100 / 55. 47.100
libavformat 55. 22.101 / 55. 22.101
libavdevice 55. 5.102 / 55. 5.102
libavfilter 4. 0.103 / 4. 0.103
libswscale 2. 5.101 / 2. 5.101
libswresample 0. 17.104 / 0. 17.104
libpostproc 52. 3.100 / 52. 3.100
[1]+ Stopped python MonitorService.py
它自行停止!有什么原因吗?
答案 0 :(得分:1)
您的代码示例无法生成您提供的打印字符串。
假设您的代码与您在示例中显示的一样,那么Bakuriu已经指出输入文件名周围的引号将丢失,并且ffmpeg将无法正确处理文件名中的嵌入空间。我还注意到输入文件的路径没有显示在你的代码中,这将是你的python应用程序没有用完该目录的问题。
尝试按如下方式修改代码:
args1 = ["ffmpeg", "-i", '"my niece.mkv"']
请注意添加单引号以确保文件名包含在双引号中。
答案 1 :(得分:1)
我完全同意@RogueThinking。您的问题是"my niece.mkv"
中的空格。解决此问题的另一种方法是将subprocess.call
与可迭代的参数列表一起使用,而不是连接完整的字符串。这些参数将被正确传递,而不必担心引用转义。
从documentation for subprocess(强调添加):
所有调用都需要args,并且应该是字符串或序列 程序参数。 通常提供一系列参数 首选,因为它允许模块处理任何所需的 转义和引用参数(例如,允许文件中的空格 名称)即可。如果传递单个字符串,则任何一个shell都必须为True(请参阅 或者字符串必须简单地命名要执行的程序 没有指定任何参数。
例如,使用列表的完整工作版本如下所示:
import subprocess
def run():
DefaultFFMPEGParam = "-tune animation -keyint_min 12 -sc_threshold 45 -bf 8 -b_strategy 2 -refs 10 -qmin 10 -qmax 51 -qcomp 0.6 -direct-pred auto -me_range 24 -me_method umh -subq 9 -trellis 2 -vcodec libx264" \
.split(' ')
crf = ['-crf', '28.0']
output = "output2.mkv"
# list concatenation
args1 = ["ffmpeg", "-i", "my niece.mkv"] + DefaultFFMPEGParam + crf + [output,]
print args1
# prints:
#
# ['ffmpeg', '-i', 'my niece.mkv', '-tune', 'animation', '-keyint_min', '12',
# '-sc_threshold', '45', '-bf', '8', '-b_strategy', '2', '-refs', '10', '-qmin',
# '10', '-qmax', '51', '-qcomp', '0.6', '-direct-pred', 'auto', '-me_range', '24',
# '-me_method', 'umh', '-subq', '9', '-trellis', '2', '-vcodec', 'libx264',
# '-crf', '28.0',
# 'output2.mkv']
subprocess.call(args1)
run()
请注意,在这种情况下,我可以省略shell=True
,并且呼叫仍然可以正常执行。