Wrap a standalone FFmpeg binary in an intuitive Iterator interface. 🏍

Related tags

Video ffmpeg-sidecar
Overview

FFmpeg Sidecar 🏍

Wrap a standalone FFmpeg binary in an intuitive Iterator interface.

Motivation

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.

Why CLI?

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:

  • Difficult, time-consuming build, toolchain, and dependencies, especially on Windows
  • Complexity, especially for beginners
  • You end up manually re-implementing a lot of the standard conversions you need from scratch

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:

  • Raw data can easily move in and out of FFmpeg instances, or piped between them. Under the hood they are moving across stdin and stdout.
  • Rich semantic information is recovered from the ffmpeg stderr logs, including:
    • Progress updates (frame #, timestamp, speed, bitrate, ...)
    • Input/output metadata and stream mappings
    • Warnings & errors
  • Argument presets and aliases with discoverable names through Intellisense/autocomplete

The only remaining downside is the size of the FFmpeg binary itself, but it's less than 100MB when zipped.

Getting started

1. Download FFmpeg

First you need an FFmpeg binary. If you don't already have one, head to https://ffmpeg.org. Either install it globally (e.g. add to PATH on windows), or simply place the executable adjacent to your Rust binary target. When you package and distribute

2. Cargo install

On the Rust side, it has zero Cargo dependencies! πŸŽ‰

cargo add ffmpeg-sidecar

Examples

Hello world πŸ‘‹

Read raw video frames.

use ffmpeg_sidecar::{
  child::FfmpegChild, command::FfmpegCommand, event::FfmpegEvent, iter::FfmpegIterator,
};

/// Iterates over the frames of a testsrc.
fn main() {
  // similar to `std::process::Command`
  let mut command = FfmpegCommand::new();
  command
    .testsrc() // generate a test pattern video
    .rawvideo(); // pipe raw video output

  // similar to `std::process::Child`
  let mut child: FfmpegChild = command.spawn().unwrap();

  // Iterator over all messages and output
  let iter: FfmpegIterator = child.iter().unwrap();
  iter.for_each(|event: FfmpegEvent| {
    match event {
      FfmpegEvent::OutputFrame(frame) => {
        let _pixels = frame.data; // <- raw RGB pixels! 🎨
      }
      FfmpegEvent::Error(e) => eprintln!("Error: {}", e),
      _ => {}
    }
  });
}

Source: /examples/hello_world.rs

cargo run --example hello-world

H265 Transcoding

Decode H265, modify the decoded frames, and then write back to H265.

Source: /examples/h265_transcode.rs

cargo run --example h265_transcode

FFplay

Pipe an FFmpeg instance to FFplay for debugging purposes.

Source: /examples/ffplay_preview.rs

cargo run --example ffplay_preview

Others

For a myriad of other examples, check any of the unit tests in /src/test.rs in this repo.

Todo

  • Add /examples
  • Take input from stdin, and pipe between iterators
  • Pipe directly to ffplay for debugging
  • Idiomatic error type instead of Result<_, String>
  • Handle indeterminate output formats like H264/H265
    • Currently these formats are mutually exclusive with using iter() since they require consuming stdout directly

πŸ“£ Pull requests are welcome!

See also

Inspired loosely by Node.js fluent-ffmpeg, which does something similar in Javascript.

You might also like...
wrap errors with automatic backtrace capture and print-on-result-unwrap

backtrace-error This is a tiny crate that provides a tiny error-wrapper struct BacktraceError with only two features: Captures a backtrace on From-con

A simple library with just one struct which is used to wrap around pointers

A simple library with just one struct which is used to wrap around pointers. This can be used to create pointers and share them across threads without the hassle of synchronization if you really do not care about that.

A standalone libp2p rendezvous server binary.

Standalone Rendezvous Server A standalone libp2p rendezvous server binary. Usage Run the rendezvous_server: rendezvous_server --secret-file PATH-TO-S

A standalone Command Line Interface debugging tool for The Witcher 3 written in Rust
A standalone Command Line Interface debugging tool for The Witcher 3 written in Rust

A standalone Command Line Interface debugging tool for The Witcher 3 written in Rust. This tool is intended for Witcher 3 modders who make mainly scri

ffmpeg libraries precompiled for WebAsembly/WASI, as a Rust crate.

FFMPEG crate for WebAssembly/WASI This crate bundles FFMPEG's libraries, precompiled for WebAssembly. No native installation required. Compatible with

rsmpeg is a thin&safe layer above the FFmpeg's Rust bindings
rsmpeg is a thin&safe layer above the FFmpeg's Rust bindings

A Rust crate that exposes FFmpeg's power as much as possible.

πŸ“Ό Wrapper around ffmpeg which simplifies merging of multiple videos
πŸ“Ό Wrapper around ffmpeg which simplifies merging of multiple videos

Vidmerger A wrapper around ffmpeg which simplifies merging of multiple videos. πŸ™‰ What is this exactly? Vidmerger is a command-line-tool which uses ff

A ffmpeg/rust based HLS stream generator
A ffmpeg/rust based HLS stream generator

hls-streamer Stream your heart's content with HLS. Movtivation I've got a CCTV camera from AliExpress, I know I can use ffmpeg hls demuxer to split up

AV1 encoding tool with fast VMAF sampling. Uses svt-av1, ffmpeg & vmaf
AV1 encoding tool with fast VMAF sampling. Uses svt-av1, ffmpeg & vmaf

ab-av1 AV1 encoding tool with fast VMAF sampling. Uses svt-av1, ffmpeg & vmaf. Command: auto-encode Automatically determine the best crf to deliver th

GBS/LSDj visualizer based on SameBoy and FFmpeg
GBS/LSDj visualizer based on SameBoy and FFmpeg

GBPresenter GBPresenter is a tool I wrote to generate visualizations of GameBoy chiptunes, based on SameBoy, FFmpeg, and Slint. The visualization desi

Rust port of ffmpeg's native AAC encoder

raash πŸͺ‡ An attempt at RIIR-ing the native AAC encoder from ffmpeg. First, I used c2rust to translate all relevant C code into Rust, and I'm in the pr

Rust Parallel Iterator With Output Sequential Consistency

par_iter_sync: Parallel Iterator With Sequential Output Crate like rayon do not offer synchronization mechanism. This crate provides easy mixture of p

A syntax exploration of eventually stable Rust Iterator items

Rust Iterator Items: a syntax exploration This crate is a thin wrapper around the unstable generator feature, allowing users to create new items that

 An iterator following a space-filling pattern over a given range
An iterator following a space-filling pattern over a given range

rlp-iter rlp-iter (Resolving Lattice Point Iterator) is an iterator that returns a space-filling permutation of integers in a given range. Specificall

Parallel iterator processing library for Rust

Parallel iterator processing library for Rust I keep needing one, so I wrote it. See [IteratorExt] for supported operations. In essence, if you have:

A more free Rust-Iterator.
A more free Rust-Iterator.

CURSOR A more free Rust-Iterator. | Examples | Docs | Latest Note | [dependencies] cursor = "1.0.0" Example use cursor::*; fn example7() - u8 {

Peekable iterator that allows to peek the next N elements without consuming them.

peekaboo docs - crates.io Peekable iterator that allows to peek the next N elements without consuming them. It's no_std compatible by default. It also

A lending iterator trait based on generic associated types and higher-rank trait bounds

A lending iterator trait based on higher-rank trait bounds (HRTBs) A lending iterator is an iterator which lends mutable borrows to the items it retur

A rust crate can find first `Err` in `IteratorResultT, E` and iterating continuously, without allocation.

Api Document first-err Find the first Err in IteratorResultT, E and allow iterating continuously. This crate is specifically designed to replace t

Releases(v0.2)
Owner
Nathan Babcock
Building a GPU-accelerated computer vision app at https://hypetrigger.io
Nathan Babcock
ffmpeg libraries precompiled for WebAsembly/WASI, as a Rust crate.

FFMPEG crate for WebAssembly/WASI This crate bundles FFMPEG's libraries, precompiled for WebAssembly. No native installation required. Compatible with

Frank Denis 45 Dec 14, 2022
rsmpeg is a thin&safe layer above the FFmpeg's Rust bindings

A Rust crate that exposes FFmpeg's power as much as possible.

Lark Technologies Pte. Ltd. 384 Jan 2, 2023
πŸ“Ό Wrapper around ffmpeg which simplifies merging of multiple videos

Vidmerger A wrapper around ffmpeg which simplifies merging of multiple videos. ?? What is this exactly? Vidmerger is a command-line-tool which uses ff

Thomas Gotwig 51 Dec 16, 2022
A ffmpeg/rust based HLS stream generator

hls-streamer Stream your heart's content with HLS. Movtivation I've got a CCTV camera from AliExpress, I know I can use ffmpeg hls demuxer to split up

null 16 Jan 9, 2023
AV1 encoding tool with fast VMAF sampling. Uses svt-av1, ffmpeg & vmaf

ab-av1 AV1 encoding tool with fast VMAF sampling. Uses svt-av1, ffmpeg & vmaf. Command: auto-encode Automatically determine the best crf to deliver th

Alex Butler 92 Jan 1, 2023
A fork of the abandoned ffmpeg-next crate which is a fork of the abandoned ffmpeg crate

This is a fork of the abandoned ffmpeg-next crate which is a fork of the abandoned ffmpeg crate. Currently supported FFmpeg versions: 4.x, 5.x. Build

Josh Holmer 4 Jan 26, 2023
This is a lightweight audio-video player built in Rust using FFmpeg libraries. It demonstrates the usage of FFmpeg with Rust to play back video files.

FFmpeg Rust Video Player This is a lightweight audio-video player built in Rust using FFmpeg libraries. It demonstrates the usage of FFmpeg with Rust

Jenin Sutradhar 3 Apr 10, 2024
Extra iterator adaptors, iterator methods, free functions, and macros.

Itertools Extra iterator adaptors, functions and macros. Please read the API documentation here How to use with cargo: [dependencies] itertools = "0.1

null 1.9k Dec 30, 2022
An iterator adapter to peek at future elements without advancing the cursor of the underlying iterator.

multipeek An iterator adapter to peek at future elements without advancing the cursor of the underlying iterator. Check out the documentation for more

Luca Palmieri 20 Jul 16, 2022
πŸ“¦+πŸ¦€=β™₯️ A tool that helps wrap binary releases for easy distribution

Rustwrap A tool that helps wrap binary releases for easy distribution. Currently supporting: npm - npm install -g your-tool will make your binary your

Rusty Ferris Club 7 Dec 15, 2022