10
votes

FFMPEG et Pythons Subprocess

J'essaie d'écrire une interface graphique pour ffmpeg . J'utilise Pythons Subprocess pour créer un processus FFMPEG pour chaque conversion que je souhaite. Cela fonctionne bien, mais j'aimerais aussi un moyen d'obtenir les progrès de la conversion, qu'il soit échoué ou non, etc. Je pensais que je pouvais le faire en accédant à la rue du processus, comme:

appelant sous-processus. Popen () xxx

et lecture stdout : xxx

Ceci fonctionne Mais le statut de FFMPEG ne montre pas. Je suppose que cela a quelque chose à voir avec la façon dont FFMPEG les rafraîchit. Y a-t-il un moyen d'y accéder?


0 commentaires

6 Réponses :


-1
votes

FFMPEG:

FFMPEG Sortie Tout le texte d'état (ce que vous voyez lorsque vous l'exécutez manuellement sur la ligne de commande) sur l'interface STDERR. Afin de capturer la sortie de FFMPEG, vous devez regarder l'interface STDRERR - ou la rediriger comme l'exemple.

Vérifiez la sortie sur STDERR:

Voici une autre façon d'essayer de lire de plus en plus de STDRER, au lieu de la rediriger lorsque vous appelez Popen

La classe popen à Python a un objet de fichier appelé stardr, vous y accéderiez de la même manière que vous accédez à STDOUT. Je pense que votre boucle regarderait quelque chose comme ceci: xxx

Disclaimer: Je n'ai pas testé cela dans Python, mais j'ai fait une application comparable à l'aide de Java.


2 commentaires

Gorgapor, es-tu sûr qu'il est?


Oui, le STDRERR est redirigé dans l'extrait de code sur la ligne avec subprocess.popen - bien sûr, il peut être coupé si vous n'utilisez pas la barre de défilement sous l'extrait de code ...



8
votes

J'ai souvent remarqué des problèmes de lecture de la sortie standard (ou même une erreur standard!) Avec sous-processus, en raison de problèmes tamponnants difficiles à vaincre. Ma solution préférée, lorsque j'ai besoin de lire une telle STDOUT / STDERR de la sous-processus, consiste à basculer vers l'utilisation, au lieu de sous-processus , peexpect (ou sur Windows, WEXPECT ).


1 commentaires

Vos deux liens sont morts, veuillez les réparer.



3
votes

Je pense que vous ne pouvez pas utiliser readline car FFMPEG n'imprime jamais une ligne, l'état est mis à jour en écrivant \ r (retour carrige), puis écrivez à nouveau la ligne.

size=      68kB time=0.39 bitrate=1412.1kbits/s    \rsize=    2786kB time=16.17 bitrate=1411.2kbits/s    \rsize=    5472kB time=31.76 bitrate=1411.2kbits/s    \r\n


1 commentaires

Vous pouvez faire en lecture ligne, mais vous obtenez seulement la version finale de cette ligne une fois qu'elle est finie ...



2
votes

Étant donné que FFMPEG écrit les données non éclairées sur STDERR, vous devez définir le descripteur de fichier STDRERR sur le non-blocage à l'aide de FCNTL.

    while True:
        readx = select.select([pipe.stderr.fileno()], [], [])[0]
        if readx:
            chunk = pipe.stderr.read()


2 commentaires

Je ne sais pas si c'est toujours vrai ... Je reçois une production progressive faisant une lecture en lecture sur STDERR dans une construction actuelle de FFMPEG sur PY2.7: pour la ligne dans proc.Sderr: impression Line ProC.Sderr. flush ()


Ah non, bien, en quelque sorte. Je ne reçois pas la sortie progressive du cadre image = xxx Sortie d'état lors de l'encodage (puisqu'il s'agit d'une ligne qui est mise à jour à plusieurs reprises) mais je vois les lignes de métadonnées alors qu'il bloque jusqu'à ce que le codage soit terminé, ce qui ne montre que le Dernière mise à jour de statut, il affiche les lignes de résumé restantes.



8
votes

Simplement ajouter, Universal_newlines = true à votre sous-processus.Popen ligne.

frame= 1900 fps=453 q=18.6 Lsize=    3473kB time=00:01:16.08 bitrate= 373.9kbits/s


1 commentaires

Solution intéressante, mais ajoutez quelques problèmes tampons avec Popen. Ne fonctionnera pas tout droit hors de la boîte si vous recherchez une surveillance de codage en direct.



-2
votes
ffmpegCommand='''
ffmpeg
-f lavfi
-i anullsrc=channel_layout=1c:sample_rate=11025
-rtsp_transport tcp
-rtsp_transport udp
-rtsp_transport http
-thread_queue_size 32000
-i rtsp://xxx.xxx.xxx.xxx:554/user=admin&password=xxx&channel=1&stream=1.sdp?real_stream
-reconnect 1
-reconnect_at_eof 1
-reconnect_streamed 1
-reconnect_delay_max 4294
-tune zerolatency
-c:v copy
-c:a aac
-bufsize 6000k
-f flv rtmp://a.rtmp.youtube.com/live2/xxx-xxx-xxx-xxx'''
cmd=ffmpegCommand.split()
# "universal newline support" This will cause to interpret \n, \r\n and \r     equally, each as a newline.

p = subprocess.Popen(cmd, stderr=subprocess.PIPE, universal_newlines=True)
while True:    
        print(p.stderr.readline().rstrip('\r\n'))

0 commentaires