Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 调用ffmpeg仅在后台终止脚本_Python_Ffmpeg_Subprocess - Fatal编程技术网

Python 调用ffmpeg仅在后台终止脚本

Python 调用ffmpeg仅在后台终止脚本,python,ffmpeg,subprocess,Python,Ffmpeg,Subprocess,我有一个python脚本,它通过子进程调用ffmpeg来执行一些mp3操作。它在前台可以正常工作,但如果我在后台运行它,它会得到ffmpeg命令,而ffmpeg命令本身也会将其配置转储到stderr中。此时,一切都停止,父任务报告为已停止,而不会在任何地方引发异常。我尝试了其他一些简单的命令来代替ffmpeg,它们通常在前台或后台执行 这是问题的最小示例: import subprocess inf = "3HTOSD.mp3" outf = "out.mp3" args = [ "f

我有一个python脚本,它通过子进程调用ffmpeg来执行一些mp3操作。它在前台可以正常工作,但如果我在后台运行它,它会得到ffmpeg命令,而ffmpeg命令本身也会将其配置转储到stderr中。此时,一切都停止,父任务报告为已停止,而不会在任何地方引发异常。我尝试了其他一些简单的命令来代替ffmpeg,它们通常在前台或后台执行

这是问题的最小示例:

import subprocess

inf = "3HTOSD.mp3"
outf = "out.mp3"

args = [    "ffmpeg",
            "-y",
            "-i",   inf,
            "-ss",  "0",
            "-t",   "20",
            outf
        ]

print "About to do"

result = subprocess.call(args)

print "Done"
我真的不明白为什么或者如何包装的进程会导致父进程终止,而至少不会引发错误,也不知道它是如何只在如此特殊的情况下发生的。发生了什么事


此外,我知道ffmpeg并不是最好的软件包,但我正在与使用ffmpeg编译的软件包进行接口,因此再次使用它似乎是明智的。

来自python/subprocess/call文档:

等待命令完成,然后返回returncode属性

因此,只要您调用的进程没有退出,您的程序就不会继续

您应该设置一个
Popen
进程对象,将其标准输出和错误放在不同的缓冲区/流中,当出现错误时,终止进程

也许像这样的方法有用:

proc = subprocess.Popen(args, stderr = subprocess.PIPE) # puts stderr into a new stream
while proc.poll() is None:
     try:
        err = proc.stderr.read()
     except: continue
     else:
        if err:
            proc.terminate()
            break
例如,它可能与使用
parent.py
有关:

from subprocess import check_call

check_call(["python", "-c", "import sys; sys.stdin.readline()"])
如果在bash中作为后台作业运行,则应重现问题:“parent.py脚本显示为stopped”:

$ python parent.py &
[1] 28052
$ jobs
[1]+  Stopped                 python parent.py
如果是父母

解决方案是重定向输入:

import os
from subprocess import check_call
try:
    from subprocess import DEVNULL
except ImportError: # Python 2
    DEVNULL = open(os.devnull, 'r+b', 0)

check_call(["python", "-c", "import sys; sys.stdin.readline()"], stdin=DEVNULL)
如果您不需要查看ffmpeg标准输出/标准输出;您还可以将它们重定向到
/dev/null

check_call(ffmpeg_cmd, stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT)
我喜欢使用模块。在我看来,它更容易使用

import commands
cmd = "ffmpeg -y -i %s -ss 0 -t 20 %s 2>&1" % (inf, outf)
status, output = commands.getstatusoutput(cmd)
if status != 0:
    raise Exception(output)
作为旁注,有时路径可能是一个问题,您可能希望使用ffmpeg二进制文件的绝对路径

matt@goliath:~$ which ffmpeg
/opt/local/bin/ffmpeg

这谢谢你的解释,整个“等待stdin”的事情对我来说是未知的。要实现的最简单的解决方案是将subprocess.PIPE附加到调用的stdin。@TimD:除非在进程运行时读取/写入/关闭相应的管道,否则不要使用PIPE,即不要将其与
subprocess.call()一起使用
函数,即使它碰巧与ffmpeg可执行文件的一些参数集一起工作。您真的读过我的问题吗?你根本没有回答我的问题。