Skip to main content

Advanced Options

Frame provides advanced features for power users including stream copy/remux mode, video cropping, trimming, GIF optimization, and hardware encoder-specific options. This guide covers all advanced configuration options.

Stream Copy / Remux Mode

Processing Mode: processingMode: "copy" Stream copy mode copies the video and audio streams directly without re-encoding, changing only the container format.

How Stream Copy Works

Instead of decoding and re-encoding video/audio:
  1. Reads the encoded streams from the source
  2. Copies them directly to the new container
  3. Extremely fast (limited only by disk I/O)
  4. Zero quality loss (bit-for-bit identical)

Benefits

  • Lightning fast - 10-100x faster than re-encoding
  • Zero quality loss - Perfect copy of original
  • Low CPU usage - No encoding overhead
  • Batch processing - Convert many files quickly

Limitations

Stream copy has many limitations. Frame validates compatibility and will show an error if the operation is not possible.
Cannot be used with:
  • Changing video codec or audio codec
  • Changing resolution or frame rate
  • Applying filters (crop, rotate, flip, scale)
  • Burn-in subtitles
  • Audio normalization or volume adjustment
  • Hardware decode acceleration
  • GIF output (GIF is a video-only container)
Can be used with:
  • Changing container format (remuxing)
  • Trimming video (start/end time)
  • Selecting specific audio/subtitle tracks
  • Metadata changes (preserve/clean/replace)

Codec Compatibility

The source video/audio codecs must be compatible with the target container. Example - Valid Stream Copy:
  • Source: video.mkv (H.264 video, AAC audio)
  • Target: video.mp4 (MP4 container)
  • ✓ H.264 is compatible with MP4
  • ✓ AAC is compatible with MP4
  • Result: Fast remux succeeds
Example - Invalid Stream Copy:
  • Source: video.mkv (VP9 video, Opus audio)
  • Target: video.mp4 (MP4 container)
  • ✗ VP9 is not compatible with MP4
  • ✗ Opus is not compatible with MP4
  • Result: Frame shows error, use re-encode mode

Stream Copy Configuration

{
  "processingMode": "copy",
  "container": "mp4"
}

Use Cases

Changing Container Format

Convert MKV to MP4 without re-encoding:
{
  "processingMode": "copy",
  "container": "mp4"
}
Speed: Seconds instead of minutes/hoursUse when:
  • Need MP4 for device compatibility
  • MKV to MP4 for streaming
  • Changing format without quality loss

Audio Extraction

Extract audio from video without re-encoding:
{
  "processingMode": "copy",
  "container": "m4a",
  "selectedAudioTracks": [0]
}
Speed: Very fast audio extractionUse when:
  • Extracting music from music videos
  • Getting audio for editing
  • Creating audio-only files

Fast Trimming

Cut video segment without quality loss:
{
  "processingMode": "copy",
  "container": "mp4",
  "startTime": "00:01:30",
  "endTime": "00:05:00"
}
Note: Cuts may not be frame-accurate due to keyframe limitations.Use when:
  • Quick rough cuts
  • Removing intro/outro
  • Extracting segments

FFmpeg Implementation

-c copy
Frame automatically validates stream compatibility before attempting copy mode.

Video Cropping

Crop video to a specific region, removing unwanted areas.

Crop Configuration

interface CropSettings {
  enabled: boolean;
  x: number;          // Left edge position
  y: number;          // Top edge position
  width: number;      // Crop width
  height: number;     // Crop height
  sourceWidth?: number;
  sourceHeight?: number;
  aspectRatio?: string | null;
}

How Cropping Works

  1. Define a rectangle within the source video
  2. Only that rectangle is kept in the output
  3. Applied before scaling/resolution changes
  4. Can maintain aspect ratio constraints

Example Configuration

Crop to center 1920x1080 from 4K source:
{
  "crop": {
    "enabled": true,
    "x": 960,
    "y": 540,
    "width": 1920,
    "height": 1080
  }
}

FFmpeg Implementation

crop=1920:1080:960:540
Format: crop=width:height:x:y

Use Cases

Removing Letterboxing

Remove black bars from 16:9 content in 4:3 frame:Source: 1440x1080 (4:3 frame with 16:9 content)Crop to 16:9:
{
  "crop": {
    "enabled": true,
    "x": 0,
    "y": 135,
    "width": 1440,
    "height": 810
  }
}

Crop to Platform Requirements

TikTok/Reels (9:16 portrait) from 16:9 landscape:Source: 1920x1080 (16:9)Crop to 9:16 centered:
{
  "crop": {
    "enabled": true,
    "x": 420,
    "y": 0,
    "width": 1080,
    "height": 1920
  }
}
Instagram Square (1:1) from 16:9:
{
  "crop": {
    "enabled": true,
    "x": 420,
    "y": 0,
    "width": 1080,
    "height": 1080
  }
}

Cropping Out Overlays

Remove logo from bottom-right corner:Source: 1920x1080 with logo at bottom-rightCrop to remove:
{
  "crop": {
    "enabled": true,
    "x": 0,
    "y": 0,
    "width": 1800,
    "height": 1000
  }
}
Then scale back to 1920x1080 if needed.
Cropping is applied before scaling. The cropped dimensions become the input for any resolution changes.

Trim / Cut Video

Extract a specific time range from video.

Time Range Configuration

{
  "startTime": "00:01:30",
  "endTime": "00:05:00"
}

Time Format

Frame supports multiple time formats:
  • HH:MM:SS - "00:01:30" (1 minute 30 seconds)
  • MM:SS - "01:30" (1 minute 30 seconds)
  • Seconds - "90" (90 seconds)
  • Fractional - "90.5" (90.5 seconds)

How Trimming Works

With startTime only:
  • Start encoding from specified time
  • Continue to end of video
With endTime only:
  • Start from beginning
  • End at specified time
With both:
  • Extract segment between start and end
  • Duration = endTime - startTime

FFmpeg Implementation

Start time (before input):
-ss 00:01:30 -i input.mp4
End time (duration calculation):
-t 00:03:30  # Duration from start
or
-to 00:05:00  # Absolute end time

Frame’s Implementation

From source code (args.rs:148-178):
if let Some(start) = &config.start_time {
    args.push("-ss".to_string());
    args.push(start.clone());
}

args.push("-i".to_string());
args.push(input.to_string());

if let Some(end_str) = &config.end_time {
    if let Some(start_str) = &config.start_time {
        // Calculate duration if both start and end specified
        let duration = end_t - start_t;
        args.push("-t".to_string());
        args.push(format!("{:.3}", duration));
    } else {
        args.push("-to".to_string());
        args.push(end_str.clone());
    }
}

Use Cases

Removing Unwanted Sections

Remove first 10 seconds:
{
  "startTime": "00:00:10"
}
Remove last 5 seconds (from 10-minute video):
{
  "endTime": "00:09:55"
}

Extracting Specific Segments

Extract 30-second clip starting at 2:15:
{
  "startTime": "00:02:15",
  "endTime": "00:02:45"
}
Extract middle section (1min to 5min):
{
  "startTime": "00:01:00",
  "endTime": "00:05:00"
}
Trimming works in both re-encode and stream copy modes. In stream copy mode, cuts may not be frame-accurate due to keyframe positions.

GIF-Specific Options

When outputting to GIF container, Frame exposes advanced GIF optimization options.

GIF Configuration

{
  "container": "gif",
  "gifColors": 256,
  "gifDither": "sierra2_4a",
  "gifLoop": 0
}

GIF Color Palette

Setting: gifColors Range: 2-256 colors Default: 256

How It Works

GIF uses an indexed color palette. Fewer colors = smaller file size but lower quality. Color Count Guidelines:
  • 256 colors - Maximum quality (default)
  • 128 colors - Good quality, smaller files (Frame’s “GIF Web Small” preset)
  • 64 colors - Acceptable for simple graphics
  • 32 colors - Low quality, very small files
  • 16 colors - Very limited, dithering artifacts
  • 2-8 colors - Only for very simple graphics

Configuration

{
  "gifColors": 128
}

File Size Impact

Reducing colors can reduce file size by 20-50% depending on content complexity.

GIF Dithering

Setting: gifDither Options: "none", "bayer", "floyd_steinberg", "sierra2_4a" Default: "sierra2_4a"

Dithering Algorithms

No Dithering

Value: "none"

Characteristics

  • No dithering applied
  • Posterization in gradients
  • Smallest file size
  • Clean, sharp edges

Use Cases

  • Simple graphics with solid colors
  • Pixel art
  • Logos and icons
  • When file size is critical

Example

{
  "gifDither": "none",
  "gifColors": 64
}

GIF Loop Count

Setting: gifLoop Range: 0-65535 Default: 0 (infinite loop)

Loop Options

  • 0 - Loop forever (default, recommended)
  • 1 - Play once, no loop
  • 2+ - Loop specific number of times

Configuration

Infinite loop:
{
  "gifLoop": 0
}
Play once:
{
  "gifLoop": 1
}
Loop 5 times:
{
  "gifLoop": 5
}
Most platforms and viewers expect GIFs to loop infinitely. Use gifLoop: 0 for standard behavior.

GIF Optimization Examples

Maximum Quality

Frame’s “GIF High Quality” preset:
{
  "container": "gif",
  "gifColors": 256,
  "gifDither": "floyd_steinberg",
  "gifLoop": 0,
  "resolution": "720p",
  "fps": "15"
}
Best for:
  • Photographic content
  • High-quality requirements
  • Portfolio work

Optimized for File Size

Frame’s “GIF Web Small” preset:
{
  "container": "gif",
  "gifColors": 128,
  "gifDither": "sierra2_4a",
  "gifLoop": 0,
  "customWidth": "640",
  "customHeight": "360",
  "fps": "12"
}
Best for:
  • Web embedding
  • Fast loading
  • Social media
  • Reduced bandwidth

Sharp, Clean Pixel Art

{
  "container": "gif",
  "gifColors": 64,
  "gifDither": "none",
  "gifLoop": 0,
  "scalingAlgorithm": "nearest"
}
Best for:
  • Pixel art animations
  • Retro games
  • Simple graphics

FFmpeg GIF Filter Implementation

From source code (args.rs:326-343):
fn build_gif_filter_complex(config: &ConversionConfig) -> String {
    let colors = config.gif_colors.clamp(2, 256);
    let dither = normalize_gif_dither(&config.gif_dither);
    
    format!(
        "[0:v:0]{chain};[gif_palette_src]palettegen=max_colors={colors}:stats_mode=single[gif_palette];[gif_src][gif_palette]paletteuse=dither={dither}:new=1[gif_out]"
    )
}
Frame uses FFmpeg’s two-pass palette generation for optimal GIF quality.

Hardware Encoder Advanced Options

Frame exposes hardware-specific options for fine-tuning encoding.

NVENC Adaptive Quantization

See Hardware Acceleration - NVENC Advanced Options for details: Spatial AQ:
{
  "nvencSpatialAq": true
}
Temporal AQ:
{
  "nvencTemporalAq": true
}

VideoToolbox Software Fallback

See Hardware Acceleration - VideoToolbox Advanced Options for details: Allow software fallback:
{
  "videotoolboxAllowSw": true
}

See Also

Build docs developers (and LLMs) love