tonhowtf/omniget · error · anyhow::Error

ffmpeg not available

Error message

ffmpeg not available

What it means

embed_metadata() first checks is_ffmpeg_available() and aborts with this plain error if ffmpeg cannot be located. It is a deliberate pre-flight guard so callers get a clear message before any temp files are created.

Solutions

  1. Install ffmpeg on the target machine or bundle it as a sidecar binary with the app.
  2. Check `ffmpeg -version` works from the same environment the app runs in (GUI PATH != shell PATH).
  3. Expose the availability check in UI before download completes so users can install ffmpeg first.
  4. Document the ffmpeg requirement in setup/install instructions.

Example fix

// before
if !is_ffmpeg_available().await {
    return Err(anyhow!("ffmpeg not available"));
}
// after
if !is_ffmpeg_available().await {
    return Err(anyhow!(
        "ffmpeg not available: install ffmpeg (https://ffmpeg.org) or add it to PATH; \
         embedding skipped"
    ));
}
Defensive patterns

Strategy: validation

Validate before calling

// gate metadata embedding before the whole download pipeline
if !is_ffmpeg_available().await {
    return Err(anyhow!(
        "ffmpeg not available; install ffmpeg or disable metadata embedding"
    ));
}

Type guard

async fn can_embed_metadata() -> bool {
    is_ffmpeg_available().await
}

Try / catch

match embed_metadata(/* ... */).await {
    Err(e) if e.to_string() == "ffmpeg not available" => {
        log::info!("skipping metadata embed: ffmpeg missing");
        // keep the downloaded file, just skip embedding
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling embed_metadata (post-download metadata/thumbnail embedding) on a machine without ffmpeg installed or with ffmpeg absent from the PATH of the running Tauri process.

Common situations: End-user machines without ffmpeg; GUI apps launched from Finder/Explorer where PATH differs from the shell; misconfigured FFMPEG_PATH-like overrides; Docker images without ffmpeg.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/f4727de517be0e78. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/ffmpeg.rs:444

pub struct MetadataEmbed {
    pub title: Option<String>,
    pub artist: Option<String>,
    pub album: Option<String>,
    pub track_number: Option<String>,
    pub genre: Option<String>,
    pub year: Option<String>,
    pub comment: Option<String>,
    pub thumbnail_url: Option<String>,
}

pub async fn embed_metadata(
    file: &Path,
    metadata: &MetadataEmbed,
    embed_thumbnail: bool,
    http_client: &reqwest::Client,
) -> anyhow::Result<()> {
    if !is_ffmpeg_available().await {
        return Err(anyhow!("ffmpeg not available"));
    }

    let temp_dir = file.parent().unwrap_or(Path::new("."));
    let ext = file.extension().and_then(|e| e.to_str()).unwrap_or("mp4");
    let temp_output = temp_dir.join(format!(".omniget_meta_{}.{}", uuid::Uuid::new_v4(), ext));

    let is_audio_only = matches!(
        ext.to_lowercase().as_str(),
        "mp3" | "m4a" | "aac" | "ogg" | "opus" | "flac" | "wav" | "wma"
    );

    let thumbnail_path = if embed_thumbnail && is_audio_only {
        if let Some(ref url) = metadata.thumbnail_url {
            match download_thumbnail(http_client, url, temp_dir).await {
                Ok(p) => Some(p),
                Err(e) => {
                    tracing::warn!("Failed to download thumbnail: {}", e);
                    None

View on GitHub (pinned to 8600b91f42)