Monitor FFmpeg Progress with Stdout Redirection
Monitoring the progress of an FFmpeg encoding process through
standard output (stdout) requires routing FFmpeg's internal progress
reporting away from its default standard error (stderr) stream. This
article explains why FFmpeg defaults to stderr, how to use the built-in
-progress flag to pipe structured metrics directly to
stdout, and how to parse the resulting stream using shell tools or
custom scripts.
The Problem with Default FFmpeg Output
By default, FFmpeg prints all informational logs, encoding
statistics, and errors to stderr, keeping
stdout reserved for raw media output when piping. Because
interactive progress displays continuously update using carriage returns
(\r), capturing and parsing standard terminal output can be
erratic and difficult to process reliably.
The Solution: Using
-progress pipe:1
FFmpeg includes a dedicated progress option (-progress)
that periodically emits machine-readable progress metrics to a specified
URL or file descriptor. By passing pipe:1, you direct this
telemetry directly to stdout.
To ensure clean output, combine this with -nostats (to
disable default console updates) and -loglevel error (to
prevent non-critical log messages from cluttering
stderr).
Basic Command Syntax
ffmpeg -loglevel error -nostats -i input.mp4 -progress pipe:1 output.mkvUnderstanding the Output Format
When redirected to stdout, FFmpeg produces key-value
pairs separated by equal signs, ending with a progress=
line for each update interval:
frame=1240
fps=59.80
stream_0_0_q=28.0
bitrate= 2450.2kbits/s
total_size=15728640
out_time_us=20666667
out_time_ms=20666667
out_time=00:00:20.666667
dup_frames=0
drop_frames=0
speed=0.997x
progress=continue
Key fields include:
- out_time_us: The current encoded duration in microseconds (most reliable for calculating completion percentages).
- out_time: Human-readable timestamp
(
HH:MM:SS.microsecond). - frame: Total number of video frames processed so far.
- speed: Current processing speed relative to real-time playback.
- progress: Indicates processing state; displays
continueduring the encode andendupon completion.
Processing Progress in Real Time
Example: Filtering with Grep
To isolate just the current timestamp in real time:
ffmpeg -loglevel error -nostats -i input.mp4 -progress pipe:1 output.mkv | grep --line-buffered "out_time="Example: Parsing with Python
You can read stdout line-by-line using Python's
subprocess module:
import subprocess
command = [
"ffmpeg",
"-loglevel", "error",
"-nostats",
"-i", "input.mp4",
"-progress", "pipe:1",
"output.mp4"
]
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True
)
for line in process.stdout:
line = line.strip()
if "=" in line:
key, value = line.split("=", 1)
if key == "out_time":
print(f"Current Position: {value}")
elif key == "progress" and value == "end":
print("Encoding Complete.")
process.wait()Calculating Completion Percentage
To calculate a percentage completion value:
Determine the total duration of the input file before encoding using
ffprobe:ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4Convert that duration into microseconds (multiply seconds by
1,000,000).Read the
out_time_usvalue from thepipe:1output stream.Compute the percentage:
(out_time_us / total_duration_us) * 100.