tonhowtf/omniget · error · anyhow::Error
ffmpeg process failed
Error message
ffmpeg process failed: {} What it means
convert() waits for the ffmpeg child process while streaming its stdout for progress. If child.wait() itself errors (the process could not be waited on — usually because it was already reaped or the runtime was interrupted), the error is wrapped into this anyhow error. Note this is a wait error, not a non-zero exit status.
Solutions
- Ensure cancel_token is the only mechanism that terminates ffmpeg (avoid killing the child elsewhere).
- Keep the tokio runtime alive until convert's future completes; don't abort the task holding it.
- Check exit status separately: if wait() succeeds with a non-zero code, report stderr, not this error.
- Log whether a cancellation/select race occurred when this fires.
Example fix
// before
status = child.wait() => {
let _ = line_reader.await;
status.map_err(|e| anyhow!("ffmpeg process failed: {}", e))
}
// after
status = child.wait() => {
let _ = line_reader.await;
let status = status.map_err(|e| anyhow!("ffmpeg process failed: {}", e))?;
if !status.success() {
anyhow::bail!("ffmpeg exited with {}: {}", status, stderr_snapshot);
}
Ok(())
} Defensive patterns
Strategy: try-catch
Try / catch
match convert(/* ... */).await {
Err(e) if e.to_string().contains("ffmpeg process failed") => {
// wait() failed: likely external kill or runtime teardown
log::error!("ffmpeg wait error (not an ffmpeg exit failure): {e}");
mark_job_interrupted(job_id);
}
other => other?,
} Prevention
- Use only the cancel token to stop ffmpeg; don't kill the child elsewhere
- Hold the tokio runtime open until conversion futures resolve
- Distinguish wait() errors from non-zero exit codes in error handling
When it happens
Trigger: Calling convert in an environment where the child is killed/reaped externally before wait() completes, or the tokio runtime drops/shuts down while waiting; also SIGKILL of the parent causing handle invalidation.
Common situations: Long conversions in apps that are suspended or terminated; double-cancel paths racing with wait(); sandboxed environments that forbid waiting on children.
Related errors
- Send cancelled while paused
- yt-dlp process failed
- MB não cabem s de vídeo — aumente o alvo ou encurte o clipe
- a janela de corte ficou vazia — o vídeo tem
- alvo pequeno demais para
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/a3166997fdf84b4e.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/ffmpeg.rs:374
let progress = progress_tx.clone();
let line_reader = tokio::spawn(async move {
while let Ok(Some(line)) = lines.next_line().await {
if cancel.is_cancelled() {
break;
}
if let Some(us) = parse_out_time_us(&line) {
if total_duration_us > 0 {
let pct = (us as f64 / total_duration_us as f64 * 100.0).min(100.0);
let _ = progress.send(ProgressUpdate::percent(pct)).await;
}
}
}
});
let result = tokio::select! {
status = child.wait() => {
let _ = line_reader.await;
status.map_err(|e| anyhow!("ffmpeg process failed: {}", e))
}
_ = cancel_token.cancelled() => {
let _ = child.kill().await;
let _ = line_reader.await;
return Ok(ConversionResult {
success: false,
output_path: opts.output_path.clone(),
file_size_bytes: 0,
duration_seconds: 0.0,
error: Some("Conversion cancelled".to_string()),
});
}
};
match result {
Ok(status) if status.success() => {
let _ = progress_tx.send(ProgressUpdate::percent(100.0)).await;
let meta = std::fs::metadata(output_path);View on GitHub (pinned to 8600b91f42)