Skip to main content

Module cli

Module cli 

Source
Expand description

CLI-compat layer (cli feature): run or translate a strict, documented subset of ffmpeg command lines in-process.

Two capabilities share one typed intermediate representation:

use ez_ffmpeg::cli::from_cli_args;

from_cli_args(&["-i", "in.mkv", "-c:v", "libx264", "-crf", "23",
                "-preset", "fast", "-c:a", "aac", "-y", "out.mp4"])?
    .start()?
    .wait()?;

The layer is optional; enable it in Cargo.toml:

[dependencies.ez-ffmpeg]
version = "*"
features = ["cli"]

§The contract: classify everything, approximate nothing

Broad CLI compatibility is a non-goal. The ffmpeg CLI is ~14k lines of option machinery whose semantics move with every release; chasing it wholesale produces the “runs, but subtly different” failures that destroy trust. This layer does the opposite:

  • every argv token must classify against the versioned compatibility manifest, or the ENTIRE command is rejected with a token-anchored, typed diagnostic (CliError) — nothing is dropped or guessed;
  • commands whose exact shape is backed by a semantic golden test (stream identity, codecs, dimensions, durations, playlist topology compared against the real ffmpeg CLI) are verified: they may execute;
  • commands that parse and match an ENUMERATED unverified manifest entry are emit-only: the code generators label their output “unverified scaffolding” and from_cli_args refuses to run them;
  • commands that parse but match neither manifest table are rejected outright (CliError::UnmatchedShape) — run and emit alike; no silent scaffolding class exists;
  • execution additionally requires a verified runtime profile of the linked FFmpeg (currently 7.1 only; 8.1 joins once its version-matched golden lane passes) — anything else fails with the typed CliError::UnverifiedRuntimeProfile before any I/O.

CLI-initiated pipelines also run with strict AVOption handling: an option no component consumed fails the run (fftools check_avoptions parity) instead of the default builder path’s warning.

§The manifest (generated; revision-pinned by an exact-equality test)

Manifest revision 4; dialect: ffmpeg 7.1 command line.

optionscopeselectorrepeatnotesmaps to
-yglobalrunrepeatableflagmandatory overwrite gate
-hide_bannerglobalno-oprepeatableaccepted, no in-process effectnone (documented no-op)
-nostdinglobalno-oprepeatableaccepted, no in-process effectnone (documented no-op)
-statsglobalno-oprepeatableaccepted, no in-process effectnone (documented no-op)
-nostatsglobalno-oprepeatableaccepted, no in-process effectnone (documented no-op)
-loglevelglobalno-oprepeatableno in-process effect; value: [repeat+][level+]LEVELnone (documented no-op)
-vglobalno-oprepeatableno in-process effect; value: [repeat+][level+]LEVELnone (documented no-op)
-ssinput or output (position-scoped)containeroncedecimal seconds only (10, 2.5)Input::set_start_time_us / Output::set_start_time_us
-tinput or output (position-scoped)containeroncedecimal seconds only (10, 2.5)Input::set_recording_time_us / Output::set_recording_time_us
-toinput or output (position-scoped)containeroncedecimal seconds only (10, 2.5)Input::set_stop_time_us / Output::set_stop_time_us
-finput or output (position-scoped)containeroncecontainer/demuxer name ([a-z0-9_]+)Input::set_format / Output::set_format
-vnoutputvideorepeatableflagOutput::disable_video
-anoutputaudiorepeatableflagOutput::disable_audio
-c:voutputvideooncecodec name or copy ([A-Za-z0-9_-]+)Output::set_video_codec
-c:aoutputaudiooncecodec name or copy ([A-Za-z0-9_-]+)Output::set_audio_codec
-b:voutputvideoonceNNN with optional k/K/m/M suffixOutput::set_video_bitrate
-b:aoutputaudioonceNNN with optional k/K/m/M suffixOutput::set_audio_bitrate
-crfoutputvideoonceinteger 0..=51Output::set_video_codec_opt(“crf”, …), libx264 only
-presetoutputvideooncex264 preset nameOutput::set_video_codec_opt(“preset”, …), libx264 only
-pix_fmtoutputvideooncepixel format name ([a-z0-9_]+)Output::set_pix_fmt
-aroutputaudiooncepositive integerOutput::set_audio_sample_rate
-acoutputaudiooncepositive integerOutput::set_audio_channels
-frames:voutputvideoonceexactly 1Output::set_max_video_frames(1)
-vfoutputvideooncesingle scale=… chain onlyOutput::set_video_filter
-mapoutputstream mapaccumulatesbasic index maps only (0, 0:v, 0:a:1, 0:1, …)Output::add_stream_map / add_stream_map_with_copy
-movflagsoutputcontaineronceexactly +faststartOutput::set_format_opt(“movflags”, “+faststart”)
-hls_timeoutputcontaineroncedecimal seconds > 0Output::set_format_opt(“hls_time”, …)
-hls_playlist_typeoutputcontaineronceexactly vodOutput::set_format_opt(“hls_playlist_type”, “vod”)
-hls_list_sizeoutputcontaineronceexactly 0Output::set_format_opt(“hls_list_size”, “0”)
-hls_segment_filenameoutputcontaineroncenon-empty path; --leading values rejectedOutput::set_format_opt(“hls_segment_filename”, …)

Command layout is fixed: exactly one -i input and exactly one output path, in the canonical [global/input options] -i INPUT [output options] OUTPUT [global options] order — after the output path only GLOBAL options are accepted (e.g. a trailing -y). The - stdin/stdout pseudo-paths are excluded — pipe I/O is process wiring, not part of the in-process subset.

Verified shapes (may execute; each is backed by a semantic golden and a compile-pinned emitted example):

idshapecontainer
V1H.264/AAC transcode (crf + preset).mp4
V2re-encoded clip (input -ss, output -t).mp4
V3audio extract (-vn, AAC).m4a
V4single-frame thumbnail (input -ss, -an, mjpeg).jpg
V5scaled H.264/AAC transcode (-vf scale).mp4
V6single-rendition VOD HLS.m3u8

Unverified entries (emit-only: code generation with a scaffolding banner, execution refused):

idshape
U1input-side trim (-ss + -t before -i)
U2faststart remux (explicit per-media copy)
U3scale with audio copy
U4thumbnail recipe shape (-vf + -frames:v)
U5audio extract via stream copy
U6PCM / resampled audio extract
U7partial HLS option set
U8mapped transcode (basic index maps)
U9mapped audio copy
U10cross-scope trim pair (input -t, output -to)
U11output-side seek transcode
U12bitrate-driven transcode
U13pixel-format transcode
U14explicit input format (e.g. lavfi)
U15container-defaults remux
U16video-codec-only transcode
U17transcode without preset
U18transcode with audio bitrate
U19audio+video codec selection only
U20transcode shape with unpinned values/container
U21clip shape with unpinned values/container
U22audio-extract shape with unpinned values/container
U23thumbnail shape with unpinned values/container
U24scaled-transcode shape with unpinned values/container
U25VOD HLS shape with unpinned values/container

Everything else — including parseable option sets outside both tables — is rejected with a typed diagnostic.

§String form

from_cli / emit_rust_code accept one string and apply POSIX word splitting ONLY: single/double quotes, backslash escapes, backslash-newline continuation, plus caret-newline continuation as an explicitly named cmd.exe compatibility extension. No variables, globs, tilde, pipes, redirects, comments or command lists — those tokens are rejected, never emulated (unquoted *, ? and [ included: quote or escape a literal). Windows cmd.exe quoting is NOT reproduced: commands relying on CommandLineToArgvW backslash rules must use the argv form.

Enums§

CliError
Error type of the CLI-compat entry points (from_cli_args, from_cli, emit_rust_code, emit_rust_code_from_args).
CliScope
Where in the command an option was found (positional scoping: options apply to the next file on the command line).

Functions§

emit_rust_code
Single-string convenience wrapper over emit_rust_code_from_args, using the same POSIX word-splitting contract as from_cli.
emit_rust_code_from_args
Translates ffmpeg-style argv tokens into a complete Rust program using the ez-ffmpeg builder API.
from_cli
Single-string convenience wrapper over from_cli_args.
from_cli_args
Builds a ready-to-start FfmpegContext from ffmpeg-style argv tokens.