Wrap a standalone FFmpeg binary in an intuitive Iterator interface.
๐ Jump to Getting Started ๐
The core goal of this project is to provide a method of interacting with any video as if it were an array of raw RGB frames.
Of course, that's what video is, fundamentally, but there is a whole pandora's box of complexity in terms of receiving and decoding video before you get there.
Using FFmpeg as the core engine provides interoperability between a massive range of formats, containers, extensions, protocols, encoders, decoders, hardware accelerations, and more.
One method of using FFmpeg is low-level bindings to the code used inside the CLI itself -- there are good crates in the Rust ecosystem that do this.
Low level bindings have drawbacks, though:
By wrapping the CLI, this crate avoids those downsides, and also solves some of the pain points that you would encounter if you were to use the CLI directly on its own:
The only remaining downside is the size of the FFmpeg binary itself, but it's less than 100MB when zipped. It can be automatically downloaded by the crate, so you may choose to not even ship it with your own application and instead download it at runtime.
On the Rust side, it has zero Cargo dependencies! ๐
console
cargo add ffmpeg-sidecar
To automatically download & install a FFmpeg binary for your platform (Windows, MacOS, and Linux), call this function anywhere in your program:
rust
ffmpeg_sidecar::download::auto_download().unwrap();
You can do this once to set up your dev environment, or include it as a feature of your client application.
To customize or extend the download, see
/examples/download_ffmpeg.rs
.
Read raw video frames.
```rust use ffmpeg_sidecar::{command::FfmpegCommand, error::Result, event::FfmpegEvent};
fn main() -> Result<()> {
FfmpegCommand::new() // <- Builder API like std::process::Command
.testsrc() // <- Discoverable aliases for FFmpeg args
.rawvideo() // <- Convenient argument presets
.spawn()? // <- Uses an ordinary std::process::Child
.iter()? // <- Iterator over all log messages and video output
.foreach(|event: FfmpegEvent| {
match event {
FfmpegEvent::OutputFrame(frame) => {
println!("frame: {}x{}", frame.width, frame.height);
let _pixels: Vec
Source: /examples/hello_world.rs
console
cargo run --example hello-world
Decode H265, modify the decoded frames, and then write back to H265.
Source: /examples/h265_transcode.rs
console
cargo run --example h265_transcode
Pipe an FFmpeg instance to FFplay for debugging purposes.
Source: /examples/ffplay_preview.rs
console
cargo run --example ffplay_preview
For a myriad of other examples, check any of the unit tests in /src/test.rs in this repo.
/examples
ffplay
for debuggingResult<_, String>
iter()
since
they require consuming stdout
directlyInspired loosely by Node.js
fluent-ffmpeg
, which does
something similar in Javascript.
Uses setup-ffmpeg
for
Github Actions and as a reference for the auto-download behavior.