Python Subprocess + Mencoder не работает, та же команда работает в терминале
-
25-09-2019 - |
Вопрос
У меня проблема с использованием 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
Вы можете скачать видео отсюда. Отказ Я вполне уверен, что видео не являются пробиртом из-за того, что он работает от терминала.
Решение
Проблема вот что 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
Другой вариант, который позволяет читать выходную строку, - это перенаправить STDERR в STDOUT, а затем прочитать только STDOUT, (не используйте ReadLines (), поскольку он блокирует, пока все строки не будут читаться):
pMerge = subprocess.Popen(mp4merge, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in pMerge.stdout:
print line,
Это перенаправляет STDERR на STDOUT, чтобы ваш буфер не заполнил.