Ho esaminato una serie di domande ma non riesco ancora a capirlo. Sto usando PyQt e spero di eseguire ffmpeg -i file.mp4 file.avi
e ottenere l'output mentre scorre, così posso creare una barra di avanzamento.Ottenere l'output in tempo reale da ffmpeg da utilizzare nella barra di avanzamento (PyQt4, stdout)
Ho guardato queste domande: Can ffmpeg show a progress bar? catching stdout in realtime from subprocess
Sono in grado di vedere l'output di un comando rsync, utilizzando questo codice:
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()
Ma quando cambio il comando a ffmpeg -i file.mp4 file.avi
Non ricevo output. Sto indovinando questo ha qualcosa a che fare con il buffering stdout/uscita, ma io sono bloccato su come leggere la riga che assomiglia
frame= 51 fps= 27 q=31.0 Lsize= 769kB time=2.04 bitrate=3092.8kbits/s
quale ho potuto usare per capire i progressi.
Qualcuno mi può mostrare un esempio di come ottenere queste informazioni da ffmpeg in pitone, con o senza l'uso di PyQt (se possibile)
EDIT: ho finito per andare con il JLP di soluzione, il mio codice si presentava così:
#!/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
che dà questo output:
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
Perfetto!
il codice in ** ** di modifica non guardare a destra (e non funziona per me). .. Non penso che tu voglia catturare un pattern jolly e non fare nulla (devi solo catturare i pattern che ti interessano) e, cosa più importante, vuoi che il 'thread.close 'sia ** al di fuori ** del ciclo while piuttosto che chiamare la prima volta si cattura il tuo modello di interesse. Il codice di @jlp sembra più corretto e funziona per me una volta adattato all'output di ffmpeg. – Anentropic