FFmpeg stdout Ausgabe auswerten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Ernie1412
User
Beiträge: 160
Registriert: Freitag 10. Januar 2020, 20:38

wie kann ich die Ausgabe von FFmpeg als progressbar auswerten ?
ausgabe hab ich :

Code: Alles auswählen

frame=    1 fps=0.0 q=-1.0 size=       0kB time=00:00:00.00 bitrate=6095.2kbits/s speed=0.32x    \rframe=10733 fps=0.0 q=-1.0 size=   73984kB time=00:07:09.28 bitrate=1411.8kbits/s speed= 858x    \rframe=20050 fps=20037 q=-1.0 size=  145664kB time=00:13:21.96 bitrate=1488.0kbits/s speed= 801x    \rframe=25816 fps=16574 q=-1.0 size=  179968kB time=00:17:21.16 bitrate=1416.0kbits/s speed= 668x    \rframe=25816 fps=4010 q=-1.0 size=  179968kB time=00:17:21.17 bitrate=1416.0kbits/s speed= 162x    \rframe=34320 fps=4946 q=-1.0 size=  230144kB time=00:23:01.32 bitrate=1364.9kbits/s speed= 199x    \rframe=44060 fps=5917 q=-1.0 size=  289280kB time=00:29:30.92 bitrate=1338.2kbits/s speed= 238x    \rframe=56877 fps=7157 q=-1.0 size=  369664kB time=00:38:03.60 bitrate=1326.1kbits/s speed= 287x    \rframe=62015 fps=7342 q=-1.0 size=  402688kB time=00:41:37.08 bitrate=1321.1kbits/s speed= 296x    \rframe=73735 fps=8241 q=-1.0 size=  480000kB time=00:49:31.00 bitrate=1323.5kbits/s speed= 332x    \rframe=84017 fps=8855 q=-1.0 size=  551680kB time=00:56:22.28 bitrate=1336.2kbits/s speed= 356x    \rframe=87389 fps=8749 q=-1.0 size=  574720kB time=00:58:37.16 bitrate=1338.6kbits/s speed= 352x    \rframe=97858 fps=9326 q=-1.0 size=  651008kB time=01:05:50.12 bitrate=1350.1kbits/s speed= 376x    \rframe=104586 fps=9488 q=-1.0 size=  697856kB time=01:10:19.24 bitrate=1354.9kbits/s speed= 383x    \rframe=108710 fps=9434 q=-1.0 size=  726528kB time=01:13:04.20 bitrate=1357.5kbits/s speed= 380x    \rframe=119123 fps=9908 q=-1.0 size=  805376kB time=01:20:07.72 bitrate=1372.3kbits/s speed=400x    \rframe=122921 fps=9777 q=-1.0 size=  833280kB time=01:22:39.64 bitrate=1376.4kbits/s speed= 394x    \rframe=126101 fps=9683 q=-1.0 Lsize=  857704kB time=01:24:46.86 bitrate=1381.3kbits/s speed= 391x    \r\n'
mein script geht so:

Code: Alles auswählen

p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        output = ''
        for line in p.stdout:            
            line = line.decode(errors='replace')
line gibt mir als kompletten string das da oben mit rframe ... aus
wie kann ich daraus eine progressbar erstellen oder zu mindest das
"rframe=20050 fps=20037 q=-1.0 size= 145664kB time=00:13:21.96 bitrate=1488.0kbits/s speed= 801x "
das hier in einem Qlabel ausgibt ?
der gibts das ja als komplett aus und nicht als einzelne zeile die ich dann immer wieder ausgeben kann.
progressbar könnte ich mit time=00:17:21.17 erstellen. aber er gibt mir da oben als komplett line aus ;(
aussderem müsste ich ein refresh oder threading erstellen.
dafür weiss ich nicht wie ;(

Bitte keine Belehrungen sondern Hilfen. Danke !!!
Ernie1412
User
Beiträge: 160
Registriert: Freitag 10. Januar 2020, 20:38

Code: Alles auswählen

proc = subprocess.Popen(command, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
    for line in proc.stdout.readlines():
        if "frame=" in line:
            print(line)
damit kriege ich schonmal die einzelnen lines raus.
allerdings gibt er die nicht "live" sondern erste wenn der prozess fertig ist raus, jetzt müsste ich nur noch "live" ausgeben können
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

shell=True benutzt man nicht, wenn Du stdout und stderr umleitest, dann hast Du ein Problem, wenn einer der beiden Buffer vollläuft. Und Du sagst doch selbst, per readlines, dass erst alles gelesen werden soll, bevor die for-Schleife startest, warum wunderst Du Dich dann, dass nichts "live" ausgegeben wird?
Thants
User
Beiträge: 34
Registriert: Dienstag 1. Dezember 2020, 12:00

Ernie1412 hat geschrieben: Mittwoch 21. Juli 2021, 20:49 damit kriege ich schonmal die einzelnen lines raus.
allerdings gibt er die nicht "live" sondern erste wenn der prozess fertig ist raus, jetzt müsste ich nur noch "live" ausgeben können
Die Ausgabe von ffmpeg enthält keine einzelnen Zeilen, der Fortschritt wird ja immer in der gleichen Zeile angezeigt. In deiner Ausgabe von oben siehst du vor jedem "frame=" ein "\r", was für ein "Carriage Return" (Wagenrücklauf) steht, d.h. der Cursor springt in der gleichen Zeile einfach nur zurück an den Anfang und weitere Ausgaben überschreiben den Text in der Zeile. Erst das "\n" am Ende steht für ein "Newline" (Zeilenvorschub), was in eine neue Zeile springt. Es gibt also nur eine einzige Zeile und die enthält den gesamten Status, es bringt also nichts, die Ausgabe "zeilenweise" einzulesen.

Du musst stattdessen die Ausgabe häppchenweise lesen (z.B. read(50) um immer höchstens 50 Byte zu lesen) und kannst davon die Information, die du anzeigen möchtest extrahieren (du musst dabei aufpassen, dass nicht genau die Info, die du brauchst, zerhackt wurde. Falls das der Fall ist, musst du eben auf den nächsten Happen zum Vervollständigen warten).

Und du hattest schon den richtigen Riecher, das sollte in einem separaten Thread gemacht werden, andernfalls blockierst du dein eigenes Programm (ein evtl. vorhandener "Abbrechen"-Button würde also z.B. nicht funktionieren).
Antworten