{"record":{"id":"f0d2642cd134135c","repo":"tonhowtf/omniget","slug":"subtitle","errorCode":null,"errorMessage":"{}","messagePattern":"\\{\\}","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/subtitle.rs","lineNumber":527,"sourceCode":"        .args([\"-vf\", &filter])\n        .args([\n            \"-c:v\",\n            \"libx264\",\n            \"-preset\",\n            \"veryfast\",\n            \"-crf\",\n            \"20\",\n            \"-c:a\",\n            \"copy\",\n            \"-movflags\",\n            \"+faststart\",\n        ])\n        .arg(&output)\n        .output()\n        .await\n        .map_err(|e| anyhow!(\"ffmpeg nao iniciou: {}\", e))?;\n    if !out.status.success() {\n        return Err(anyhow!(\"{}\", String::from_utf8_lossy(&out.stderr).trim()));\n    }\n    super::report(&progress, \"subtitle\", \"done\", 1, Some(1), None);\n    Ok(output.to_string_lossy().to_string())\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    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\";\n\n    #[test]\n    fn reads_srt_with_multiline_text() {\n        let cues = parse(SRT).unwrap();\n        assert_eq!(cues.len(), 2);\n        assert_eq!(cues[0].start_ms, 1000);\n        assert_eq!(cues[0].end_ms, 3500);\n        assert_eq!(cues[1].text, \"Segunda\\nem duas linhas\");","sourceCodeStart":509,"sourceCodeEnd":545,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/subtitle.rs#L509-L545","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the stderr in the error message for the exact ffmpeg failure","On Windows, escape/normalize the subtitle path in the subtitles filter (forward slashes, escape ':' as '\\\\:')","Try a different output container/codec combination","Verify the input video plays with ffprobe"],"exampleFix":"// before\n.args([\"-vf\", &format!(\"subtitles={}\", sub.display())])\n// after\nlet escaped = sub.display().to_string().replace('\\\\', \"/\").replace(':', \"\\\\\\\\:\");\n.args([\"-vf\", &format!(\"subtitles='{}'\", escaped)])","handlingStrategy":"try-catch","validationCode":"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);\nif !vid_ok { return Err(\"input video unreadable by ffmpeg\"); }","typeGuard":null,"tryCatchPattern":"match burn(opts, progress).await {\n    Err(e) => {\n        let stderr = e.to_string();\n        if stderr.contains(\"Invalid argument\") || stderr.contains(\"No such filter\") {\n            // likely subtitles= filter path escaping — normalize path and retry once\n        } else { tracing::error!(\"ffmpeg burn failed: {stderr}\"); }\n    }\n    Ok(p) => { /* output at p */ }\n}","preventionTips":["Escape subtitle paths for the subtitles filter (forward slashes, escape ':' on Windows)","ffprobe the input video before burning","Prefer .mp4/H.264 output for compatibility","Log full ffmpeg stderr on failure for diagnosis"],"tags":["ffmpeg","process-exit","subtitle-burn","stderr","media-processing"],"backgroundTag":"http-error-response","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}