Monitor FFmpeg progress for production: parsing -progress output
Track FFmpeg encoding progress in production. The -progress flag emits structured key-value pairs vs the chaotic stderr output that breaks log aggregators.
When to use this
You parse FFmpeg progress when you need real-time feedback during long encodes — UI progress bars, queue health monitoring, ETA calculation, OOM detection. The default approach (parsing stderr line-by-line) is fragile and ships verbose log volume to your aggregator. The -progress flag emits structured key-value output to a file or stdout, dramatically simpler to parse and far less log volume to ship.
Command variants
ffmpeg -progress pipe:1 -i input.mp4 \
-c:v libx264 -preset medium -crf 22 \
-c:a copy \
output.mp4 2>/dev/null | grep -E "frame=|fps=|out_time=|progress="pipe:1 sends -progress output to stdout. Suppresses stderr to silence the verbose default output.
ffmpeg -progress progress.log -i input.mp4 \
-c:v libx264 -preset medium -crf 22 \
-c:a copy \
output.mp4Writes structured progress to progress.log every second. Parse the file from your monitoring service.
ffmpeg -progress pipe:1 -nostats -i input.mp4 \
-c:v libx264 -preset medium -crf 22 \
-c:a copy \
output.mp4 2>/dev/null-nostats suppresses the default 1-line stderr stats. Cleaner output for production.
What each parameter does
-progress [target]Send structured progress to target. pipe:1 = stdout, pipe:2 = stderr, [filename] = file. Updates every second.
-nostatsSuppress the default verbose stderr stats line. Useful when -progress is doing the reporting.
progress=continueField in the progress output indicating encoding is in progress. progress=end signals completion.
frame=N out_time_ms=N speed=NStandard progress fields. frame = frames encoded so far. out_time_ms = position in output (milliseconds). speed = encode rate vs realtime (1x = realtime).
What this outputs
A stream of structured key-value pairs (one field per line) updated every second during encoding. Format is stable and parseable; no need to handle FFmpeg's verbose stderr output.
Pitfalls
- Default stderr output is fragile to parse: format changes between FFmpeg versions, contains warnings mixed with progress. Use -progress for production monitoring.
- -progress pipe:1 to stdout requires explicit stderr suppression (2>/dev/null) or your output gets contaminated with verbose logs.
- Progress updates every second by default; can't increase frequency. For sub-second progress, parse frame number changes from -progress and infer rate.
- Progress fields differ between encoders (NVENC vs libx264 produce different field sets). Test with your specific encoder pool.
- Progress file accumulates indefinitely if not rotated. For long-running encodes, periodically truncate or rotate the progress file.
- progress=continue alternates with progress=end at the close of the encode. Race conditions in parsers checking only current value can miss completion.
At production scale
Parsing FFmpeg progress at scale matters because logging FFmpeg's default stderr output is wasteful. A typical encode emits ~5-10 KB of stderr; -progress emits ~500 bytes. At 100K encodes/day, that's 500 MB vs 50 MB of log volume. The cost difference at log-aggregation scale (Datadog charges by log volume) is meaningful — 10× reduction matters.
MpegFlow workers always use -progress for structured progress reporting. The progress is parsed, summarized, and exposed via the gRPC API to the coordinator. UIs and webhooks receive concise progress events, not raw FFmpeg output.
- FFmpeg
- progress
- monitoring
- tooling
- Operations