Python + sous-processus mencoder ne fonctionne pas, les mêmes travaux de commande dans le terminal

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

Question

J'ai un problème en utilisant mencoder (SVN-r30531-4.2.1) à travers un python (2.6.1) sous-processus. Je suis en train de joindre deux fichiers mp4 qui sont exactement la même taille, codec, etc. Tous les deux ont pas d'audio. Le code que je utilise pour tester est:

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"

Et cela ne fonctionne pas, il se bloque juste indéfiniment. Cependant, quand je lance exactement la même commande par le terminal (OS X 10.6.4), il fonctionne. La commande est:

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

Vous pouvez télécharger les vidéos d'ici . Je suis tout à fait confiant que les vidéos ne sont pas le gros problème en raison du fait que cela fonctionne à partir du terminal.

Était-ce utile?

La solution

Le problème ici est que les blocs de pMerge.stderr.readlines() pour toujours jusqu'à ce que le processus est terminé. Il lit toutes les lignes avant de continuer.

Depuis mencoder écrit beaucoup à la sortie standard, le tampon de sortie standard est rempli et mencoder attend à vide avant de pouvoir continuer. Ainsi, le processus ne se termine jamais.

Voici une façon de faire la même chose, qui ne se bloque pas:

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

Une autre option qui vous permet de lire la ligne par ligne de sortie est de rediriger stderr vers stdout, puis lecture seule stdout, (ne pas utiliser readlines () car il bloque jusqu'à ce que toutes les lignes sont lues):

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

stderr vers stdout de sorte que votre tampon ne remplira pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top