README

FFmpegProgressBar

A Raku module that adds a progress bar to ffmpeg commands.

output.mp4 ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ 75.00% 00:00:05 ETA: 2s

With optional frame/bitrate info:

output.mp4 ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ 75.00% 00:00:05 ETA: 2s [750/1000 (25.5fps)] (2.5Mbps)

Features

  • Command-line interface - Use ffpb command to run ffmpeg with a progress bar

  • Can be used as a library - Use in your Raku scripts

  • Progress bar - Shows percentage, elapsed time, and ETA during encoding

    • Optional display features - Show frames, bitrate, or verbose output with CLI flags

  • Auto duration detection - Automatically detects video duration from ffprobe or parses -t/-to/-ss arguments

  • Multi-input duration - Correctly handles -ss per input (e.g., -ss 10 -i a.mp4 -ss 30 -i b.mp4)

  • Multi-output support - Handles multiple output files (e.g., -i input.mp4 output1.mp4 output2.mkv)

  • -map support - Filters duration detection to relevant inputs when -map is used (e.g., -map 0:v -map 1:a)

  • Flexible time parsing - Supports HH:MM:SS, MM:SS, and unit formats (1h30m, 45m30s)

  • Two-pass encoding - Automatically detects and runs pass 1 before showing progress for pass 2

  • Progress Tracking API - get-progress(), progress-supply(), watch-progress() for external monitoring (see section below)

Requirements

Installation

zef install ffmpegprogressbar

Installing from source

To install from a local folder:

cd /path/to/FFmpegProgressBar
zef install .

Usage

Command Line

ffpb -i input.mp4 -c:v libx264 output.mp4

Command Line Options

  • -V, --verbose - Show detected duration and executed command

  • -F, --frames - Show current frame and encoding fps

  • -B, --bitrate - Show output bitrate

  • -S, --style - Set progress bar style (bar, hash, hash-dash, equals)

  • -D, --duration, --total-time - Set duration in seconds (skip auto-detection)

  • -M, --ffmpeg - Path to ffmpeg binary

  • -P, --ffprobe - Path to ffprobe binary

  • -E, --stderr - Show ffmpeg stderr on success (last 20 lines, use --stderr all for all)

  • -Q, --quiet - Suppress progress bar rendering (useful when only using progress API)

  • --no-color - Disable colored output

Library

use FFmpegProgressBar;

my $progress = FfmpegProgress.new(:duration(30), :verbose(True));
$progress.run('-i', 'input.mp4', 'output.mp4');

Or use the subroutine interface:

ffmpeg-progress(
    '-i', 'input.mp4',
    '-c:v', 'libx264',
    'output.mp4',
    :duration(30),
    :verbose(True)
)

Library Options

  • $ffmpeg - Path to ffmpeg binary (default: 'ffmpeg')

  • $ffprobe - Path to ffprobe binary (default: 'ffprobe')

  • $duration - Manually set video duration (default: 0, auto-detected)

  • $verbose - Show detected duration and executed command

  • $quiet - Suppress progress bar rendering (useful when only using progress API)

  • $show-frames - Show current frame and encoding fps

  • $show-bitrate - Show output bitrate

  • $bar-type - Progress bar style (bar, hash, hash-dash, equals)

  • $no-color - Disable colored output

  • $stderr-lines - Show ffmpeg stderr on success ('20', '50', 'all', or '' for off)

Library Methods

  • $ff.quit() - Send 'q' to gracefully stop encoding (call from external code)

  • $ff.quit(:force) - Force kill ffmpeg immediately

use FFmpegProgressBar;

my $ff = FfmpegProgress.new(:duration(30), :verbose(True));
$ff.run('-i', 'input.mp4', 'output.mp4');

# Or control externally:
my $ff2 = FfmpegProgress.new(:ffmpeg('/path/to/ffmpeg'));
$ff2.run('-i', 'input.mp4', 'output.mp4');
# ... in another thread or loop:
$ff2.quit() if $some-condition;
$ff2.quit(:force);  # force kill

Progress Tracking API

FFmpegProgressBar provides three ways to monitor encoding progress externally:

watch-progress() (Recommended)

Simple async iteration that yields percent directly. Use :quiet to suppress the progress bar:

use FFmpegProgressBar;

my $p = FfmpegProgress.new(:quiet);
my $promise = start { $p.run('-i', 'input.mp4', 'output.mp4') };

for $p.watch-progress -> $percent {
    say "Progress: {$percent.fmt('%.1f')}%";
    $p.quit() if $percent >= 50;
}

await $promise;
say $p.get-progress().summary;

With full snapshots (watch-progress(:emit)):

for $p.watch-progress(:emit) -> $snap {
    say $snap.summary;
    $p.quit() if $snap.is-stalled;
}

get-progress()

One-off read - returns a ProgressSnapshot:

my $snap = $p.get-progress();
say $snap.percent;       # 75.0
say $snap.fps;          # 25.0
say $snap.is-complete;  # Bool
say $snap.is-failed;    # Bool
say $snap.summary;

progress-supply()

Reactive supply for event-driven code:

$p.progress-supply.tap: -> $snap {
    say "Progress: {$snap.percent.fmt('%.1f')}%";
};

The progress API returns time-based percentage that matches the progress bar exactly.

Dotfile Configuration

You can create a config file to set default options. The following paths are checked in order:

Unix/Linux/macOS

  • ~/.ffpbrc

  • ~/.config/ffpbrc

  • ~/.config/ffpb/config

  • /etc/ffpbrc

Windows

  • %USERPROFILE%\.ffpbrc

  • %USERPROFILE%\.config\ffpbrc

  • %USERPROFILE%\.config\ffpb\config

  • %APPDATA%\ffpb\config

  • %APPDATA%\ffpbrc

Each line should contain one option (like CLI arguments). Lines starting with # are treated as comments.

Example ~/.ffpbrc:

# Always show verbose info, frame info and use hash style
-V
-F
-S hash

Examples

# Basic encoding
ffpb -i input.mp4 output.mkv

# With verbose output
ffpb -V -i input.mp4 output.mp4

# With frames and bitrate
ffpb -F -B -i input.mp4 output.mp4

# With custom bar style
ffpb -S hash -i input.mp4 output.mp4

# With duration override
ffpb -D 60 -i input.mp4 output.mp4

# With custom ffmpeg/ffprobe paths
ffpb -M /usr/bin/ffmpeg -P /usr/bin/ffprobe -i input.mp4 output.mp4

# Show stderr on success
ffpb -E -i input.mp4 output.mp4

# Last 50 lines				
ffpb -E 50 -i input.mp4 output.mp4

# All stderr output
ffpb -E all -i input.mp4 output.mp4

# Two-pass encoding
ffpb -i input.mp4 -c:v libx264 -b:v 1M -pass 2 -f mp4 output.mp4

FFmpegProgressBar automatically detects -pass 2 and runs the analysis pass (pass 1) silently before displaying the progress bar for the encoding pass.

Bar styles (use -S or --style)

  • bar - ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ (default on unicode terminals; hash-dash otherwise)

  • hash - [########........]

  • hash-dash - [########--------]

  • equals - [======== ]

Windows Support

Full Windows support is implemented. The following features work on Windows 10 and later:

  • Progress bar - Works in Windows Terminal, VS Code terminal, or modern conhost

  • Unicode support - Uses console code page detection

  • Non-blocking keyboard input - Uses Win32 Console API

  • Binary lookup - Automatically finds ffmpeg with .exe, .bat, .cmd extensions

  • Config file locations - Supports %APPDATA% and %USERPROFILE% paths

Requirements on Windows

  • Windows 10 or later (for ANSI color support)

  • ffmpeg installed and in PATH

  • Raku version 6.d or later

For best results, use Windows Terminal which has full ANSI/VT support.

Note on Keyboard Input

  • Unix/Linux/macOS: Pressing 'q' or Ctrl+C cleanly stops encoding. First Ctrl+C sends 'q' (graceful) and second Ctrl+C force-kills ffmpeg.

  • Windows: Pressing 'q' provides graceful shutdown (recommended). Ctrl+C force kills ffmpeg immediately due to limitations with how the native executable wrapper handles console signals on Windows.

AUTHOR

Sasha Abbott [email protected]

LICENSE

This library is free software; you can redistribute it and/or modify it under CC0.

FFmpegProgressBar v0.0.7

Add a progress bar to ffmpeg commands

Authors

  • Sasha Abbott

License

CC0-1.0

Dependencies

Pod::To::Man:ver<1.2.1>:auth<zef:samy>Terminal::Spinners:ver<1.6.0>:auth<github:ryn1x>Terminal::Size:ver<1.0.1>:auth<zef:demayl>Terminal::WCWidth:ver<0.1.5>:auth<zef:raku-community-modules>

Test Dependencies

Provides

  • FFmpegProgressBar
  • FFmpegProgressBar::FFmpegFlags
  • FFmpegProgressBar::Formatter
  • FFmpegProgressBar::Parser
  • FFmpegProgressBar::Probe
  • FFmpegProgressBar::ProgressSnapshot
  • FFmpegProgressBar::Terminal

Documentation

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.