tonhowtf/omniget · error
Failed to run ffmpeg: {}
Error message
Failed to run ffmpeg: {} What it means
mux_video_audio spawns `ffmpeg -y -i <video> -i <audio> -c copy <output>` via tokio::process. If spawning/waiting on the ffmpeg process itself fails at the OS level (io::Error from .status()), this error wraps that io error. Note stderr/stdout are piped to null, so ffmpeg's own diagnostics are lost; a non-zero exit code instead produces the separate 'ffmpeg returned code' error.
Solutions
- Install ffmpeg or ensure it's on PATH (verify with `which ffmpeg` / `ffmpeg -version`).
- In packaged Tauri builds, ship ffmpeg as a sidecar and resolve its absolute path instead of relying on PATH.
- Check execute permissions on the binary (chmod +x) and that antivirus isn't quarantining it.
- Check is_ffmpeg_available() (which uses find_tool) before calling mux_video_audio to fail fast with a clearer message.
Example fix
// before
let status = crate::core::process::command("ffmpeg")
.args(["-y", "-i", &video.to_string_lossy(), "-i", &audio.to_string_lossy(), "-c", "copy", &output.to_string_lossy()])
.status()
.await
.map_err(|e| anyhow!("Failed to run ffmpeg: {}", e))?;
// after — resolve an explicit binary path and capture stderr for diagnostics
let ffmpeg = crate::core::dependencies::find_tool("ffmpeg").await
.ok_or_else(|| anyhow!("ffmpeg not found; install it or bundle it as a sidecar"))?;
let out = crate::core::process::command(ffmpeg)
.args(["-y", "-i", &video.to_string_lossy(), "-i", &audio.to_string_lossy(), "-c", "copy", &output.to_string_lossy()])
.output()
.await
.map_err(|e| anyhow!("Failed to run ffmpeg: {}", e))?;
if !out.status.success() {
return Err(anyhow!("ffmpeg failed: {}", String::from_utf8_lossy(&out.stderr)));
} Defensive patterns
Strategy: validation
Validate before calling
// Check the tool exists before attempting the mux
if !crate::core::ffmpeg::is_ffmpeg_available().await {
bail!("ffmpeg is not installed or not on PATH");
}
for p in [video, audio] {
if !tokio::fs::metadata(p).await.map(|m| m.len() > 0).unwrap_or(false) {
bail!("input missing or empty: {}", p.display());
}
} Try / catch
// stderr is nulled by the library, so fall back to re-running with capture to obtain the real reason
match mux_video_audio(&video, &audio, &out).await {
Err(e) if e.to_string().contains("Failed to run ffmpeg") => {
Err(anyhow!("ffmpeg could not be started — is it installed? ({e})"))
}
other => other,
} Prevention
- Always call is_ffmpeg_available() (or find_tool) before invoking mux_video_audio.
- In packaged Tauri apps, bundle ffmpeg as a sidecar and resolve it by absolute path — never rely on the user's PATH.
- Keep inputs validated (exists, non-empty, probed via ffprobe) before muxing.
- Watch for AV/antivirus policies blocking unsigned helper binaries in production installs.
When it happens
Trigger: Calling mux_video_audio when the OS cannot exec or await ffmpeg: binary not on PATH, permission denied on the binary, executable missing/corrupted, or EAGAIN/resource limits on process spawn.
Common situations: ffmpeg not installed or not bundled with the Tauri app; PATH differs in the packaged app vs dev environment; sidecar not extracted; antivirus blocks spawning the binary; disk-full or fd-limit conditions.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- ffmpeg nao iniciou: {}
- Failed to run ffprobe: {}
- ffmpeg nao iniciou: {}
- ffmpeg: {}
- ffmpeg nao iniciou: {}
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/d3a6d1c4ec3fccae.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/ffmpeg.rs:54
std::fs::create_dir_all(parent)?;
}
let status = crate::core::process::command("ffmpeg")
.args([
"-y",
"-i",
&video.to_string_lossy(),
"-i",
&audio.to_string_lossy(),
"-c",
"copy",
&output.to_string_lossy(),
])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.await
.map_err(|e| anyhow!("Failed to run ffmpeg: {}", e))?;
if !status.success() {
return Err(anyhow!("ffmpeg returned code {}", status));
}
Ok(())
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversionOptions {
pub input_path: String,
pub output_path: String,
pub video_codec: Option<String>,
pub audio_codec: Option<String>,
pub resolution: Option<String>,
pub video_bitrate: Option<String>,
pub audio_bitrate: Option<String>,
pub sample_rate: Option<u32>,View on GitHub (pinned to 8600b91f42)