Python subprocess + mencoder不工作,相同命令在终端正常

0 投票
1 回答
669 浏览
提问于 2025-04-16 02:19

我在用mencoder(版本SVN-r30531-4.2.1)通过Python(版本2.6.1)来处理一个子进程时遇到了问题。我想把两个完全相同大小、编码等的mp4文件合并在一起。这两个文件都没有声音。我用来测试的代码是:

import subprocess

mp4merge = [ "mencoder", "in1.mp4", "in2.mp4", "-ovc", "copy", "-oac", "copy", "-of", "lavf", "-o", "out.mp4" ]

try:

    pMerge = subprocess.Popen(mp4merge, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    while pMerge.poll() == None:

        for l in pMerge.stderr.readlines():
            print l

    if pMerge.poll() is not None:

        print "Complete"

except subprocess.CalledProcessError:
    print "fail"

但是这个代码不管用,它会一直卡在那里不动。不过,当我在终端(OS X 10.6.4)里运行完全相同的命令时,它是可以正常工作的。这个命令是:

mencoder in1.mp4 in2.mp4 -ovc copy -oac copy -of lavf -o out.mp4

你可以从这里下载视频。我很确定视频本身没有问题,因为在终端里运行是可以成功的。

1 个回答

2

这里的问题是,pMerge.stderr.readlines() 会一直卡在那里,直到进程结束。它会在继续之前读取所有的行。

因为 mencoder 会向标准输出(stdout)写入很多内容,所以标准输出的缓冲区被填满了,mencoder 在等待这个缓冲区清空后才能继续。因此,进程就永远不会结束。

这里有一种方法可以做到同样的事情,但不会卡住:

pMerge = subprocess.Popen(mp4merge, stdout=subprocess.PIPE,
    stderr=subprocess.PIPE)
stdout, stderr = pMerge.communicate()
print stdout
print stderr

另一种选择是将标准错误输出(stderr)重定向到标准输出(stdout),然后只读取标准输出(不要使用 readlines(),因为它会在读取所有行之前卡住):

pMerge = subprocess.Popen(mp4merge, stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT)
for line in pMerge.stdout:
    print line,

这样做会将标准错误输出重定向到标准输出,这样你的缓冲区就不会被填满。

撰写回答