{"record":{"id":"4745ca741e4e468a","repo":"tonhowtf/omniget","slug":"a-legenda-nao-tem-falas","errorCode":null,"errorMessage":"a legenda nao tem falas","messagePattern":"a legenda nao tem falas","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/dub.rs","lineNumber":72,"sourceCode":"        s /= 2.0;\n    }\n    while s < 0.5 {\n        parts.push(\"atempo=0.5\".to_string());\n        s /= 0.5;\n    }\n    parts.push(format!(\"atempo={:.4}\", s));\n    parts.join(\",\")\n}\n\npub async fn dub(opts: DubOptions, progress: super::ProgressFn) -> anyhow::Result<DubResult> {\n    let id = \"dub\";\n    let srt = tokio::fs::read_to_string(&opts.srt_path).await?;\n    let cues: Vec<Cue> = parse_cues(&srt)\n        .into_iter()\n        .filter(|c| !c.text.trim().is_empty())\n        .collect();\n    if cues.is_empty() {\n        return Err(anyhow!(\"a legenda nao tem falas\"));\n    }\n    let ffmpeg = crate::core::dependencies::ensure_ffmpeg().await?;\n    let work = super::temp_dir().join(format!(\"dub-{}\", uuid::Uuid::new_v4()));\n    std::fs::create_dir_all(&work)?;\n    let out_dir = if opts.output_dir.trim().is_empty() {\n        Path::new(&opts.srt_path)\n            .parent()\n            .map(|p| p.to_path_buf())\n            .unwrap_or_else(|| PathBuf::from(\".\"))\n    } else {\n        PathBuf::from(opts.output_dir.trim())\n    };\n    std::fs::create_dir_all(&out_dir)?;\n    let stem = Path::new(&opts.srt_path)\n        .file_stem()\n        .map(|s| s.to_string_lossy().to_string())\n        .unwrap_or_else(|| \"dublagem\".into());\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/dub.rs#L54-L90","documentation":"dub() reads the SRT subtitle file, parses it into cues, and filters out cues whose text is empty or whitespace-only. If no non-empty cues remain, it refuses to proceed and throws the Portuguese message 'a legenda nao tem falas' ('the subtitle has no lines'). The library throws this because dubbing audio for zero spoken lines is a no-op and would produce a broken/empty output pipeline.","triggerScenarios":"Calling dub with opts.srt_path pointing at an SRT file that is empty, contains only sequence/timestamp lines with blank text, contains only whitespace cues, or does not parse into any Cue at all (malformed SRT yielding zero cues).","commonSituations":"Passing a subtitle file downloaded as an empty stub or ads/notes-only file; passing the wrong file path so a placeholder/empty SRT is read; using an SRT format (e.g. WebVTT or with BOM/HTML tags) the parser cannot read, so parse_cues returns nothing; subtitles that contain only formatting tags stripped to whitespace.","solutions":["Check the SRT file before dubbing: ensure it is a valid, non-empty SubRip file with at least one cue containing dialogue text.","Verify opts.srt_path points to the correct subtitle file for the target media.","If the file is VTT or another format, convert it to SRT (e.g. ffmpeg -i subs.vtt subs.srt) before calling dub.","Strip HTML/formatting tags or fix the encoding (UTF-8 without BOM) so cues parse with non-empty text."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let srt = tokio::fs::read_to_string(&opts.srt_path).await?;\nlet has_dialogue = parse_cues(&srt).iter().any(|c| !c.text.trim().is_empty());\nif !has_dialogue {\n    anyhow::bail!(\"SRT at {} has no non-empty cues; refusing to dub\", opts.srt_path.display());\n}","typeGuard":null,"tryCatchPattern":"match dub(opts).await {\n    Err(e) if e.to_string().contains(\"nao tem falas\") => {\n        // prompt user to select a dialogue-bearing subtitle file\n    }\n    other => other?,\n}","preventionTips":["Validate SRT files (parse cue count) before offering the dub action in the UI.","Ensure subtitle files are genuine SubRip format (numbered cues, '-->' timestamps), not VTT or stub files.","Strip HTML tags and re-encode to UTF-8 so text survives the empty-text filter.","Log the cue count after parsing so empty parses are caught at ingest time."],"tags":["subtitles","srt","empty-input","validation"],"backgroundTag":"empty-result-set","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"}