I've looked at a number of questions but still can't quite figure this out. I'm using PyQt, and am hoping to run ffmpeg -i file.mp4 file.avi and get the output as it streams so I can create a progress bar.
I've looked at these questions: Can ffmpeg show a progress bar? catching stdout in realtime from subprocess
I'm able to see the output of a rsync command, using this 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() But when I change the command to ffmpeg -i file.mp4 file.avi I receive no output. I'm guessing this has something to do with stdout / output buffering, but I'm stuck as to how to read the line that looks like
frame= 51 fps= 27 q=31.0 Lsize= 769kB time=2.04 bitrate=3092.8kbits/s Which I could use to figure out progress.
Can someone show me an example of how to get this info from ffmpeg into python, with or without the use of PyQt (if possible)
EDIT: I ended up going with jlp's solution, my code looked like this:
#!/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 Which gives this 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 Perfect!

thread.closeto be outside the while loop rather than called the first time you catch your pattern of interest. @jlp 's code seems more correct and works for me once adapted to ffmpeg output.frame_number = thread.match.group(0).decode('utf-8')thread.close()if thread.exitstatus:print(thread.before)else:print('Ok')