tonhowtf/omniget · error

ffmpeg

Error message

ffmpeg: {}

What it means

as_jpeg shells out to ffmpeg to convert an input media file to a JPEG frame; when the ffmpeg process exits with a non-zero status the captured stderr is wrapped into an anyhow error 'ffmpeg: <stderr>'. This indicates the conversion command itself failed.

Solutions

  1. Run the same ffmpeg command manually to see the full stderr
  2. Verify the input file is decodable (ffprobe it) and not corrupt/empty
  3. Update/reinstall ffmpeg with the needed codecs (e.g. libheif for HEIC)
  4. Convert the file to JPEG/PNG beforehand and pass a standard format

Example fix

// before
Err(anyhow!("ffmpeg: {}", String::from_utf8_lossy(&status.stderr).trim()))
// after (include exit code and input path)
Err(anyhow!("ffmpeg exited with {:?}: {}", status.status.code(), String::from_utf8_lossy(&status.stderr).trim()))
Defensive patterns

Strategy: validation

Validate before calling

let ok = tokio::process::Command::new("ffprobe").args(["-v","error","-select_streams","v:0","-show_entries","stream=codec_name","-of","csv=p=0", path]).output().await?.status.success();
if !ok { return Err(anyhow!("input is not a decodable image/video")); }

Try / catch

match as_jpeg(path).await { Err(e) if e.to_string().starts_with("ffmpeg:") => { eprintln!("conversion failed: {e}"); fallback_to_original_format(path) }, r => r }

Prevention

When it happens

Trigger: publish_web -> as_jpeg on a file that ffmpeg cannot decode: corrupt file, unsupported codec/container, wrong path/extension, or ffmpeg binary missing/incompatible arguments.

Common situations: Uploading a photo in an exotic format (HEIC with old ffmpeg, WEBP without libwebp), a zero-byte or truncated download, or a mismatched ffmpeg build lacking needed decoders.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/instagram/publish.rs:103

async fn as_jpeg(path: &Path) -> anyhow::Result<(Vec<u8>, u32, u32)> {
    let bytes = tokio::fs::read(path).await?;
    if let Some((w, h)) = jpeg_dimensions(&bytes) {
        return Ok((bytes, w, h));
    }
    let ffmpeg = crate::core::dependencies::ensure_ffmpeg().await?;
    let out = super::super::temp_dir().join(format!("ig-{}.jpg", upload_id()));
    let status = crate::core::process::command(&ffmpeg)
        .args(["-y", "-hide_banner", "-loglevel", "error", "-i"])
        .arg(path)
        .args(["-q:v", "2", "-pix_fmt", "yuvj420p"])
        .arg(&out)
        .stdin(std::process::Stdio::null())
        .stdout(std::process::Stdio::null())
        .stderr(std::process::Stdio::piped())
        .output()
        .await?;
    if !status.status.success() {
        return Err(anyhow!(
            "ffmpeg: {}",
            String::from_utf8_lossy(&status.stderr).trim()
        ));
    }
    let bytes = tokio::fs::read(&out).await?;
    let _ = tokio::fs::remove_file(&out).await;
    let (w, h) = jpeg_dimensions(&bytes)
        .or_else(|| png_dimensions(&bytes))
        .unwrap_or((1080, 1080));
    Ok((bytes, w, h))
}

async fn rupload_photo(
    client: &IgClient,
    bytes: Vec<u8>,
    w: u32,
    h: u32,
    uid: &str,

View on GitHub (pinned to 8600b91f42)