Skip to main content

Typed fluent FFmpeg/ffprobe wrapper with msgspec models

Project description

ffmpeg-wrap

A typed Python wrapper for FFmpeg and ffprobe CLI tools. Build FFmpeg commands with a fluent API and parse ffprobe output into typed data structures.

Requirements

  • Python 3.10+
  • FFmpeg and ffprobe installed and available on PATH

Installation

With uv:

uv add ffmpeg-wrap

With pip:

pip install ffmpeg-wrap

Usage

import ffmpeg_wrap as ffmpeg

Probe a media file

result = ffmpeg.probe("video.mkv")

for stream in result.streams:
    print(stream.codec_name, stream.codec_type)

if result.format:
    print(result.format.duration)
    print(result.format.format_name)

Build and run an FFmpeg command

ffmpeg.input("input.mkv").output("output.mp4", c="copy").overwrite_output().run()

Multiple inputs and outputs

(
    ffmpeg.input("input.mkv", ss=10, t=30)
    .output("clip.mp4", vcodec="libx264", acodec="aac")
    .overwrite_output()
    .run()
)

Global arguments

(
    ffmpeg.input("input.mkv")
    .output("output.mp4", c="copy")
    .global_args("-hide_banner", "-loglevel", "error")
    .overwrite_output()
    .run()
)

Capture output

stdout, stderr = (
    ffmpeg.input("input.mkv")
    .output("output.mp4", c="copy")
    .overwrite_output()
    .run(capture_stdout=True, capture_stderr=True)
)

Validate a media file

validate() checks whether a file is valid media without parsing full probe output. It returns a (ok, stderr) tuple instead of raising on bad media.

ok, stderr = ffmpeg.validate("video.mkv")
if not ok:
    print(f"Invalid media: {stderr}")

The default loglevel="warning" surfaces ffprobe warnings (non-monotonic DTS, unsupported codecs, truncated frames) in addition to hard errors. Use a stricter level when only fatal problems matter:

ok, stderr = ffmpeg.validate("video.mkv", loglevel="error")
ok, stderr = ffmpeg.validate("video.mkv", loglevel="fatal")

Pass extra ffprobe flags via extra_args:

ok, stderr = ffmpeg.validate("video.mkv", extra_args=("-hide_banner",))

Use validate() when you only need a pass/fail check. Use probe() when you need stream and format metadata. The only exception validate() raises is FFmpegError when the ffprobe executable could not be run (missing, not executable, etc.).

try:
    ok, stderr = ffmpeg.validate("video.mkv")
except ffmpeg.FFmpegError:
    print("ffprobe could not be executed")

Error handling

try:
    ffmpeg.probe("nonexistent.mkv")
except ffmpeg.FFmpegError as e:
    print(f"Probe failed: {e}")

try:
    ffmpeg.input("missing.mkv").output("out.mp4").run()
except ffmpeg.FFmpegError as e:
    print(f"FFmpeg failed: {e}")

Custom executable paths

result = ffmpeg.probe("video.mkv", ffprobe_path="/usr/local/bin/ffprobe")

ok, stderr = ffmpeg.validate("video.mkv", ffprobe_path="/usr/local/bin/ffprobe")

ffmpeg.input("input.mkv", ffmpeg_path="/usr/local/bin/ffmpeg").output("output.mp4").run()

API Reference

probe(filename, ffprobe_path="ffprobe")

Run ffprobe on a file and return a typed ProbeResult.

  • filename -- Path to the media file (str or PathLike).
  • ffprobe_path -- Path to the ffprobe executable. Defaults to "ffprobe".
  • Returns: ProbeResult with streams and format fields.
  • Raises: FFmpegError on subprocess failure or invalid output.

validate(filename, ffprobe_path="ffprobe", loglevel="warning", extra_args=())

Run ffprobe in validation mode and check for errors/warnings.

  • filename -- Path to the media file (str or PathLike).
  • ffprobe_path -- Path to the ffprobe executable. Defaults to "ffprobe".
  • loglevel -- Value passed to ffprobe's -v flag. Defaults to "warning" (surfaces DTS/codec warnings). Use "error" to ignore warnings or "fatal"/"panic" for only unrecoverable failures.
  • extra_args -- Additional raw arguments forwarded to ffprobe before the filename, e.g. ("-hide_banner",).
  • Returns: tuple[bool, str] -- (ok, stderr_text). ok is True when ffprobe exits with code 0 and stderr is empty after stripping whitespace.
  • Raises: FFmpegError only when the ffprobe executable could not be run. Does not raise on invalid media.

input(filename, ffmpeg_path="ffmpeg", **kwargs)

Create a new FFmpeg builder chain starting with an input file.

  • filename -- Input file path.
  • ffmpeg_path -- Path to the ffmpeg executable. Defaults to "ffmpeg".
  • **kwargs -- Input options passed as FFmpeg flags (e.g., ss=10, t=30).
  • Returns: FFmpeg instance for method chaining.

FFmpeg

Fluent builder for FFmpeg commands.

  • input(filename, **kwargs) -- Add an input file with options.
  • output(filename, **kwargs) -- Add an output file with options.
  • overwrite_output() -- Add the -y flag to overwrite existing output files.
  • global_args(*args) -- Add global arguments before inputs.
  • compile() -- Build the command as a list of strings without executing it.
  • run(capture_stdout=False, capture_stderr=False) -- Execute the command. Returns (stdout, stderr). Values are bytes when the corresponding capture flag is True, or None otherwise. Raises FFmpegError on failure.

ProbeResult

Typed result from ffprobe.

  • streams -- List of Stream objects.
  • format -- Optional Format object.

Stream

A single stream from ffprobe output. Fields include index, codec_name, codec_type, width, height, channels, sample_rate, duration, bit_rate, tags, disposition.

Format

The format section from ffprobe output. Fields include filename, nb_streams, nb_programs, format_name, format_long_name, start_time, duration, size, bit_rate, probe_score, tags.

FFmpegError

Exception raised when FFmpeg or ffprobe operations fail.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ffmpeg_wrap-0.2.0.tar.gz (26.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ffmpeg_wrap-0.2.0-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

Details for the file ffmpeg_wrap-0.2.0.tar.gz.

File metadata

  • Download URL: ffmpeg_wrap-0.2.0.tar.gz
  • Upload date:
  • Size: 26.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for ffmpeg_wrap-0.2.0.tar.gz
Algorithm Hash digest
SHA256 4390163276efa541ce05d153991354c68cd7424925535860f65055e1485527af
MD5 683330b132c3b71097c0b72b799bfae4
BLAKE2b-256 751e647d7a3d42f560deb868a638f983575f87fe7ab852a5ab36e06ac4b9b47e

See more details on using hashes here.

File details

Details for the file ffmpeg_wrap-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: ffmpeg_wrap-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 8.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for ffmpeg_wrap-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dc50d74d230fe9ee3113d8919d593e5112e006588c7683840f6e88f07ea6e614
MD5 f0add1329c891c7e875704f8ae147a63
BLAKE2b-256 0d06de118d0c1f24be1d56ba52a8689710171a2b223ba41fb807c2dfb7de2270

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page