{"record":{"id":"4bd585d3c9a92b07","repo":"tonhowtf/omniget","slug":"o-arquivo-n-o-tem-trilha-de-udio-silence-cut","errorCode":null,"errorMessage":"o arquivo não tem trilha de áudio","messagePattern":"o arquivo não tem trilha de áudio","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/silence_cut.rs","lineNumber":228,"sourceCode":"            \"null\",\n            \"-\",\n        ])\n        .output()\n        .await\n        .map_err(|e| anyhow!(\"ffmpeg nao iniciou: {}\", e))?;\n    Ok(String::from_utf8_lossy(&out.stderr).to_string())\n}\n\nasync fn cut_one(ffmpeg: &Path, opts: &SilenceOptions, input: &str) -> anyhow::Result<SilenceItem> {\n    let inp = Path::new(input);\n    let probe = crate::core::ffmpeg::probe(inp).await?;\n    let total = probe.duration_seconds;\n    if total <= 0.0 {\n        return Err(anyhow!(\"não consegui medir a duração\"));\n    }\n    let has_audio = probe.streams.iter().any(|s| s.codec_type == \"audio\");\n    if !has_audio {\n        return Err(anyhow!(\"o arquivo não tem trilha de áudio\"));\n    }\n\n    let stderr = detect(ffmpeg, inp, opts.threshold_db, opts.min_silence).await?;\n    let spans = parse_spans(&stderr, total);\n    let (spans, skipped) = cap_spans(spans, MAX_SEGMENTS);\n    let keeps = keep_ranges(&spans, total, opts.padding.max(0.0));\n    let kept: f64 = keeps.iter().map(|k| k.duration()).sum();\n\n    let mut item = SilenceItem {\n        input: input.to_string(),\n        output: None,\n        duration_before: total,\n        duration_after: kept,\n        seconds_removed: (total - kept).max(0.0),\n        cuts: spans.len(),\n        skipped_short: skipped,\n        ok: true,\n        error: None,","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/silence_cut.rs#L210-L246","documentation":"Silence cutting operates on audio; after probing, cut_one checks whether any stream has codec_type == \"audio\". If none does, it throws 'o arquivo não tem trilha de áudio' (the file has no audio track). Silence detection without an audio stream is meaningless, so the operation is refused early.","triggerScenarios":"Calling run/cut_one on a video file with video-only streams (muted capture, screen recording without audio device), or an images-only/animation file.","commonSituations":"OBS or OS capture configured without a microphone/desktop-audio source; stripped audio track after prior processing; passing a GIF or image sequence.","solutions":["Ensure the input contains an audio track; re-record with an audio source enabled.","Check with ffprobe -show_streams that an audio stream exists before calling run.","If the source legitimately has no audio, skip silence cutting rather than calling the API."],"exampleFix":"// before\ncut_silences(\"screen-no-audio.mp4\").await?;\n// after\nlet probe = ffmpeg_probe(\"screen-no-audio.mp4\").await?;\nif probe.streams.iter().any(|s| s.codec_type == \"audio\") {\n    cut_silences(\"screen-no-audio.mp4\").await?;\n}","handlingStrategy":"validation","validationCode":"// Rust\nlet probe = ffmpeg_probe(input).await?;\nanyhow::ensure!(\n    probe.streams.iter().any(|s| s.codec_type == \"audio\"),\n    \"entrada sem audio\"\n);","typeGuard":"fn has_audio(p: &Probe) -> bool {\n    p.streams.iter().any(|s| s.codec_type == \"audio\")\n}","tryCatchPattern":"match run(&opts, input).await {\n    Err(e) if e.to_string().contains(\"trilha de áudio\") => {\n        eprintln!(\"pule o corte de silencio: entrada sem audio\");\n    }\n    r => r?,\n}","preventionTips":["Check audio stream presence with ffprobe before silence cutting","Record with an audio source enabled when silence cutting is planned","Treat audio-less files as no-op for this feature instead of errors"],"tags":["ffmpeg","audio","validation","rust"],"backgroundTag":"incompatible-source-type","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"}