Skip to main content

Output

Struct Output 

Source
pub struct Output { /* private fields */ }

Implementations§

Source§

impl Output

Source

pub fn add_attachment(self, path: impl Into<PathBuf>) -> Self

Embeds a file as a container attachment stream (FFmpeg -attach), e.g. a .ttf/.otf font for Matroska subtitle rendering, or cover art.

The MIME type is guessed from the file extension (.ttfapplication/x-truetype-font, .otfapplication/vnd.ms-opentype, otherwise application/octet-stream). Use add_attachment_with_mimetype to set it explicitly.

§Behavior & limitations
  • Local files only. The path is read with std::fs at build time, so protocol URLs (http:, pipe:, …) are not supported here (unlike some FFmpeg inputs). A missing, unreadable, empty, or oversized file surfaces as an Err from FfmpegContext build — never a panic. The setter itself does no I/O and never fails.
  • Muxer support. Attachments are supported only by Matroska/WebM (.mkv/.webm). MP4, MOV, MPEG-TS and other muxers do not accept a generic attachment stream and will reject the job at header-write time (surfacing as an Err from the running job, not a panic).
  • Must be used alongside at least one mapped/encoded stream: an output whose only stream is an attachment is not supported.
§Example
let output = Output::from("output.mkv")
    .add_stream_map("0:v")
    .add_attachment("assets/DejaVuSans.ttf");
Source

pub fn add_attachment_with_mimetype( self, path: impl Into<PathBuf>, mimetype: impl Into<String>, ) -> Self

Same as add_attachment but with an explicit MIME type (e.g. "application/x-truetype-font", "image/png") instead of guessing from the extension.

An empty mimetype is rejected at build time (Matroska requires a non-empty mimetype tag for every attachment).

§Example
let output = Output::from("output.mkv")
    .add_stream_map("0:v")
    .add_attachment_with_mimetype("cover.png", "image/png");
Source§

impl Output

Source

pub fn set_video_bsf(self, bsf_chain: impl Into<String>) -> Self

Sets the bitstream-filter chain for the video output stream(s), equivalent to FFmpeg -bsf:v.

Bitstream filters transform encoded packets without decoding them (e.g. rewriting NAL headers). The chain runs in the mux stage — after stream copy or encoding, before the packet is written — matching the FFmpeg CLI.

§Arguments
  • bsf_chain - A single BSF name (e.g. "h264_mp4toannexb") or a comma-separated chain with per-filter options (e.g. "hevc_metadata=aud=insert,extract_extradata"), parsed by FFmpeg’s av_bsf_list_parse_str. An empty string clears any previously set video BSF.
§Returns
  • Self - Returns the modified Output, allowing for method chaining.
§Examples
// Convert H.264 from MP4 (length-prefixed) to Annex B for MPEG-TS.
let output = Output::from("output.ts")
    .set_format("mpegts")
    .add_stream_map_with_copy("0:v")
    .set_video_bsf("h264_mp4toannexb");
Source

pub fn set_audio_bsf(self, bsf_chain: impl Into<String>) -> Self

Sets the bitstream-filter chain for the audio output stream(s), equivalent to FFmpeg -bsf:a.

See set_video_bsf for the chain syntax; an empty string clears any previously set audio BSF.

§Examples
let output = Output::from("output.aac")
    .add_stream_map_with_copy("0:a")
    .set_audio_bsf("aac_adtstoasc");
Source

pub fn set_subtitle_bsf(self, bsf_chain: impl Into<String>) -> Self

Sets the bitstream-filter chain for the subtitle output stream(s), equivalent to FFmpeg -bsf:s.

See set_video_bsf for the chain syntax; an empty string clears any previously set subtitle BSF.

Source§

impl Output

Source

pub fn set_video_codec_opt( self, key: impl Into<String>, value: impl Into<String>, ) -> Self

Sets a video codec-specific option.

These options control video encoding parameters such as compression, quality, and speed.

Supported Parameters:

ParameterDescription
crf=0-51Quality level for x264/x265, lower means higher quality (0 is lossless)
preset=ultrafast, superfast, fast, medium, slow, veryslowEncoding speed, affects compression efficiency
tune=film, animation, grain, stillimage, fastdecode, zerolatencyOptimizations for specific types of content
b=4MBitrate (e.g., 4M for 4 Mbps)
g=50GOP (Group of Pictures) size, affects keyframe frequency

Example Usage:

let output = Output::from("some_url")
    .set_video_codec_opt("crf", "18")
    .set_video_codec_opt("preset", "fast");
Source

pub fn set_video_codec_opts( self, opts: Vec<(impl Into<String>, impl Into<String>)>, ) -> Self

Sets multiple video codec options at once.

Example Usage:

let output = Output::from("some_url")
    .set_video_codec_opts(vec![
        ("crf", "18"),
        ("preset", "fast")
    ]);
Source

pub fn set_audio_codec_opt( self, key: impl Into<String>, value: impl Into<String>, ) -> Self

Sets a audio codec-specific option.

These options control audio encoding parameters such as bitrate, sample rate, and format.

Supported Parameters:

ParameterDescription
b=192kBitrate (e.g., 128k for 128 Kbps, 320k for 320 Kbps)
compression_level=0-12Compression efficiency for formats like FLAC

Example Usage:

let output = Output::from("some_url")
    .set_audio_codec_opt("b", "320k")
    .set_audio_codec_opt("compression_level", "6");
Source

pub fn set_audio_codec_opts( self, opts: Vec<(impl Into<String>, impl Into<String>)>, ) -> Self

Sets multiple audio codec options at once.

Example Usage:

let output = Output::from("some_url")
    .set_audio_codec_opts(vec![
        ("b", "320k"),
        ("compression_level", "6")
    ]);
Source

pub fn set_subtitle_codec_opt( self, key: impl Into<String>, value: impl Into<String>, ) -> Self

Sets a subtitle codec-specific option.

These options control subtitle encoding parameters such as format and character encoding.

Supported Parameters:

ParameterDescription
mov_textSubtitle format for MP4 files
srtSubtitle format for .srt files
assAdvanced SubStation Alpha (ASS) subtitle format
forced_subs=1Forces the subtitles to always be displayed

Example Usage:

let output = Output::from("some_url")
    .set_subtitle_codec_opt("mov_text", "");
Source

pub fn set_subtitle_codec_opts( self, opts: Vec<(impl Into<String>, impl Into<String>)>, ) -> Self

Sets multiple subtitle codec options at once.

Example Usage:

let output = Output::from("some_url")
    .set_subtitle_codec_opts(vec![
        ("mov_text", ""),
        ("forced_subs", "1")
    ]);
Source

pub fn set_format_opt( self, key: impl Into<String>, value: impl Into<String>, ) -> Self

Sets a format-specific option for the output container.

FFmpeg supports various format-specific options that can be passed to the muxer. These options allow fine-tuning of the output container’s behavior.

Example Usage:

let output = Output::from("some_url")
    .set_format_opt("movflags", "faststart")
    .set_format_opt("flvflags", "no_duration_filesize");
§Common Format Options:
FormatOptionDescription
mp4movflags=faststartMoves moov atom to the beginning of the file for faster playback start
flvflvflags=no_duration_filesizeRemoves duration/size metadata for live streaming

Parameters:

  • key: The format option name (e.g., "movflags", "flvflags").
  • value: The value to set (e.g., "faststart", "no_duration_filesize").

Returns the modified Output struct for chaining.

Source

pub fn set_format_opts( self, opts: Vec<(impl Into<String>, impl Into<String>)>, ) -> Self

Sets multiple format-specific options at once.

This method allows setting multiple format options in a single call.

Example Usage:

let output = Output::from("some_url")
    .set_format_opts(vec![
        ("movflags", "faststart"),
        ("flvflags", "no_duration_filesize")
    ]);

Parameters:

  • opts: A vector of key-value pairs representing format options.

Returns the modified Output struct for chaining.

Source§

impl Output

Source

pub fn add_metadata( self, key: impl Into<String>, value: impl Into<String>, ) -> Self

Add or update global metadata for the output file.

If value is empty string, the key will be removed (FFmpeg behavior). Replicates FFmpeg’s -metadata key=value option.

FFmpeg reference: fftools/ffmpeg_opt.c (opt_metadata() handles -metadata key=value).

§Examples
let output = Output::from("output.mp4")
    .add_metadata("title", "My Video")
    .add_metadata("author", "John Doe");
Source

pub fn add_metadata_map(self, metadata: HashMap<String, String>) -> Self

Add multiple global metadata entries at once.

FFmpeg reference: fftools/ffmpeg_opt.c (consecutive -metadata invocations append to the same dictionary; this helper simply batches the calls on the Rust side).

§Examples
let mut metadata = HashMap::new();
metadata.insert("title".to_string(), "My Video".to_string());
metadata.insert("author".to_string(), "John Doe".to_string());

let output = Output::from("output.mp4")
    .add_metadata_map(metadata);
Source

pub fn remove_metadata(self, key: &str) -> Self

Remove a global metadata key.

FFmpeg reference: fftools/ffmpeg_opt.c (-metadata key= deletes the key when value is empty; we follow the same rule by interpreting an empty string as removal).

§Examples
let output = Output::from("output.mp4")
    .add_metadata("title", "My Video")
    .remove_metadata("title");  // Remove the title
Source

pub fn clear_all_metadata(self) -> Self

Clear all metadata (global, stream, chapter, program) and mappings.

Useful when you want to start fresh without any metadata.

FFmpeg reference: fftools/ffmpeg_opt.c (users typically issue -map_metadata -1 and then reapply -metadata options; this helper emulates that workflow programmatically).

§Examples
let output = Output::from("output.mp4")
    .add_metadata("title", "My Video")
    .clear_all_metadata();  // Remove all metadata
Source

pub fn disable_auto_copy_metadata(self) -> Self

Disable automatic metadata copying from input files.

By default, FFmpeg automatically copies global and stream metadata from input files to output. This method disables that behavior, similar to FFmpeg’s -map_metadata -1 option. FFmpeg reference: ffmpeg_mux_init.c (copy_meta() sets metadata_global_manual when -map_metadata -1 is used; auto_copy_metadata mirrors the same flag).

§Examples
let output = Output::from("output.mp4")
    .disable_auto_copy_metadata()  // Don't copy any metadata from input
    .add_metadata("title", "New Title");  // Only use explicitly set metadata
Source

pub fn add_stream_metadata( self, stream_spec: impl Into<String>, key: impl Into<String>, value: impl Into<String>, ) -> Result<Self, String>

Add or update stream-specific metadata.

Uses FFmpeg’s stream specifier syntax to identify target streams. If value is empty string, the key will be removed (FFmpeg behavior). Replicates FFmpeg’s -metadata:s:spec key=value option.

FFmpeg reference: fftools/ffmpeg_opt.c (opt_metadata() with stream specifiers, lines 2465-2520 in FFmpeg 7.x).

§Stream Specifier Syntax
  • "v:0" - First video stream
  • "a:1" - Second audio stream
  • "s" - All subtitle streams
  • "v" - All video streams
  • "p:0:v" - Video streams in program 0
  • "#0x100" or "i:256" - Stream with specific ID
  • "m:language:eng" - Streams with metadata language=eng
  • "u" - Usable streams only
  • "disp:default" - Streams with default disposition
§Examples
let output = Output::from("output.mp4")
    .add_stream_metadata("v:0", "language", "eng")
    .add_stream_metadata("a:0", "title", "Main Audio");
§Errors

Returns error if the stream specifier syntax is invalid.

Source

pub fn add_chapter_metadata( self, chapter_index: usize, key: impl Into<String>, value: impl Into<String>, ) -> Self

Add or update chapter-specific metadata.

Chapters are used for DVD-like navigation points in media files. If value is empty string, the key will be removed (FFmpeg behavior). Replicates FFmpeg’s -metadata:c:N key=value option. FFmpeg reference: fftools/ffmpeg_opt.c (opt_metadata() handles the c: target selector).

§Examples
let output = Output::from("output.mp4")
    .add_chapter_metadata(0, "title", "Introduction")
    .add_chapter_metadata(1, "title", "Main Content");
Source

pub fn add_program_metadata( self, program_index: usize, key: impl Into<String>, value: impl Into<String>, ) -> Self

Add or update program-specific metadata.

Programs are used in multi-program transport streams (e.g., MPEG-TS). If value is empty string, the key will be removed (FFmpeg behavior). Replicates FFmpeg’s -metadata:p:N key=value option. FFmpeg reference: fftools/ffmpeg_opt.c (opt_metadata() with p: selector).

§Examples
let output = Output::from("output.ts")
    .add_program_metadata(0, "service_name", "Channel 1")
    .add_program_metadata(1, "service_name", "Channel 2");
Source

pub fn map_metadata_from_input( self, input_index: usize, src_type_spec: impl Into<String>, dst_type_spec: impl Into<String>, ) -> Result<Self, String>

Map metadata from an input file to this output.

Replicates FFmpeg’s -map_metadata [src_file_idx]:src_type:dst_type option. This allows copying metadata from specific locations in input files to specific locations in the output file.

§Type Specifiers
  • "g" or "" - Global metadata
  • "s" or "s:spec" - Stream metadata (with optional stream specifier)
  • "c:N" - Chapter N metadata
  • "p:N" - Program N metadata
§Examples
use ez_ffmpeg::core::metadata::{MetadataType, MetadataMapping};

let output = Output::from("output.mp4")
    // Copy global metadata from input 0 to output global
    .map_metadata_from_input(0, "g", "g")?
    // Copy first video stream metadata from input 1 to output first video stream
    .map_metadata_from_input(1, "s:v:0", "s:v:0")?;
§Errors

Returns error if the type specifier syntax is invalid. FFmpeg reference: fftools/ffmpeg_opt.c (opt_map_metadata() parses the same [file][:type] triplet and feeds it into MetadataMapping).

Source§

impl Output

Source

pub fn new(url: impl Into<String>) -> Self

Source

pub fn new_by_write_callback<F>(write_callback: F) -> Self
where F: FnMut(&[u8]) -> i32 + Send + 'static,

Creates a new Output instance with a custom write callback and format string.

This method initializes an Output object that uses a provided write_callback function to handle the encoded data being written to the output stream. You can optionally specify the desired output format via the format method.

§Parameters:
  • write_callback: fn(buf: &[u8]) -> i32: A function that processes the provided buffer of encoded data and writes it to the destination. The function should return the number of bytes successfully written (positive value) or a negative value in case of error.
§Return Value:
  • Returns a new Output instance configured with the specified write_callback function.
§Behavior of write_callback:
  • Positive Value: Indicates the number of bytes successfully written.
  • Negative Value: Indicates an error occurred. For example:
    • ffmpeg_sys_next::AVERROR(ffmpeg_sys_next::EIO): Represents an input/output error.
    • Other custom-defined error codes can also be returned to signal specific issues.
§Example:
let output = Output::new_by_write_callback(move |buf| {
    println!("Processing {} bytes of data for output", buf.len());
    buf.len() as i32 // Return the number of bytes processed
})
.set_format("mp4");
Source

pub fn set_io_buffer_size(self, size: usize) -> Self

Sets the AVIO buffer size, in bytes, for a custom write_callback output.

FFmpeg hands one buffer-sized chunk per callback, so a larger buffer means fewer Rust↔FFmpeg round-trips for sequential or network sinks. Only applies when the output is a callback (no URL); ignored otherwise. The default is 64 KiB, which keeps first-packet latency low for live use.

§Errors

The value is validated when the context is built: FfmpegContext::builder().build() fails with OpenOutputError::InvalidOption if size is 0 or exceeds i32::MAX (FFmpeg’s avio_alloc_context takes an int buffer size).

Source

pub fn set_max_muxing_queue_size(self, size: usize) -> Self

Sets the per-stream packet cap of the pre-mux queue (FFmpeg -max_muxing_queue_size parity; default 128).

Until the muxer starts (it waits for every mapped output stream to become ready), each encoder parks its packets in a per-stream queue. The cap only applies once the queue’s byte threshold (set_muxing_queue_data_threshold) is exceeded — below it, packet count is unlimited. Raise this (or the byte threshold) if a job fails with a pre-mux backpressure error, e.g. a sparse subtitle stream whose first packet lands deep into a high-bitrate file.

§Errors

Validated when the context is built: 0 fails with OpenOutputError::InvalidOption.

Source

pub fn set_muxing_queue_data_threshold(self, bytes: usize) -> Self

Sets the per-stream byte threshold below which the pre-mux queue’s packet cap does not apply (FFmpeg -muxing_queue_data_threshold parity; default 50 MiB).

This is a trigger, not a hard byte cap: below the threshold the packet count is unbounded, and above it admission stops at max_muxing_queue_size. Together they bound how much a fast encoder parks before the muxer starts, which doubles as the demux read-ahead window: jobs that must read further ahead (late first packet on one mapped stream) need a larger threshold (and/or packet cap).

§Errors

Validated when the context is built: 0 fails with OpenOutputError::InvalidOption.

Source

pub fn set_seek_callback<F>(self, seek_callback: F) -> Self
where F: FnMut(i64, i32) -> i64 + Send + 'static,

Sets a custom seek callback for the output stream.

This function assigns a user-defined function that handles seeking within the output stream. Seeking is required for certain formats (e.g., mp4, mkv) where metadata or index information needs to be updated at specific positions in the file.

Why is seek_callback necessary?

  • Some formats (e.g., MP4) require seek operations to update metadata (moov, mdat).
  • If no seek_callback is provided for formats that require seeking, FFmpeg will fail with:
    [mp4 @ 0x...] muxer does not support non seekable output
  • For streaming formats (flv, ts, rtmp, hls), seeking is not required.

FFmpeg may invoke seek_callback from different threads.

  • If using a File as the output, wrap it in Arc<Mutex<File>> to ensure thread-safe access.
§Parameters:
  • seek_callback: FnMut(i64, i32) -> i64
    • offset: i64: The target seek position in the stream.

    • whence: i32: The seek mode determining how offset should be interpreted:

      • ffmpeg_sys_next::SEEK_SET (0): Seek to an absolute position.
      • ffmpeg_sys_next::SEEK_CUR (1): Seek relative to the current position.
      • ffmpeg_sys_next::SEEK_END (2): Seek relative to the end of the output.
      • ffmpeg_sys_next::AVSEEK_SIZE (65536): Query the total size of the stream instead of seeking.

      avio_seek strips ffmpeg_sys_next::AVSEEK_FORCE (131072) from whence before invoking a custom callback; the example masks it anyway as cheap defense. No other whence values reach a custom seek callback.

§Return Value:
  • Positive Value: The new offset position after seeking.
  • Negative Value: An error occurred. Common errors include:
    • ffmpeg_sys_next::AVERROR(ffmpeg_sys_next::ESPIPE): Seek is not supported.
    • ffmpeg_sys_next::AVERROR(ffmpeg_sys_next::EIO): General I/O error.
§Example (Thread-safe seek callback using Arc<Mutex<File>>):

Since FFmpeg may call write_callback and seek_callback from different threads, use Arc<Mutex<File>> to ensure safe concurrent access.

use ez_ffmpeg::Output;
use std::fs::File;
use std::io::{Seek, SeekFrom, Write};
use std::sync::{Arc, Mutex};

// ✅ Create a thread-safe file handle
let file = Arc::new(Mutex::new(File::create("output.mp4").expect("Failed to create file")));

// ✅ Define the write callback (data writing logic)
let write_callback = {
    let file = Arc::clone(&file);
    move |buf: &[u8]| -> i32 {
        let mut file = file.lock().unwrap();
        match file.write_all(buf) {
            Ok(_) => buf.len() as i32,
            Err(e) => {
                println!("Write error: {}", e);
                ffmpeg_sys_next::AVERROR(ffmpeg_sys_next::EIO) as i32
            }
        }
    }
};

// ✅ Define the seek callback (position adjustment logic)
let seek_callback = {
    let file = Arc::clone(&file);
    Box::new(move |offset: i64, whence: i32| -> i64 {
        let mut file = file.lock().unwrap();

        // ✅ Handle AVSEEK_SIZE: FFmpeg asks for the total stream size instead of seeking
        if whence == ffmpeg_sys_next::AVSEEK_SIZE {
            if let Ok(size) = file.metadata().map(|m| m.len() as i64) {
                return size;
            }
            return ffmpeg_sys_next::AVERROR(ffmpeg_sys_next::EIO) as i64;
        }

        // ✅ Defensive: mask AVSEEK_FORCE (avio_seek strips it before a custom
        // callback). The AVIO layer sends no other whence values (lseek extensions
        // like SEEK_HOLE/SEEK_DATA never reach a custom callback).
        match whence & !ffmpeg_sys_next::AVSEEK_FORCE {
            ffmpeg_sys_next::SEEK_SET => file.seek(SeekFrom::Start(offset as u64)),
            ffmpeg_sys_next::SEEK_CUR => file.seek(SeekFrom::Current(offset)),
            ffmpeg_sys_next::SEEK_END => file.seek(SeekFrom::End(offset)),
            _ => return ffmpeg_sys_next::AVERROR(ffmpeg_sys_next::ESPIPE) as i64,
        }.map_or(ffmpeg_sys_next::AVERROR(ffmpeg_sys_next::EIO) as i64, |pos| pos as i64)
    })
};

// ✅ Create an output with both callbacks
let output = Output::new_by_write_callback(write_callback)
    .set_format("mp4")
    .set_seek_callback(seek_callback);
Source

pub fn set_format(self, format: impl Into<String>) -> Self

Sets the output format for the container.

This method allows you to specify the output format for the container. If no format is specified, FFmpeg will attempt to detect it automatically based on the file extension or output URL.

§Parameters:
  • format: &str: A string specifying the desired output format (e.g., mp4, flv, mkv).
§Return Value:
  • Returns the Output instance with the newly set format.
Source

pub fn set_video_codec(self, video_codec: impl Into<String>) -> Self

Sets the video codec to be used for encoding.

§Arguments
  • video_codec - A string slice representing the desired video codec (e.g., "h264", "hevc").
§Returns
  • Self - Returns the modified Output struct, allowing for method chaining.
§Examples
let output = Output::from("rtmp://localhost/live/stream")
    .set_video_codec("h264");
Source

pub fn set_audio_codec(self, audio_codec: impl Into<String>) -> Self

Sets the audio codec to be used for encoding.

§Arguments
  • audio_codec - A string slice representing the desired audio codec (e.g., "aac", "mp3").
§Returns
  • Self - Returns the modified Output struct, allowing for method chaining.
§Examples
let output = Output::from("rtmp://localhost/live/stream")
    .set_audio_codec("aac");
Source

pub fn set_subtitle_codec(self, subtitle_codec: impl Into<String>) -> Self

Sets the subtitle codec to be used for encoding.

§Arguments
  • subtitle_codec - A string slice representing the desired subtitle codec (e.g., "mov_text", "webvtt").
§Returns
  • Self - Returns the modified Output struct, allowing for method chaining.
§Examples
let output = Output::from("rtmp://localhost/live/stream")
    .set_subtitle_codec("mov_text");
Source

pub fn set_frame_pipelines( self, frame_pipelines: Vec<impl Into<FramePipeline>>, ) -> Self

Replaces the entire frame-processing pipeline with a new sequence of transformations for pre-encoding frames on this Output.

This method clears any previously set pipelines and replaces them with the provided list.

§Parameters
  • frame_pipelines - A list of FramePipeline instances defining the transformations to apply before encoding.
§Returns
  • Self - Returns the modified Output, enabling method chaining.
§Example
let output = Output::from("some_url")
    .set_frame_pipelines(vec![
        FramePipelineBuilder::new(AVMediaType::AVMEDIA_TYPE_VIDEO).filter("opengl", Box::new(my_filter)),
        // Additional pipelines...
    ]);
Source

pub fn add_frame_pipeline( self, frame_pipeline: impl Into<FramePipeline>, ) -> Self

Adds a single FramePipeline to the existing pipeline list.

If no pipelines are currently defined, this method creates a new pipeline list. Otherwise, it appends the provided pipeline to the existing transformations.

§Parameters
§Returns
  • Self - Returns the modified Output, enabling method chaining.
§Example
let output = Output::from("some_url")
    .add_frame_pipeline(FramePipelineBuilder::new(AVMediaType::AVMEDIA_TYPE_VIDEO).filter("opengl", Box::new(my_filter)).build())
    .add_frame_pipeline(FramePipelineBuilder::new(AVMediaType::AVMEDIA_TYPE_AUDIO).filter("my_custom_filter1", Box::new(...)).filter("my_custom_filter2", Box::new(...)));
Source

pub fn add_stream_map(self, linklabel: impl Into<String>) -> Self

Adds a stream mapping for a specific stream or stream type, re-encoding it according to this output’s codec settings.

§Linklabel (FFmpeg-like Specifier)

This string typically follows "<input_index>:<media_type>" syntax:

  • "0:v" – the video stream(s) from input #0.
  • "1:a?" – audio from input #1, ignore if none present (due to ?).
  • Other possibilities include "0:s", "0:d", etc. for subtitles/data, optionally with ?.

By calling add_stream_map, you force re-encoding of the chosen stream(s). If the user wants a bit-for-bit copy, see add_stream_map_with_copy.

§Parameters
  • linklabel: An FFmpeg-style specifier referencing the desired input index and media type, like "0:v", "1:a?", etc.
§Returns
  • Self - for chained method calls.
§Example
// Re-encode the video stream from input #0 (fail if no video).
let output = Output::from("output.mp4")
    .add_stream_map("0:v");
Source

pub fn add_stream_map_with_copy(self, linklabel: impl Into<String>) -> Self

Adds a stream mapping for a specific stream or stream type, copying it bit-for-bit from the source without re-encoding.

§Linklabel (FFmpeg-like Specifier)

Follows the same "<input_index>:<media_type>" pattern as add_stream_map:

  • "0:a" – audio stream(s) from input #0.
  • "0:a?" – same, but ignore errors if no audio exists.
  • And so on for video (v), subtitles (s), attachments (t), etc.
§Copy vs. Re-encode

Here, copy = true by default, meaning the chosen stream(s) are passed through without decoding/encoding. This generally only works if the source’s codec is compatible with the container/format you’re outputting to. If you require re-encoding (e.g., to ensure compatibility or apply filters), use add_stream_map.

§Parameters
  • linklabel: An FFmpeg-style specifier referencing the desired input index and media type, like "0:v?".
§Returns
  • Self - for chained method calls.
§Example
// Copy the audio stream(s) from input #0 if present, no re-encode:
let output = Output::from("output.mkv")
    .add_stream_map_with_copy("0:a?");
Source

pub fn set_start_time_us(self, start_time_us: i64) -> Self

Sets the start time (in microseconds) for output encoding.

If this is set, FFmpeg will attempt to start encoding from the specified timestamp in the input stream. This can be used to skip initial content.

§Parameters
  • start_time_us - The start time in microseconds.
§Returns
  • Self - The modified Output, allowing method chaining.
§Example
let output = Output::from("output.mp4")
    .set_start_time_us(2_000_000); // Start at 2 seconds
Source

pub fn set_recording_time_us(self, recording_time_us: i64) -> Self

Sets the recording time (in microseconds) for output encoding.

This indicates how many microseconds of data should be processed (i.e., maximum duration to encode). Once this time is reached, FFmpeg will stop encoding.

§Parameters
  • recording_time_us - The maximum duration (in microseconds) to process.
§Returns
  • Self - The modified Output, allowing method chaining.
§Example
let output = Output::from("output.mp4")
    .set_recording_time_us(5_000_000); // Record for 5 seconds
Source

pub fn set_stop_time_us(self, stop_time_us: i64) -> Self

Sets a stop time (in microseconds) for output encoding.

If set, FFmpeg will stop encoding once the input’s timestamp surpasses this value. Effectively, encoding ends at this timestamp regardless of remaining data.

§Parameters
  • stop_time_us - The timestamp (in microseconds) at which to stop.
§Returns
  • Self - The modified Output, allowing method chaining.
§Example
let output = Output::from("output.mp4")
    .set_stop_time_us(10_000_000); // Stop at 10 seconds
Source

pub fn set_shortest(self, shortest: bool) -> Self

Finish the output when its shortest limiting stream ends (FFmpeg -shortest).

Encoded audio/video are truncated at the frame level before encoding (no B-frame stranding); streamcopy / subtitle / data are truncated at the packet level — the same presentation-time cut FFmpeg makes, with the same limitation that a copy B-frame near the cut may reference a dropped later packet. Exact when the shortest→longest gap is within the buffering window (see set_shortest_buf_duration_us, default 10 s). Default: false.

§Limitations

Any cut stream fed by an input whose read cannot be interrupted mid-packet — a pipe, a custom IO source, a live device, or a readrate-limited (-re) input — may keep that demuxer alive until its in-flight read returns, delaying termination. Ordinary seekable file and network inputs are unaffected, as is a single encoded stream (there is nothing to cut it against).

When a cut stream also has an output bitstream filter that reorders, buffers, or rewrites packet timestamps (e.g. setts, pgs_frame_merge), the packet-level cut is decided on the pre-filter timestamps. Timestamp-preserving 1:1 filters (h264_mp4toannexb, aac_adtstoasc, metadata filters) are unaffected.

§Example
let output = Output::from("output.mp4").set_shortest(true);
Source

pub fn set_shortest_buf_duration_us(self, shortest_buf_duration_us: i64) -> Self

Maximum microseconds one stream is buffered waiting for a lagging peer before it is released anyway (FFmpeg -shortest_buf_duration, expressed in seconds upstream, microseconds here). Bounds -shortest memory use and precision. Values <= 0 are ignored. Default: 10_000_000 (10 s).

§Example
let output = Output::from("output.mp4")
    .set_shortest(true)
    .set_shortest_buf_duration_us(30_000_000); // tolerate a 30 s gap
Source

pub fn set_framerate(self, num: i32, den: i32) -> Self

Sets a target frame rate for output encoding, as a num/den rational (e.g. 30, 1 for 30 FPS).

This can force the output to use a specific frame rate (e.g., 30/1 for 30 FPS). If unset, FFmpeg typically preserves the source frame rate or uses defaults based on the selected codec/container.

§Parameters
  • num: Frame rate numerator (e.g., 30 for 30fps, 24000 for 23.976fps)
  • den: Frame rate denominator (e.g., 1 for 30fps, 1001 for 23.976fps)
§Returns
  • Self - The modified Output, allowing method chaining.
§Errors

The value is validated when the context is built: FfmpegContext::builder().build() fails with OpenOutputError::InvalidOption if num or den is not positive.

§Example
let output = Output::from("output.mp4")
    .set_framerate(30, 1);
Source

pub fn set_framerate_max(self, num: i32, den: i32) -> Self

Sets a maximum frame rate cap for output encoding (-fpsmax).

Unlike set_framerate, this does not force a rate: the output keeps its native frame rate and is only clamped when that rate exceeds the cap or cannot be determined (ffmpeg_filter.c choose_out_timebase).

§Parameters
  • num: Upper-bound numerator (e.g., 30 for a 30fps cap)
  • den: Upper-bound denominator
§Returns
  • Self - The modified Output, allowing method chaining.
§Errors

Validated when the context is built, like set_framerate: non-positive values fail with OpenOutputError::InvalidOption.

§Example
let output = Output::from("output.mp4")
    .set_framerate_max(30, 1);
Source

pub fn set_vsync_method(self, method: VSyncMethod) -> Self

Sets the video sync method to be used during encoding.

FFmpeg uses a variety of vsync policies to handle frame presentation times, dropping/duplicating frames as needed. Adjusting this can be useful when you need strict CFR (constant frame rate), or to pass frames through without modification (VsyncPassthrough).

§Parameters
  • method - A variant of VSyncMethod, such as VsyncCfr or VsyncVfr.
§Returns
  • Self - The modified Output, allowing method chaining.
§Example
let output = Output::from("output.mp4")
    .set_vsync_method(VSyncMethod::VsyncCfr);
Source

pub fn set_bits_per_raw_sample(self, bits: i32) -> Self

Sets the bits per raw sample for video encoding.

This value can influence quality or color depth when dealing with certain pixel formats. Commonly used for high-bit-depth workflows or specialized encoding scenarios.

§Parameters
  • bits - The bits per raw sample (e.g., 8, 10, 12).
§Returns
  • Self - The modified Output, allowing method chaining.
§Example
let output = Output::from("output.mkv")
    .set_bits_per_raw_sample(10); // e.g., 10-bit
Source

pub fn set_audio_sample_rate(self, audio_sample_rate: i32) -> Self

Sets the audio sample rate (in Hz) for output encoding.

This method allows you to specify the desired audio sample rate for the output. Common values include 44100 (CD quality), 48000 (standard for digital video), and 22050 or 16000 (for lower bitrate applications).

§Parameters
  • audio_sample_rate - The sample rate in Hertz (e.g., 44100, 48000).
§Returns
  • Self - The modified Output, allowing method chaining.
§Example
let output = Output::from("output.mp4")
    .set_audio_sample_rate(48000); // Set to 48kHz
Source

pub fn set_audio_channels(self, audio_channels: i32) -> Self

Sets the number of audio channels for output encoding.

Common values include 1 (mono), 2 (stereo), 5.1 (6 channels), and 7.1 (8 channels). This setting affects the spatial audio characteristics of the output.

§Parameters
  • audio_channels - The number of audio channels (e.g., 1 for mono, 2 for stereo).
§Returns
  • Self - The modified Output, allowing method chaining.
§Example
let output = Output::from("output.mp4")
    .set_audio_channels(2); // Set to stereo
Source

pub fn set_audio_sample_fmt(self, sample_fmt: impl Into<String>) -> Self

Sets the audio sample format for output encoding, by FFmpeg format name — the same currency as set_pix_fmt.

Common names (see ffmpeg -sample_fmts):

  • "s16" (signed 16-bit)
  • "s32" (signed 32-bit)
  • "flt" (32-bit float)
  • "fltp" (32-bit float, planar)
§Parameters
  • sample_fmt - The FFmpeg sample format name (e.g., "s16").
§Returns
  • Self - The modified Output, allowing method chaining.
§Errors

The name is resolved when the context is built (like set_pix_fmt): an unknown name fails with OpenOutputError::UnknownSampleFormat.

§Example
let output = Output::from("output.mp4")
    .set_audio_sample_fmt("s16"); // signed 16-bit
Source

pub fn set_video_qscale(self, video_qscale: i32) -> Self

Sets the video quality scale (VBR) for encoding.

This method configures a fixed quality scale for variable bitrate (VBR) video encoding. Lower values result in higher quality but larger file sizes, while higher values produce lower quality with smaller file sizes.

§Note on Modern Usage

While still supported, using fixed quality scale (-q:v) is generally not recommended for modern video encoding workflows with codecs like H.264 and H.265. Instead, consider:

  • For H.264/H.265: Use CRF (Constant Rate Factor) via -crf parameter
  • For two-pass encoding: Use target bitrate settings

This parameter is primarily useful for older codecs or specific scenarios where direct quality scale control is needed.

§Quality Scale Ranges by Codec
  • H.264/H.265: 0-51 (if needed: 17-28)
    • 17-18: Visually lossless
    • 23: High quality
    • 28: Good quality with reasonable file size
  • MPEG-4/MPEG-2: 2-31 (recommended: 2-6)
    • Lower values = higher quality
  • VP9: 0-63 (if needed: 15-35)
§Parameters
  • video_qscale - The quality scale value for video encoding.
§Returns
  • Self - The modified Output, allowing method chaining.
§Example
// For MJPEG encoding of image sequences
let output = Output::from("output.jpg")
    .set_video_qscale(2);  // High quality JPEG images

// For legacy image format conversion
let output = Output::from("output.png")
    .set_video_qscale(3);  // Controls compression level
Source

pub fn set_force_key_frames(self, spec: impl Into<String>) -> Self

Force the video encoder to emit a keyframe (an IDR request) at the given absolute output times — the list form of FFmpeg’s -force_key_frames "0,5,10.5".

spec is a comma-separated list of times in seconds (e.g. "0,5,10.5"). Each token is parsed as a decimal number of seconds and converted to microseconds. The list is sorted ascending internally, so input order does not matter; duplicate times are kept (matching FFmpeg).

§Semantics and limitations
  • Times are absolute output/encoder presentation timestamps, not offsets relative to the first frame.
  • pict_type = I is a request: software encoders such as mpeg4, libx264 and libx265 honor it and emit a keyframe; some hardware encoders may ignore it or keep their own GOP cadence. ez-ffmpeg can guarantee no more than the FFmpeg CLI does here.
  • Applies only to re-encoded video streams. Audio, subtitle, and stream-copy outputs ignore it; there is no effect if it is never set.
  • MVP grammar: only a comma-separated list of decimal seconds is supported. The HH:MM:SS, expr:, source, and source_no_drop forms of FFmpeg’s option are not supported and such tokens return an error.
  • Negative times are rejected — an ez-ffmpeg MVP choice; a negative forced time is meaningless.
§Errors

The spec is stored as given and validated when the context is built (like every other deferred option): FfmpegContext::builder().build() fails with OpenOutputError::InvalidOption if it is empty, contains an empty token, or contains a token that is not a finite, non-negative decimal number (this rejects NaN, infinities, and values that would overflow i64 microseconds).

§Example
let output = Output::from("output.mp4")
    .set_video_codec("libx264")
    .set_force_key_frames("0,5,10.5");
Source

pub fn set_audio_qscale(self, audio_qscale: i32) -> Self

Sets the audio quality scale for encoding.

This method configures codec-specific audio quality settings. The range, behavior, and optimal values depend entirely on the audio codec being used.

§Quality Scale Ranges by Codec
  • MP3 (libmp3lame): 0-9 (recommended: 2-5)
    • 0: Highest quality
    • 2: Near-transparent quality (~190-200 kbps)
    • 5: Good quality (~130 kbps)
    • 9: Lowest quality
  • AAC: 0.1-255 (recommended: 1-5)
    • 1: Highest quality (~250 kbps)
    • 3: Good quality (~160 kbps)
    • 5: Medium quality (~100 kbps)
  • Vorbis: -1 to 10 (recommended: 3-8)
    • 10: Highest quality
    • 5: Good quality
    • 3: Medium quality
§Parameters
  • audio_qscale - The quality scale value for audio encoding.
§Returns
  • Self - The modified Output, allowing method chaining.
§Example
// For MP3 encoding at high quality
let output = Output::from("output.mp3")
    .set_audio_codec("libmp3lame")
    .set_audio_qscale(2);

// For AAC encoding at good quality
let output = Output::from("output.m4a")
    .set_audio_codec("aac")
    .set_audio_qscale(3);

// For Vorbis encoding at high quality
let output = Output::from("output.ogg")
    .set_audio_codec("libvorbis")
    .set_audio_qscale(7);
Source

pub fn set_max_video_frames(self, max_frames: impl Into<Option<i64>>) -> Self

Sets the maximum number of video frames to encode (-frames:v).

Equivalent FFmpeg Command:

ffmpeg -i input.mp4 -frames:v 100 output.mp4

Example Usage:

let output = Output::from("some_url")
    .set_max_video_frames(500);
Source

pub fn set_max_audio_frames(self, max_frames: impl Into<Option<i64>>) -> Self

Sets the maximum number of audio frames to encode (-frames:a).

Equivalent FFmpeg Command:

ffmpeg -i input.mp4 -frames:a 500 output.mp4

Example Usage:

let output = Output::from("some_url")
    .set_max_audio_frames(500);
Source

pub fn set_max_subtitle_frames(self, max_frames: impl Into<Option<i64>>) -> Self

Sets the maximum number of subtitle frames to encode (-frames:s).

Equivalent FFmpeg Command:

ffmpeg -i input.mp4 -frames:s 200 output.mp4

Example Usage:

let output = Output::from("some_url")
    .set_max_subtitle_frames(200);
Source

pub fn disable_video(self) -> Self

Disables video stream mapping (equivalent to -vn in FFmpeg).

Video streams will be excluded from automatic stream mapping. This is useful when you want to extract only audio from a video file.

Equivalent FFmpeg Command:

ffmpeg -i input.mp4 -vn output.mp3
§Examples
// Extract audio only, no video
let output = Output::from("output.mp3")
    .disable_video();
Source

pub fn disable_audio(self) -> Self

Disables audio stream mapping (equivalent to -an in FFmpeg).

Audio streams will be excluded from automatic stream mapping. This is useful when you want to create a silent video.

Equivalent FFmpeg Command:

ffmpeg -i input.mp4 -an output.mp4
§Examples
// Create video without audio
let output = Output::from("output.mp4")
    .disable_audio();
Source

pub fn disable_subtitle(self) -> Self

Disables subtitle stream mapping (equivalent to -sn in FFmpeg).

Subtitle streams will be excluded from automatic stream mapping.

Equivalent FFmpeg Command:

ffmpeg -i input.mkv -sn output.mkv
§Examples
// Copy video and audio, but exclude subtitles
let output = Output::from("output.mkv")
    .disable_subtitle();
Source

pub fn disable_data(self) -> Self

Disables data stream mapping (equivalent to -dn in FFmpeg).

Data streams (timed metadata, chapter markers, etc.) will be excluded from automatic stream mapping.

Equivalent FFmpeg Command:

ffmpeg -i input.mkv -dn output.mp4
§Examples
// Copy video and audio, but exclude data streams
let output = Output::from("output.mp4")
    .disable_data();
Source

pub fn set_video_bitrate(self, bitrate: impl Into<String>) -> Self

Sets the video bitrate (equivalent to -b:v in FFmpeg).

The bitrate string follows FFmpeg conventions:

  • "1M" or "1000k" for 1 Mbps
  • "500k" for 500 Kbps
  • "2M" for 2 Mbps

Equivalent FFmpeg Command:

ffmpeg -i input.mp4 -b:v 2M output.mp4
§Examples
let output = Output::from("output.mp4")
    .set_video_bitrate("2M");
Source

pub fn set_audio_bitrate(self, bitrate: impl Into<String>) -> Self

Sets the audio bitrate (equivalent to -b:a in FFmpeg).

The bitrate string follows FFmpeg conventions:

  • "128k" for 128 Kbps
  • "192k" for 192 Kbps
  • "320k" for 320 Kbps

Equivalent FFmpeg Command:

ffmpeg -i input.mp4 -b:a 192k output.mp4
§Examples
let output = Output::from("output.mp4")
    .set_audio_bitrate("192k");
Source

pub fn set_pix_fmt(self, pix_fmt: impl Into<String>) -> Self

Sets the output pixel format (equivalent to -pix_fmt in FFmpeg).

Common pixel formats include:

  • "yuv420p" - Most compatible format for H.264
  • "yuv444p" - Higher quality, less compatible
  • "rgb24" - RGB format
  • "nv12" - Common for hardware encoding

To see all available formats, run: ffmpeg -pix_fmts

§Behavior
  • Unknown format name: Returns OpenOutputError::UnknownPixelFormat error. This matches FFmpeg CLI behavior (e.g., ffmpeg -pix_fmt foobar also fails).
  • Format incompatible with encoder: The filter graph automatically converts to a compatible format. For example, specifying rgb48be with libx264 will auto-convert to yuv420p.
  • Stream copy mode: This setting has no effect when using -c:v copy.

Equivalent FFmpeg Command:

ffmpeg -i input.mp4 -pix_fmt yuv420p output.mp4
§Examples
let output = Output::from("output.mp4")
    .set_pix_fmt("yuv420p");
Source

pub fn set_sws_opts(self, opts: impl Into<String>) -> Self

Sets sws (libswscale) options for the scale filters libavfilter auto-inserts to convert this output’s frames to a format/size the encoder accepts (pixel format, resolution, color).

This maps to FFmpeg’s graph-level AVFilterGraph.scale_sws_opts. It only affects auto-inserted scaling; if you build the filtergraph yourself with an explicit scale=..., that filter’s own arguments still apply. Has no effect on stream-copy (-c:v copy) outputs, which are not filtered.

The string uses FFmpeg option syntax, e.g. "flags=lanczos+accurate_rnd". To see the available flags, run ffmpeg -h filter=scale.

§Graph-level, not per-output

FFmpeg applies these options to the whole filtergraph, not a single output. When one filtergraph drives several outputs, they must not set different non-empty values — that conflict is rejected when the graph is configured. An explicit FilterComplex::set_sws_opts takes precedence over this per-output value.

§Examples
let output = Output::from("output.mp4")
    .set_sws_opts("flags=lanczos+accurate_rnd");
Source

pub fn set_swr_opts(self, opts: impl Into<String>) -> Self

Sets swr (libswresample) options for the aresample filters libavfilter auto-inserts to convert this output’s audio to a sample format / rate / channel layout the encoder accepts.

This maps to FFmpeg’s graph-level AVFilterGraph.aresample_swr_opts. It only affects auto-inserted resampling; an explicit aresample=... in a hand-written filtergraph keeps its own arguments. Has no effect on stream-copy outputs.

The string uses FFmpeg option syntax, e.g. "resampler=soxr:precision=28".

§Graph-level, not per-output

See set_sws_opts: the value is graph-level and the same precedence / conflict rules apply.

§Examples
let output = Output::from("output.mp4")
    .set_swr_opts("resampler=soxr:precision=28");

Trait Implementations§

Source§

impl From<&str> for Output

Source§

fn from(url: &str) -> Self

Converts to this type from the input type.
Source§

impl From<Box<dyn FnMut(&[u8]) -> i32 + Send>> for Output

Source§

fn from(write_callback_and_format: Box<dyn FnMut(&[u8]) -> i32 + Send>) -> Self

Converts to this type from the input type.
Source§

impl From<String> for Output

Source§

fn from(url: String) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Output

§

impl !Sync for Output

§

impl !UnwindSafe for Output

§

impl Freeze for Output

§

impl Send for Output

§

impl Unpin for Output

§

impl UnsafeUnpin for Output

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WasmNotSend for T
where T: Send,