rust-ffmpeg-sys

Low-level, auto-generated Rust FFI bindings to FFmpeg's C libraries via bindgen.

Library
Cargo
v9.0.0
212stars
WTFPL

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
72/100Good
Development Activity72
Maintenance60
Community76
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
53/100Fair
Architecture62
Code Quality55
Innovation58
Learning Curve35

ffmpeg-sys-next provides raw, unsafe Rust bindings to FFmpeg’s C API, generated at build time with bindgen against whichever FFmpeg installation it finds on the host (or, optionally, FFmpeg source it fetches and builds itself). It is a fork of the abandoned meh/rust-ffmpeg-sys crate, kept current with FFmpeg’s release cadence: crate major and minor versions track FFmpeg’s own major.minor series directly.

Rather than shipping a fixed binding surface, the crate’s build.rs inspects the FFmpeg headers being compiled against and emits compile-time cfg flags (ffmpeg_x_y, avcodec_version_greater_than_x_y, ff_api_* deprecation guards) so downstream code can conditionally compile against the exact feature set of the linked FFmpeg version. It underlies the higher-level, safe ffmpeg-next crate and is the standard low-level entry point for any Rust project that needs direct access to libavcodec, libavformat, libavfilter, libavdevice, libswscale, or libswresample.

What You Get

  • Auto-generated bindgen bindings covering libavcodec, libavformat, libavfilter, libavdevice, libswscale, libswresample, and libpostproc
  • Compile-time version-detection cfg flags (ffmpeg_x_y, avcodec_version_greater_than_x_y) so you can gate code on the exact linked FFmpeg version
  • A build.rs that can locate FFmpeg via pkg-config/vcpkg or fetch and statically build FFmpeg from source on demand
  • Per-component Cargo feature flags to link only the FFmpeg libraries you need
  • Platform-specific hardware acceleration bindings (VideoToolbox, VAAPI, NVIDIA, D3D11VA, DXVA2, AMF, Vulkan) behind opt-in build features

Common Use Cases

  • Building custom video/audio transcoding pipelines in Rust that need direct libavcodec/libavformat control
  • Implementing the low-level backend for a higher-level Rust media library, as ffmpeg-next itself does
  • Writing performance-critical media tools (frame extraction, format probing, filter graphs) without shelling out to the ffmpeg CLI binary
  • Cross-compiling media applications where the exact FFmpeg feature set and hardware-acceleration backend need to be pinned at build time

Under The Hood

Architecture The entire architecture centers on a single large build.rs that runs at compile time: it detects or locates FFmpeg (via pkg-config, vcpkg, or environment variables like FFMPEG_DIR), optionally fetches and statically builds FFmpeg from source when the build feature is enabled, then runs bindgen against the discovered headers with custom ParseCallbacks to control integer typing, enum constification, and macro parsing, emitting a bindings.rs that src/lib.rs pulls in directly via include!(concat!(env!("OUT_DIR"), "/bindings.rs")). A small hand-written avutil module (error, util, rational, pixfmt, and a feature-gated profile submodule) sits alongside the generated bindings to provide the handful of helpers bindgen can’t produce automatically, such as AVERROR handling and rational arithmetic. There is no runtime layering or dependency injection here — it is fundamentally a build-time code generator, so changes to build.rs’s library-detection and bindgen configuration ripple through the compiled bindings surface of every downstream consumer.

Tech Stack The crate targets Rust’s 2024 edition and depends on bindgen (with the runtime feature) to generate FFI bindings, cc and pkg-config to detect and compile against native libraries, num_cpus to parallelize any source builds, and vcpkg on MSVC targets; libc is the only runtime dependency, supplying C type definitions. CI (GitHub Actions) builds the crate against a matrix of FFmpeg versions from 3.3 through 9.0, using jrottenberg/ffmpeg Docker containers for older releases and prebuilt FFmpeg archives for newer ones where the Docker images lag.

Code Quality There are no dedicated unit test files under src/ — the CI “Test” step (cargo test --features $FEATURES) is effectively a compile and link smoke check, and doctests are explicitly disabled in Cargo.toml to work around a known rust-bindgen issue, so there is no assertion-based test suite in the conventional sense. Quality is instead enforced by cargo clippy -- -D warnings in CI and by the crate compiling cleanly across ten-plus FFmpeg version and platform combinations, which is itself a meaningful regression check on the generated-bindings path. The handful of hand-written files use plain Rust error handling built around FFmpeg’s own AVERROR codes and standard naming conventions; the bulk of the public surface is bindgen-generated and inherits FFmpeg’s C naming rather than idiomatic Rust naming.

What Makes It Unique The crate’s differentiator is operational rather than algorithmic: it automatically detects the installed FFmpeg version and generates a binding surface, plus matching cfg feature flags, for that exact version instead of shipping one static binding snapshot per crate release the way many other -sys crates do. That lets a single crate release support a wide span of FFmpeg versions and gracefully expose or hide newer API surface via the ffmpeg_x_y cfg flags, with an optional self-building FFmpeg source path for environments without a system FFmpeg install. It’s a solid engineering answer to sys-crate versioning churn, built on patterns established by other bindgen-based sys crates rather than a wholly new approach.

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