L'obtention de la sortie en temps réel à partir de ffmpeg pour être utilisé dans la barre de progression (PyQt4, stdout)

J'ai regardé un certain nombre de questions, mais ne peut toujours pas tout à fait le comprendre. Je suis l'aide de PyQt, et j'espère pour exécuter ffmpeg -i file.mp4 file.avi et obtenir la sortie en elle diffuse donc je peux créer une barre de progression.

J'ai regardé ces questions:
Peut ffmpeg afficher une barre de progression?
la capture de la sortie standard stdout en temps réel à partir de sous-processus

Je suis en mesure de voir la sortie d'une commande rsync, à l'aide de ce code:

import subprocess, time, os, sys

cmd = "rsync -vaz -P source/dest/"
p, line = True, 'start'


p = subprocess.Popen(cmd,
                     shell=True,
                     bufsize=64,
                     stdin=subprocess.PIPE,
                     stderr=subprocess.PIPE,
                     stdout=subprocess.PIPE)

for line in p.stdout:
    print("OUTPUT>>> " + str(line.rstrip()))
    p.stdout.flush()

Mais quand j'ai changer la commande à ffmpeg -i file.mp4 file.avi je ne reçois aucune sortie. Je suppose que cela a quelque chose à voir avec stdout /tampon de sortie, mais je suis coincé à la façon de lire la ligne qui ressemble à

frame=   51 fps= 27 q=31.0 Lsize=     769kB time=2.04 bitrate=3092.8kbits/s

Que je pourrais utiliser pour déterminer les progrès accomplis.

Quelqu'un peut-il me montrer un exemple de la façon d'obtenir cette information de ffmpeg en python, avec ou sans l'utilisation de PyQt (si possible)


EDIT:
J'ai fini par aller avec pam, c'est la solution, mon code ressemble à ceci:

#!/usr/bin/python
import pexpect

cmd = 'ffmpeg -i file.MTS file.avi'
thread = pexpect.spawn(cmd)
print "started %s" % cmd
cpl = thread.compile_pattern_list([
    pexpect.EOF,
    "frame= *\d+",
    '(.+)'
])
while True:
    i = thread.expect_list(cpl, timeout=None)
    if i == 0: # EOF
        print "the sub process exited"
        break
    elif i == 1:
        frame_number = thread.match.group(0)
        print frame_number
        thread.close
    elif i == 2:
        #unknown_line = thread.match.group(0)
        #print unknown_line
        pass

Qui donne ce résultat:

started ffmpeg -i file.MTS file.avi
frame=   13
frame=   31
frame=   48
frame=   64
frame=   80
frame=   97
frame=  115
frame=  133
frame=  152
frame=  170
frame=  188
frame=  205
frame=  220
frame=  226
the sub process exited

Parfait!

  • votre code dans le modifier n'est pas bon (et ne fonctionne pas pour moi)... je ne pense pas que vous voulez prendre un modèle générique et ne rien faire (vous ne devez attraper les modèles que vous vous souciez d') et, plus important encore, vous voulez les thread.close être hors le tout en boucle plutôt que de appelé la première fois que vous reprenez votre modèle d'intérêt. @pam 's code semble plus correct et fonctionne pour moi une fois adapté pour les formats de sortie.
  • En cas de Python3, il convient de: frame_number = thread.match.group(0).decode('utf-8')
InformationsquelleAutor Jason O'Neil | 2011-10-03