Python Subprocess + Mencoder не работает, та же команда работает в терминале

StackOverflow https://stackoverflow.com/questions/3407742

Вопрос

У меня проблема с использованием 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, чтобы ваш буфер не заполнил.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top