C.W.K.
Stream
Lesson 06 of 08 · published

Progress Monitoring

~8 min · progress, monitor, scripting

Level 0Viewer
0 XP0/73 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

Three modes

  • Default — single line redrawn with frame/time/bitrate stats. Good for interactive use.
  • -progress pipe:1 — machine-readable progress events on stdout. Good for scripts.
  • -progress <file> — same events written to a file (for daemons/non-tty processes).

Parsing progress

The machine format is key=value pairs separated by newlines. out_time_us=12345678 = current encode position in microseconds. fps=84.3, bitrate=4521.2kbits/s, progress=continue or progress=end.

Code

Interactive vs scripted progress·bash
# Default interactive (the redrawing line)
ffmpeg -i in.mp4 -c:v libx264 out.mp4

# Machine-readable on stdout, no other log noise
ffmpeg -hide_banner -loglevel error -nostats \
  -i in.mp4 -c:v libx264 -crf 20 \
  -progress pipe:1 \
  out.mp4 | grep --line-buffered -E '^(out_time_us|progress)='

# Write to a file (read elsewhere)
ffmpeg -i in.mp4 -c:v libx264 \
  -progress /tmp/ffmpeg_progress.txt \
  out.mp4
Python progress callback·python
import subprocess

def encode_with_callback(src, dst, on_progress=lambda pct: None):
    # Get total duration first
    duration = float(subprocess.check_output([
        "ffprobe", "-v", "error", "-show_entries", "format=duration",
        "-of", "default=noprint_wrappers=1:nokey=1", src,
    ]))
    total_us = duration * 1_000_000

    p = subprocess.Popen([
        "ffmpeg", "-y", "-i", src,
        "-c:v", "libx264", "-crf", "20", "-preset", "slow",
        "-c:a", "copy",
        "-progress", "pipe:1",
        "-nostats", "-loglevel", "error",
        dst,
    ], stdout=subprocess.PIPE, text=True)
    for line in p.stdout:
        if line.startswith("out_time_us="):
            us = int(line.split("=", 1)[1])
            on_progress(min(100, us / total_us * 100))
    return p.wait()

encode_with_callback("in.mp4", "out.mp4",
                    on_progress=lambda p: print(f"\r{p:.1f}%", end="", flush=True))

External links

Exercise

Write a shell script that encodes a video and shows a percentage progress bar (parsing -progress pipe:1). Test on a 5-minute clip. Then port it to Python using the recipe above. Bonus: add ETA computation based on observed encoding speed.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.