tonhowtf/omniget · error · anyhow::Error

{}

Error message

{}

What it means

After burn's ffmpeg invocation completes, a non-zero exit status causes burn to return ffmpeg's trimmed stderr directly via anyhow!("{}"). The message content is whatever ffmpeg printed — typically filter syntax, encoding, or input errors while burning subtitles.

Solutions

  1. Read the stderr in the error message for the exact ffmpeg failure
  2. On Windows, escape/normalize the subtitle path in the subtitles filter (forward slashes, escape ':' as '\\:')
  3. Try a different output container/codec combination
  4. Verify the input video plays with ffprobe

Example fix

// before
.args(["-vf", &format!("subtitles={}", sub.display())])
// after
let escaped = sub.display().to_string().replace('\\', "/").replace(':', "\\\\:");
.args(["-vf", &format!("subtitles='{}'", escaped)])
Defensive patterns

Strategy: try-catch

Validate before calling

let vid_ok = std::process::Command::new("ffprobe").args(["-v","error","-select_streams","v:0","-show_entries","stream=codec_name","-of","csv=p=0", &opts.video]).output().map(|o| o.status.success()).unwrap_or(false);
if !vid_ok { return Err("input video unreadable by ffmpeg"); }

Try / catch

match burn(opts, progress).await {
    Err(e) => {
        let stderr = e.to_string();
        if stderr.contains("Invalid argument") || stderr.contains("No such filter") {
            // likely subtitles= filter path escaping — normalize path and retry once
        } else { tracing::error!("ffmpeg burn failed: {stderr}"); }
    }
    Ok(p) => { /* output at p */ }
}

Prevention

When it happens

Trigger: Calling burn when ffmpeg exits with failure: malformed subtitles filter string (unescaped special chars like ':' or '\' in the subtitle path on Windows), unsupported video codec, unreadable input video, invalid output path/extension, or ffmpeg crashing mid-encode.

Common situations: Windows paths with backslashes/colons breaking the subtitles= filter (needs forward slashes and escaping); output container/codec mismatch (e.g. .mp4 with a codec ffmpeg rejects); input video corrupted or DRM-protected.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/subtitle.rs:527

        .args(["-vf", &filter])
        .args([
            "-c:v",
            "libx264",
            "-preset",
            "veryfast",
            "-crf",
            "20",
            "-c:a",
            "copy",
            "-movflags",
            "+faststart",
        ])
        .arg(&output)
        .output()
        .await
        .map_err(|e| anyhow!("ffmpeg nao iniciou: {}", e))?;
    if !out.status.success() {
        return Err(anyhow!("{}", String::from_utf8_lossy(&out.stderr).trim()));
    }
    super::report(&progress, "subtitle", "done", 1, Some(1), None);
    Ok(output.to_string_lossy().to_string())
}

#[cfg(test)]
mod tests {
    use super::*;

    const SRT: &str = "1\n00:00:01,000 --> 00:00:03,500\nPrimeira fala\n\n2\n00:00:05,000 --> 00:00:06,000\nSegunda\nem duas linhas\n\n";

    #[test]
    fn reads_srt_with_multiline_text() {
        let cues = parse(SRT).unwrap();
        assert_eq!(cues.len(), 2);
        assert_eq!(cues[0].start_ms, 1000);
        assert_eq!(cues[0].end_ms, 3500);
        assert_eq!(cues[1].text, "Segunda\nem duas linhas");

View on GitHub (pinned to 8600b91f42)