2010-08-04 22 views
0

J'ai un problème avec mencoder (SVN-r30531-4.2.1) via un sous-processus python (2.6.1). J'essaye de joindre deux fichiers mp4 qui sont exactement la même taille, codec, etc. Les deux n'ont aucun audio. Le code que j'utilise pour tester est:Sous-processus Python + mencoder ne fonctionne pas, la même commande fonctionne dans le terminal

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 indéfiniment. Cependant, lorsque j'exécute exactement la même commande via Terminal (OS X 10.6.4) cela 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 from here. Je suis assez confiant que les vidéos ne sont pas le problème à cause du fait que cela fonctionne à partir de Terminal.

Répondre

2

Le problème ici est que pMerge.stderr.readlines() bloque pour toujours jusqu'à la fin du processus. Il lit toutes les lignes avant de continuer.

Depuis que mencoder écrit beaucoup dans la sortie standard, le tampon stdout est rempli et mencoder attend qu'il se vide avant de pouvoir continuer. Donc, le processus ne se termine jamais.

est ici 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, 

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

+0

Merci! C'est ce qui causait le problème. – betamax