{"record":{"id":"3f83e7e4bbe3a2c9","repo":"tonhowtf/omniget","slug":"ffmpeg-returned-code","errorCode":null,"errorMessage":"ffmpeg returned code {}","messagePattern":"ffmpeg returned code (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/ffmpeg.rs","lineNumber":57,"sourceCode":"    let status = crate::core::process::command(\"ffmpeg\")\n        .args([\n            \"-y\",\n            \"-i\",\n            &video.to_string_lossy(),\n            \"-i\",\n            &audio.to_string_lossy(),\n            \"-c\",\n            \"copy\",\n            &output.to_string_lossy(),\n        ])\n        .stdout(std::process::Stdio::null())\n        .stderr(std::process::Stdio::null())\n        .status()\n        .await\n        .map_err(|e| anyhow!(\"Failed to run ffmpeg: {}\", e))?;\n\n    if !status.success() {\n        return Err(anyhow!(\"ffmpeg returned code {}\", status));\n    }\n\n    Ok(())\n}\n\n#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct ConversionOptions {\n    pub input_path: String,\n    pub output_path: String,\n    pub video_codec: Option<String>,\n    pub audio_codec: Option<String>,\n    pub resolution: Option<String>,\n    pub video_bitrate: Option<String>,\n    pub audio_bitrate: Option<String>,\n    pub sample_rate: Option<u32>,\n    pub fps: Option<f64>,\n    pub trim_start: Option<String>,\n    pub trim_end: Option<String>,","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/ffmpeg.rs#L39-L75","documentation":"mux_video_audio successfully launched ffmpeg, but the process exited with a non-zero status code. Because stderr and stdout are redirected to null, the actual ffmpeg diagnostic is discarded and only the exit code is reported. Typical causes are invalid input files, mismatched stream parameters for stream copy, or an unwritable output path.","triggerScenarios":"Calling mux_video_audio where ffmpeg itself fails: unreadable/corrupt video or audio input, audio track with a codec incompatible with `-c copy` into the chosen container (e.g. Opus in MP4), output file locked or on a full filesystem, or bad characters/paths passed through.","commonSituations":"Muxing WebM audio into an .mp4 container with stream copy; downloading a video whose separate audio stream failed mid-way (truncated file); output directory lacks write permission; ffmpeg too old for a codec in the inputs.","solutions":["Change output container or re-encode instead of `-c copy` (e.g. use `-c:a aac` when muxing Opus/Vorbis audio into MP4).","Re-enable stderr capture (`Stdio::piped()` and read it) to see ffmpeg's real error message, since current code nulls it.","Validate both input files with ffprobe (probe()) before muxing; re-download truncated inputs.","Check the output path is writable and has enough free disk space; update ffmpeg if the input codec is newer than the binary supports."],"exampleFix":"// before\n.stdout(std::process::Stdio::null())\n.stderr(std::process::Stdio::null())\n.status()\n.await\n.map_err(|e| anyhow!(\"Failed to run ffmpeg: {}\", e))?;\nif !status.success() {\n    return Err(anyhow!(\"ffmpeg returned code {}\", status));\n}\n// after — capture stderr so the exit code comes with a reason\nlet out = crate::core::process::command(\"ffmpeg\")\n    .args([\"-y\", \"-i\", &video.to_string_lossy(), \"-i\", &audio.to_string_lossy(), \"-c\", \"copy\", &output.to_string_lossy()])\n    .stderr(std::process::Stdio::piped())\n    .output()\n    .await\n    .map_err(|e| anyhow!(\"Failed to run ffmpeg: {}\", e))?;\nif !out.status.success() {\n    return Err(anyhow!(\"ffmpeg returned code {}: {}\", out.status, String::from_utf8_lossy(&out.stderr)));\n}","handlingStrategy":"fallback","validationCode":"// Ensure inputs are probeable and compatible before stream-copy mux\nlet vinfo = probe(video).await?;\nlet ainfo = probe(audio).await?;\nif !vinfo.streams.iter().any(|s| s.codec_type == \"video\") {\n    bail!(\"no video stream in {}\", video.display());\n}\n// Opus/Vorbis audio is not MP4-compatible with -c copy; prefer an .mkv/.webm output or re-encode","typeGuard":null,"tryCatchPattern":"// Since ffmpeg's stderr is discarded, retry once with re-encode fallback on any exit-code error\nmatch mux_video_audio(&video, &audio, &out).await {\n    Err(e) if e.to_string().starts_with(\"ffmpeg returned code\") => {\n        warn!(\"stream-copy failed ({}), retrying with re-encode\", e);\n        // run ffmpeg with -c:v copy -c:a aac into the same output\n    }\n    other => other,\n}","preventionTips":["Probe both inputs with ffprobe and check codec/container compatibility before using `-c copy` (Opus/Vorbis won't copy into MP4).","Choose an output container (MKV) that accepts virtually any stream copy.","Patch or wrap the library to capture stderr — a bare exit code with nulled stderr makes diagnosis impossible.","Only mux fully downloaded (non-.part) files; truncated inputs are a top cause of ffmpeg failures."],"tags":["ffmpeg","exit-code","muxing","rust"],"backgroundTag":"process-exit-nonzero","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"}