OpenSpace ffmpeg-graceful-degradation

Graceful degradation workflow for ffmpeg encoding failures with progressive fallback strategies

install
source · Clone the upstream repo
git clone https://github.com/HKUDS/OpenSpace
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/HKUDS/OpenSpace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/gdpval_bench/skills/ffmpeg-graceful-degradation" ~/.claude/skills/hkuds-openspace-ffmpeg-graceful-degradation && rm -rf "$T"
manifest: gdpval_bench/skills/ffmpeg-graceful-degradation/SKILL.md
source content

FFmpeg Graceful Degradation

When processing videos with ffmpeg, encoding failures are common due to codec availability, library version mismatches, or system configuration issues. This skill provides a systematic fallback strategy to ensure video processing completes successfully.

Overview

The pattern involves: (1) probing encoder availability upfront, (2) testing on a short clip before batch processing, (3) progressive fallback through copy mode, alternative codecs, and finally moviepy, (4) using moviepy as a reliable bundled alternative.

Step 1: Probe Encoder Availability

Before any encoding work, check what encoders are available:

ffmpeg -encoders | grep -E "libx264|libopenh264|mpeg4"

Expected output shows which encoders are present:

  • libx264
    - Preferred H.264 encoder (may be missing)
  • libopenh264
    - Alternative H.264 (often has library issues)
  • mpeg4
    - Universal fallback (always available)

Step 2: Test Encoding on Single Short Clip

Never start batch processing without validation. Extract and test a short segment:

# Extract 5-second test clip
ffmpeg -y -i input.mp4 -ss 0 -t 5 -c copy test_clip.mp4

# Attempt encode with preferred codec
ffmpeg -y -i test_clip.mp4 -c:v libx264 -preset fast test_output.mp4

Check the exit code and output for errors. Common failures:

  • libopenh264.so: wrong ELF class
  • Encoder libx264 not found
  • Library version mismatches

Step 3: Progressive Fallback Strategy

If the preferred encoder fails, try these fallbacks in order:

Fallback A: Copy Mode (No Re-encoding)

ffmpeg -y -i input.mp4 -c:v copy -c:a copy output.mp4

Fast, lossless, but doesn't change codec/format.

Fallback B: MPEG4 Codec

ffmpeg -y -i input.mp4 -c:v mpeg4 -q:v 3 -c:a copy output.mp4

Universal compatibility, larger file sizes, always available.

Fallback C: Install MoviePy (Bundles Working FFmpeg)

pip install moviepy

Then use Python instead of raw ffmpeg:

from moviepy.editor import VideoFileClip, concatenate_videoclips

# Single clip processing
clip = VideoFileClip("input.mp4")
clip.write_videofile("output.mp4", codec="libx264")

# Concatenate multiple clips
clips = [VideoFileClip(f) for f in clip_files]
final = concatenate_videoclips(clips)
final.write_videofile("output.mp4", codec="libx264")

MoviePy bundles its own ffmpeg binary, avoiding system library issues.

Step 4: Implementation Pattern

Here's a complete graceful degradation workflow:

import subprocess
import os

def safe_video_encode(input_path, output_path, clips=None):
    """
    Encode video with graceful degradation fallbacks.
    
    Args:
        input_path: Single input file path, or
        clips: List of clip paths for concatenation
    
    Returns:
        True if successful, False otherwise
    """
    
    # Step 1: Check encoder availability
    result = subprocess.run(
        ["ffmpeg", "-encoders"],
        capture_output=True, text=True
    )
    has_libx264 = "libx264" in result.stdout
    has_mpeg4 = "mpeg4" in result.stdout
    
    # Step 2: If concatenating, prepare clips with moviepy
    if clips:
        try:
            from moviepy.editor import VideoFileClip, concatenate_videoclips
            loaded_clips = [VideoFileClip(c) for c in clips]
            final = concatenate_videoclips(loaded_clips)
            final.write_videofile(output_path, codec="libx264", logger=None)
            return True
        except Exception as e:
            print(f"MoviePy failed: {e}")
    
    # Step 3: Try ffmpeg with progressive fallbacks
    encoders_to_try = []
    if has_libx264:
        encoders_to_try.append("libx264")
    encoders_to_try.append("mpeg4")  # Always available
    
    for codec in encoders_to_try:
        cmd = [
            "ffmpeg", "-y",
            "-i", input_path,
            "-c:v", codec,
            "-c:a", "copy",
            output_path
        ]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            return True
    
    # Step 4: Last resort - copy mode
    cmd = ["ffmpeg", "-y", "-i", input_path, "-c", "copy", output_path]
    result = subprocess.run(cmd, capture_output=True, text=True)
    return result.returncode == 0

Decision Flow

Start
  │
  ▼
Check encoders (ffmpeg -encoders)
  │
  ├─ libx264 available? ──Yes──► Try libx264
  │         │                       │
  │         No                      └─► Success? ──Yes──► Done
  │         │                                      │
  │         ▼                                      No
  │    Test short clip                             │
  │         │                                      ▼
  │         ▼                               Try -c:v copy
  │    Encode fails? ──Yes──► Check libopenh264    │
  │         │                       │              │
  │         No                      Broken         ▼
  │         │                       │         Try mpeg4
  │         ▼                       ▼              │
  │      Done                  Install moviepy     │
  │                              │                 │
  │                              ▼                 │
  │                         Use VideoFileClip ◄────┘
  │                         concatenate_videoclips
  │                              │
  │                              ▼
  │                            Done
  │
  ▼
End

Key Principles

  1. Test first, batch later - Always validate on a short clip
  2. Fail fast, fallback gracefully - Don't waste time on doomed encodings
  3. MoviePy as safety net - Its bundled ffmpeg avoids system issues
  4. Copy mode preserves content - Even if quality isn't ideal

Common Error Patterns

Error MessageCauseSolution
libopenh264.so: wrong ELF class
Library architecture mismatchUse moviepy or mpeg4
Encoder libx264 not found
FFmpeg built without x264Use mpeg4 fallback
Broken pipe
Process killed mid-operationTry copy mode first
Invalid data found
Corrupt or incompatible inputRe-extract source

When to Use This Skill

  • Processing user-uploaded videos (unknown codecs/formats)
  • Running in containers with limited codec support
  • Batch processing where failure would be costly
  • Cross-platform deployments with varying ffmpeg builds