ff-filter 0.15.0

Video and audio filter graph operations - the Rust way
Documentation

ff-filter

Apply video and audio transformations without writing FFmpeg filter-graph strings. Build a chain with method calls; the graph description is generated and validated internally.

Project status (as of 2026-06-04): The library foundation is in place. Development continues through avio-editor-demo, a real-world video editing application built on avio, which surfaces bugs and drives API improvements. Pull requests, bug reports, and feature requests are welcome — see the main repository for full context.

Installation

[dependencies]
ff-filter = "0.15"

Building a Filter Chain

use ff_filter::{FilterGraph, ScaleAlgorithm};

let graph = FilterGraph::builder()
    .trim(10.0, 30.0)                           // keep seconds 10–30
    .scale(1280, 720, ScaleAlgorithm::Fast)     // resize to 720p
    .fade_in(0.0, 0.5)                           // 0.5-second fade in at the start
    .fade_out(19.5, 0.5)                         // 0.5-second fade out
    .build()?;

build() checks the configured steps and returns an Err if a value is out of range or the step set is empty. The underlying FFmpeg graph itself is constructed lazily on the first push_video / push_audio call, using the first frame's format.

Available Video Operations

This is a representative selection; see the API docs for the full set (colour grading, blurs, denoise, keying, transitions, text, and more).

Method Effect
trim(start, end) Discard frames outside the given time range (secs)
scale(w, h, algorithm) Resize frames using the given resampling algorithm
fit_to_aspect(w, h, color) Scale to fit w × h, preserving aspect (letterbox)
crop(x, y, w, h) Extract a rectangular region
overlay(x, y) Composite a second video stream at (x, y)
fade_in(start, duration) Fade from black, starting at start (secs)
fade_out(start, duration) Fade to black, starting at start (secs)
rotate(degrees, fill_color) Rotate clockwise; exposed corners filled with color
tone_map(ToneMap::Hable) HDR-to-SDR tone mapping with the selected curve

Available Audio Operations

Method Effect
volume(gain_db) Adjust loudness by the given number of dB
equalizer(bands) Apply a multi-band parametric EQ (Vec<EqBand>)
amix(inputs) Mix multiple audio streams into one

Hardware Acceleration

use ff_filter::{FilterGraph, HwAccel, ScaleAlgorithm};

let graph = FilterGraph::builder()
    .scale(1920, 1080, ScaleAlgorithm::Fast)
    .hardware(HwAccel::Cuda)
    .build()?;

HwAccel selects the device type (Cuda, VideoToolbox, or Vaapi). When hardware is enabled, hwupload / hwdownload filters are inserted around the chain automatically.

Using the Filter Graph

// Push decoded frames into input slot 0 and pull transformed frames out.
while let Some(input_frame) = decoder.decode_frame()? {
    graph.push_video(0, &input_frame)?;
    while let Some(output_frame) = graph.pull_video()? {
        encoder.push_video(&output_frame)?;
    }
}

Multi-input filters (such as xfade or overlay) read from additional slots: push clip A frames to slot 0 and clip B frames to slot 1.

Error Handling

Variant When it occurs
FilterError::InvalidConfig A configured value is out of range (returned by build())
FilterError::BuildFailed No steps were added, or the FFmpeg graph cannot be built
FilterError::InvalidInput A frame was pushed to an out-of-range input slot
FilterError::ProcessFailed A push or pull operation failed
FilterError::Ffmpeg An underlying FFmpeg function returned an error code
FilterError::CompositionFailed A multi-track composition or mixing operation failed
FilterError::AnalysisFailed An analysis operation (e.g. loudness measurement) failed

MSRV

Rust 1.93.0 (edition 2024).

License

MIT OR Apache-2.0