python子流程调用终止而不通知

2024-04-26 20:35:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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

如果在脚本中运行这个命令,它工作得很好,但是如果子流程调用,它遇到

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

它自己停下来!有什么原因吗?你知道吗


Tags: build脚本outputenablemyargsrootextra
2条回答

您提供的打印字符串不能由您的代码示例生成。你知道吗

假设您的代码如示例中所示,那么正如Bakuriu所指出的,输入文件名周围的引号将丢失,ffmpeg将无法正确处理文件名中的嵌入空间。我还注意到,输入文件的路径没有显示在代码中,这将是一个问题,因为python应用程序没有在该目录中运行。你知道吗

尝试按以下方式修改代码:

args1 = ["ffmpeg", "-i", '"my niece.mkv"']

请注意添加了单引号,以确保文件名用双引号括起来。你知道吗

我完全同意@RogueThinking。你的问题是"my niece.mkv"中的空格。解决这个问题的另一种方法是将subprocess.call与可iterable参数列表一起使用,而不是将完整的字符串串联起来。参数将被正确地传递,而不必担心引用转义。你知道吗

documentation for subprocess(加上强调):

args is required for all calls and should be a string, or a sequence of program arguments. 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). If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.

例如,使用列表的完整工作版本如下所示:

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,调用仍然正确执行。你知道吗

相关问题 更多 >