tonhowtf/omniget · error
ffmpeg
Error message
ffmpeg: {} What it means
start() spawns the ffmpeg child process via crate::core::process::command(). If the OS-level spawn fails (io::Error), it is wrapped as "ffmpeg: {io error}". This happens before any recording state is stored.
Solutions
- Ensure ensure_ffmpeg().await? is awaited successfully before start() and that ffmpeg exists at the returned path
- Run `ffmpeg -version` manually with the same environment/PATH to reproduce the spawn failure
- Check file permissions on the ffmpeg binary (chmod +x)
- Check system resource limits (ulimit, disk space) if the binary exists
Example fix
// before
start(opts).await?; // assumes ffmpeg is present
// after
let ffmpeg = ensure_ffmpeg().await?; // surface install errors early
println!("using ffmpeg at {}", ffmpeg);
start(opts).await?; Defensive patterns
Strategy: try-catch
Validate before calling
let ffmpeg = ensure_ffmpeg().await?;
if !std::path::Path::new(&ffmpeg).exists() {
return Err(anyhow!("ffmpeg missing at {}", ffmpeg));
} Try / catch
match screen_record::start(opts).await {
Err(e) if e.to_string().starts_with("ffmpeg:") => {
eprintln!("failed to spawn ffmpeg: {} — reinstall via ensure_ffmpeg()", e);
ensure_ffmpeg().await?;
screen_record::start(opts).await
}
other => other,
} Prevention
- Always call ensure_ffmpeg() (and check the returned path exists) before start()
- Keep PATH intact when launching from GUI environments
- Verify the binary is executable after any update/reinstall
When it happens
Trigger: The ffmpeg binary path is invalid or not executable, the binary was removed after ensure_ffmpeg() earlier, resource limits (fork/ENOMEM), or an invalid working directory for the child.
Common situations: ffmpeg not installed and ensure_ffmpeg skipped or failed silently; a broken PATH; permission bits stripped from the binary; disk-full or fd-limit conditions.
Related errors
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/6e9a228ade9ec2df.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/screen_record.rs:364
PathBuf::from(opts.output_dir.trim())
};
std::fs::create_dir_all(&dir)?;
let ring = opts.replay_seconds > 0;
let (target, ring_dir, output) = if ring {
let r = super::temp_dir().join(format!("replay-{}", uuid::Uuid::new_v4()));
std::fs::create_dir_all(&r)?;
(r.clone(), Some(r), None)
} else {
let out = dir.join(format!("Gravacao {}.mp4", stamp()));
(out.clone(), None, Some(out))
};
let args = build_args(&opts, &target, ring);
let mut cmd = crate::core::process::command(&ffmpeg);
cmd.args(&args)
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::piped());
let child = cmd.spawn().map_err(|e| anyhow!("ffmpeg: {}", e))?;
*ERROR.lock().unwrap_or_else(|e| e.into_inner()) = None;
*SESSION.lock().unwrap_or_else(|e| e.into_inner()) = Some(Session {
child,
started: Instant::now(),
output,
ring_dir,
opts,
});
// Se o ffmpeg morrer nos primeiros instantes (permissão, dispositivo), avisa.
tokio::time::sleep(std::time::Duration::from_millis(900)).await;
let died = {
let mut s = SESSION.lock().unwrap_or_else(|e| e.into_inner());
match s.as_mut() {
Some(sess) => match sess.child.try_wait() {
Ok(Some(_)) => Some(sess.child.stderr.take()),
_ => None,
},
None => None,View on GitHub (pinned to 8600b91f42)