screenpipe/screenpipe · critical

failed to find ffmpeg path

Error message

failed to find ffmpeg path

What it means

extract_frame resolves the ffmpeg executable with find_ffmpeg_path() from screenpipe-core. When it returns None, the call fails with 'failed to find ffmpeg path' before any process is spawned. The library relies on a bundled or PATH-discoverable ffmpeg.

Source

Thrown at crates/screenpipe-engine/src/video_utils.rs:296

            warn!(
                "could not read video metadata for {}, falling back to decoded-ordinal selection: {}",
                file_path, error
            );
            Ok(None)
        }
    }
}

pub async fn extract_frame(file_path: &str, offset_index: i64) -> Result<String> {
    ensure_regular_media_file(file_path).await?;
    if offset_index < 0 {
        return Err(anyhow::anyhow!(
            "invalid negative frame index: {}",
            offset_index
        ));
    }
    let ffmpeg_path =
        find_ffmpeg_path().ok_or_else(|| anyhow::anyhow!("failed to find ffmpeg path"))?;

    // Frames may be stored either as video chunks or as individual still
    // images. `offset_index` is a zero-based decode ordinal, not milliseconds
    // and not a presentation timestamp; a still image has exactly one frame, so
    // no selection applies to it at all.
    let is_image = std::path::Path::new(file_path)
        .extension()
        .and_then(|e| e.to_str())
        .map(|e| {
            matches!(
                e.to_ascii_lowercase().as_str(),
                "jpg" | "jpeg" | "png" | "webp" | "bmp" | "gif" | "tiff"
            )
        })
        .unwrap_or(false);

    let locator = if is_image {
        None

View on GitHub (pinned to 4ebf712990)

Solutions

  1. Install ffmpeg system-wide (brew/apt) or place it on PATH
  2. Ship the screenpipe ffmpeg sidecar next to the binary as the bundler expects
  3. Verify find_ffmpeg_path() returns Some in your environment before calling
  4. Pin ffmpeg in your Dockerfile/CI image so the dependency is explicit

Example fix

// CI before
- run: cargo test -p screenpipe-engine
// after
- run: sudo apt-get update && sudo apt-get install -y ffmpeg
- run: cargo test -p screenpipe-engine
Defensive patterns

Strategy: fallback

Validate before calling

fn ffmpeg_available() -> bool {
    std::process::Command::new("ffmpeg").arg("-version").output()
        .map(|o| o.status.success()).unwrap_or(false)
}
// or directly: screenpipe_core::find_ffmpeg_path().is_some()

Try / catch

match extract_frame(path, idx).await {
    Ok(f) => f,
    Err(e) if e.to_string() == "failed to find ffmpeg path" => {
        eprintln!("install ffmpeg (brew install ffmpeg / apt install ffmpeg)");
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling extract_frame on a machine where the ffmpeg sidecar is missing and ffmpeg is not on PATH; broken bundle layout; overridden search paths pointing at a nonexistent directory.

Common situations: Running tests in CI containers without ffmpeg; packaging the app without sidecar binaries; PATH stripped under systemd/services; macOS Gatekeeper quarantine removing binaries.

Related errors


AI-assisted analysis of screenpipe/screenpipe@4ebf712990 (2026-09-01). Data as JSON: /api/errors/6de0437238a9f7b8. Report an issue: GitHub.