I have a snippet of code that runs a video conversion using ffmpeg
.
I read the output to analyze it later in the application, and also want to print it to console, for user feedback.
So I have
p = Popen(['ffmpeg', *args], stderr=STDOUT, stdout=PIPE)
while True:
line = p.stdout.readline()
if not line:
break
print(line.decode('utf-8'), end='')
p.wait()
if p.returncode == 0:
pass
Which works, somewhat. It prints the initial output of the ffmpeg command, as those are simple print statements.
But once the conversion starts, all the output is updated on one line, presumably using some reset character to move the cursor position back to the start of the line.
Is there a way to continue to print that output?
Edit:
p = subprocess.Popen(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, universal_newlines=True)
with p.stdout:
for line in iter(p.stdout.readline, None):
if not line:
break
if line.startswith('frame'):
print(f'\033[2K{line.strip()}\r', end='')
else:
print(line, end='')
This includes the cursor return, and clears the current line before printing to it again. And still prints the part I want on the same line, like it normally does.
Here's an old code snippet of mine, which includes the universal_newlines=True
option and then iterates over the stdout.
#!/usr/bin/env python3
from subprocess import Popen, PIPE, STDOUT
orig_file='V1.mp4'
new_file='V1.mkv'
command_line='ffmpeg -y -i '+orig_file+' '+new_file # -y Overwrite output files without asking
comm = Popen(command_line, shell=True, stdout=PIPE, stderr=STDOUT, universal_newlines=True)
with comm.stdout:
for line in iter(comm.stdout.readline, b''):
print(line.strip())
if "Done" in line:
break
if line != '':
pass
else:
break
Obviously, you can quiz the contents of line
and decide which lines you wish to use, or define your output based on the contents.
Output snippet:
....
frame= 1 fps=0.0 q=0.0 size= 5kB time=00:00:00.11 bitrate= 334.6kbits/s speed=3.14x
frame= 54 fps=0.0 q=28.0 size= 5kB time=00:00:02.40 bitrate= 16.4kbits/s speed=4.16x
frame= 83 fps= 74 q=28.0 size= 5kB time=00:00:03.54 bitrate= 11.1kbits/s speed=3.18x
frame= 110 fps= 68 q=28.0 size= 5kB time=00:00:04.69 bitrate= 8.4kbits/s speed=2.91x
frame= 130 fps= 60 q=28.0 size= 5kB time=00:00:05.49 bitrate= 7.2kbits/s speed=2.53x
frame= 150 fps= 56 q=28.0 size= 5kB time=00:00:06.33 bitrate= 6.2kbits/s speed=2.37x
frame= 174 fps= 53 q=28.0 size= 256kB time=00:00:07.33 bitrate= 285.9kbits/s speed=2.25x
frame= 195 fps= 52 q=28.0 size= 256kB time=00:00:08.21 bitrate= 255.4kbits/s speed=2.18x
....