2010-08-04 1 views
0

У меня возникла проблема с использованием mencoder (SVN-r30531-4.2.1) через подпроцесс python (2.6.1). Я пытаюсь присоединиться к двум файлам mp4, которые имеют одинаковый размер, кодек и т. Д. Оба не имеют звука. Код, который я использую для тестирования:Подпроцесс Python + mencoder не работает, эта же команда работает в терминале

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" 

И он не работает, он просто висит бесконечно. Однако, когда я запускаю ту же самую команду через Terminal (OS X 10.6.4), она работает. Команда:

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

Вы можете скачать видео from here. Я вполне уверен, что видео не являются пробкой из-за того, что она работает с Терминалом.

ответ

2

Проблема в том, что pMerge.stderr.readlines() блокирует навсегда до завершения процесса. Он читает все строк перед продолжением.

Поскольку mencoder много записывает в stdout, буфер stdout заполняется, и mencoder ждет его, пока он не будет удален. Таким образом, процесс никогда не заканчивается.

Вот способ сделать то же самое, что не будет висеть:

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

Другим вариант, который позволяет читать вывод построчно-линией для перенаправления потока ошибок на стандартный вывод, а затем только для чтения стандартный вывод (не используйте readlines(), так как он блокирует, пока все строки читаются):

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

Это перенаправляет поток ошибок на стандартный вывод, чтобы ваш буфер не заполнится.

+0

Спасибо! Это и вызывало проблему. – betamax