ff-encode 0.1.0

Video and audio encoding - the Rust way
docs.rs failed to build ff-encode-0.1.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: ff-encode-0.5.0

ff-encode

Safe, high-level video and audio encoding — no unsafe code required, LGPL-compliant by default.

Overview

All APIs are safe — FFmpeg internals are fully encapsulated so you never need to write unsafe code.

⚖️ License & Commercial Use

This crate is designed for commercial use without licensing fees.

Default Behavior (LGPL-Compatible) ✅

By default, ff-encode only uses LGPL-compatible encoders, making it safe for commercial use:

  • Free for commercial use - No licensing fees
  • No royalty payments required
  • Safe for proprietary software
  • No GPL contamination

How It Works

When you request H.264 or H.265 encoding, the crate automatically selects encoders in this priority:

  1. Hardware encoders (LGPL-compatible):

    • NVIDIA NVENC (h264_nvenc, hevc_nvenc)
    • Intel Quick Sync Video (h264_qsv, hevc_qsv)
    • AMD AMF/VCE (h264_amf, hevc_amf)
    • Apple VideoToolbox (h264_videotoolbox, hevc_videotoolbox)
    • VA-API (h264_vaapi, hevc_vaapi) - Linux
  2. Fallback to royalty-free codecs:

    • H.264 → VP9 (libvpx-vp9)
    • H.265 → AV1 (libaom-av1)

GPL Feature ⚠️

The gpl feature enables libx264/libx265 software encoders, which require licensing fees for commercial distribution:

# WARNING: Requires GPL compliance and MPEG LA licensing for commercial use

ff-encode = { version = "0.1", features = ["gpl"] }

Only enable gpl if:

  • ✅ You have appropriate licenses from MPEG LA, or
  • ✅ Your software is GPL-licensed (open source), or
  • ✅ For non-commercial/educational use only

📦 Installation

[dependencies]

# Default: LGPL-compatible (commercial use OK)

ff-encode = "0.1"



# With GPU acceleration (recommended)

ff-encode = { version = "0.1", features = ["hwaccel"] }



# With GPL codecs (requires licensing)

ff-encode = { version = "0.1", features = ["gpl"] }

🚀 Quick Start

use ff_encode::{VideoEncoder, VideoCodec, AudioCodec};

// Create encoder - will automatically use LGPL-compatible encoder
let mut encoder = VideoEncoder::create("output.mp4")?
    .video(1920, 1080, 30.0)
    .video_codec(VideoCodec::H264)  // Will use hardware or VP9
    .audio(48000, 2)
    .audio_codec(AudioCodec::Aac)
    .build()?;

// Verify LGPL compliance
println!("Encoder: {}", encoder.actual_video_codec());
println!("LGPL compliant: {}", encoder.is_lgpl_compliant());

// Encode frames
for frame in video_frames {
    encoder.push_video(&frame)?;
}

encoder.finish()?;

🔍 Checking Compliance at Runtime

let encoder = VideoEncoder::create("output.mp4")?
    .video(1920, 1080, 30.0)
    .video_codec(VideoCodec::H264)
    .build()?;

if encoder.is_lgpl_compliant() {
    println!("✓ Safe for commercial use: {}", encoder.actual_video_codec());
} else {
    println!("⚠ GPL encoder (requires licensing): {}", encoder.actual_video_codec());
}

Example outputs:

  • ✓ Safe for commercial use: h264_nvenc - NVIDIA hardware encoder
  • ✓ Safe for commercial use: libvpx-vp9 - VP9 fallback
  • ⚠ GPL encoder: libx264 - Requires licensing (only with gpl feature)

📚 Features

Video Codecs

  • H.264/AVC - Most compatible (auto-selects hardware or VP9 fallback)
  • H.265/HEVC - High compression (auto-selects hardware or AV1 fallback)
  • VP9 - Google's royalty-free codec (LGPL-compatible)
  • AV1 - Next-gen royalty-free codec (LGPL-compatible)
  • ProRes - Apple's professional codec
  • DNxHD - Avid's professional codec

Audio Codecs

  • AAC - Most compatible
  • Opus - High quality, low latency
  • MP3 - Universal compatibility
  • FLAC - Lossless
  • PCM - Uncompressed

Hardware Acceleration

All hardware encoders are LGPL-compatible:

use ff_encode::HardwareEncoder;

let encoder = VideoEncoder::create("output.mp4")?
    .video(1920, 1080, 60.0)
    .hardware_encoder(HardwareEncoder::Nvenc)  // Force NVIDIA
    .build()?;

// Check available hardware
for hw in HardwareEncoder::available() {
    println!("Available: {:?}", hw);
}

⚡ Performance

Encoding Presets

use ff_encode::Preset;

let encoder = VideoEncoder::create("output.mp4")?
    .video(1920, 1080, 30.0)
    .preset(Preset::Fast)      // Faster encoding, larger file
    .build()?;

Available presets:

  • Ultrafast - Fastest, lowest quality
  • Fast / Faster - Good for real-time
  • Medium - Default, balanced
  • Slow / Slower / Veryslow - Best quality

Quality Control

// Constant bitrate
let encoder = VideoEncoder::create("output.mp4")?
    .video(1920, 1080, 30.0)
    .video_bitrate(8_000_000)  // 8 Mbps
    .build()?;

// Constant quality (CRF)
let encoder = VideoEncoder::create("output.mp4")?
    .video(1920, 1080, 30.0)
    .video_quality(23)  // 0-51, lower = better
    .build()?;

📊 Progress Tracking

use ff_encode::Progress;

let encoder = VideoEncoder::create("output.mp4")?
    .video(1920, 1080, 30.0)
    .on_progress(|progress: Progress| {
        println!("Progress: {:.1}%", progress.percent());
        println!("Frames: {} / {}",
            progress.frames_encoded,
            progress.total_frames.unwrap_or(0)
        );
    })
    .build()?;

🛡️ Safety & Error Handling

All operations use proper error types:

use ff_encode::EncodeError;

match VideoEncoder::create("output.mp4") {
    Ok(builder) => { /* ... */ },
    Err(EncodeError::CannotCreateFile { path }) => {
        eprintln!("Cannot create: {}", path.display());
    },
    Err(EncodeError::NoSuitableEncoder { codec, tried }) => {
        eprintln!("No encoder for {}, tried: {:?}", codec, tried);
    },
    Err(e) => eprintln!("Error: {}", e),
}

🔧 Advanced Usage

Force VP9 (Always LGPL-Compatible)

let encoder = VideoEncoder::create("output.webm")?
    .video(1920, 1080, 30.0)
    .video_codec(VideoCodec::Vp9)  // Explicit VP9
    .build()?;

Disable Hardware Acceleration

let encoder = VideoEncoder::create("output.mp4")?
    .video(1920, 1080, 30.0)
    .hardware_encoder(HardwareEncoder::None)  // Software only
    .build()?;
// Will use VP9 or AV1 (LGPL-compatible)

📜 License

This crate: MIT OR Apache-2.0

FFmpeg: LGPL 2.1+ (or GPL 2+ with gpl feature)

Important: The default configuration (without gpl feature) is LGPL-compliant and safe for commercial use without licensing fees.

❓ FAQ

Q: Can I use this in my commercial product?

A: Yes! By default (without the gpl feature), all encoders are LGPL-compatible and free for commercial use.

Q: What if I need libx264/libx265?

A: Enable the gpl feature, but be aware:

  • You must comply with GPL license terms, or
  • Obtain commercial licenses from MPEG LA for H.264/H.265

Q: What's the quality difference between hardware and software encoding?

A: Modern hardware encoders (NVENC, QSV) have excellent quality, often comparable to software encoders at similar bitrates. VP9 and AV1 provide better compression than H.264 but require more CPU time.

Q: Which hardware encoder should I use?

A: Use HardwareEncoder::Auto (default) to automatically select the best available hardware encoder. The encoder will try NVENC → QSV → AMF → VideoToolbox in order.

🔗 See Also