imageio-ffmpeg

A pure-Python wrapper that bundles a platform-specific ffmpeg binary for reading and writing video, with no system ffmpeg install required.

Library
PyPI
v0.6.0
297stars
BSD-2-Clause

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
41/100Fair
Development Activity0
Maintenance20
Community64
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
64/100Good
Architecture78
Code Quality66
Innovation55
Learning Curve55

imageio-ffmpeg gives Python code direct access to ffmpeg without asking the user to install anything extra: platform-specific PyPI wheels vendor a pinned ffmpeg executable, and the library exposes it through two small generator functions, read_frames() and write_frames(), that stream raw video frames in and out over subprocess pipes. It also provides count_frames_and_secs() for exact frame/duration counts and automatic H.264 hardware-encoder detection, preferring h264_nvenc/h264_vaapi over software libx264 when the bundled ffmpeg supports them.

The project exists primarily as the engine behind imageio’s own ffmpeg format plugin, but is fully usable standalone by anyone who wants low-level, dependency-free video I/O in Python. Internally it manages the full subprocess lifecycle itself — a background log-catching thread drains ffmpeg’s stderr to avoid pipe deadlocks, and explicit GeneratorExit/KeyboardInterrupt handling guarantees the ffmpeg process is always terminated cleanly rather than left orphaned.

What You Get

  • A bundled, pinned ffmpeg executable for Windows, macOS, and Linux (x86_64/aarch64), selected automatically at runtime via importlib.resources
  • read_frames() / write_frames() generator functions for streaming raw video frames without buffering an entire file in memory
  • count_frames_and_secs() for exact frame-count and duration lookups by parsing ffmpeg’s own decode pass
  • Automatic detection of the best available H.264 encoder, preferring hardware acceleration (NVENC, VAAPI) over software encoding
  • Environment-variable overrides (IMAGEIO_FFMPEG_EXE, IMAGEIO_FFMPEG_NO_PREVENT_SIGINT) to point at a custom binary or change signal handling

Common Use Cases

  • Backing imageio’s ffmpeg format plugin for reading/writing video and camera streams
  • Frame-by-frame video processing pipelines in computer vision and ML projects
  • Programmatic transcoding or re-encoding of video files with a specific codec, bitrate, or quality
  • Cross-platform tooling and CI pipelines that need consistent video encoding without an OS-specific ffmpeg install step

Under The Hood

Architecture The library is organized into four small modules: _io.py (the public read/write frame generators and subprocess orchestration), _parsing.py (ffmpeg stderr header/log parsing via a background LogCatcher thread), _utils.py (ffmpeg executable discovery, _popen_kwargs, version querying), and _definitions.py (version, platform detection, per-platform binary filename mapping). __init__.py re-exports a deliberately small public surface: count_frames_and_secs, read_frames, write_frames, get_ffmpeg_exe, get_ffmpeg_version. Both read_frames and write_frames are Python generators wrapping a subprocess.Popen call to the bundled ffmpeg binary, negotiating frame-by-frame reads/writes over stdin/stdout pipes while the LogCatcher thread drains stderr to avoid pipe deadlock. Process teardown distinguishes GeneratorExit (normal close), other exceptions (propagate), and BaseException (Ctrl-C/SystemExit, switching to a hard kill policy) — a deliberate design to guarantee the ffmpeg subprocess is always reaped. There is no dependency injection or plugin system; the subprocess pipe orchestration in _io.py is the core abstraction that every consumer, chiefly the imageio package itself, depends on directly.

Tech Stack Pure Python 3.9+ with zero runtime dependencies (install_requires=[]) — the only “dependency” is the ffmpeg binary itself, vendored directly into platform-specific wheels rather than requiring a system install. Binary selection happens through _definitions.py’s FNAME_PER_PLATFORM table, mapping OS+architecture to a pinned ffmpeg release, resolved at runtime via importlib.resources. Packaging uses classic setuptools/setup.py rather than a pyproject.toml-based build backend, with invoke (via tasks.py) driving formatting, linting, and CI orchestration. CI runs a matrix across Python 3.9-3.13, PyPy, and Linux/Windows/macOS using pytest/pytest-cov. There is no database, web framework, or ORM involved — this is a narrowly-scoped systems-integration library.

Code Quality The test suite covers the public API with pytest across several files, including dedicated coverage for resource-warning-free generator closing and subprocess termination edge cases (SIGINT/kill-policy behavior), showing deliberate attention to the lifecycle bugs this kind of wrapper is prone to. Error handling favors explicit, typed exceptions (IOError, RuntimeError, TypeError) with descriptive messages that include captured ffmpeg stderr output rather than swallowing failures. There is no static type-checking and no type hints in function signatures; linting is flake8 plus black for formatting, both enforced in CI. Naming is consistent and the codebase is compact and readable.

API Design The public API is intentionally minimal and function-based rather than object-oriented: five top-level functions cover the entire surface, with generator-based streaming (send()/iteration) instead of buffered in-memory APIs, keeping memory usage predictable for large video files. Docstrings on every public function include runnable usage examples. Getting started requires a single pip install and no configuration, since the ffmpeg binary ships inside the wheel — the one piece of friction is that advanced usage (custom input/output ffmpeg flags) requires knowing ffmpeg’s own command-line vocabulary, which the library passes through largely unvalidated.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search