use std::{path::Path, process::Command};
use crate::{Error, QrFrame, Result};
pub fn encode_prores(
frames: &[QrFrame],
fps: f64,
output_path: &Path,
) -> Result<()> {
let ffmpeg = which_ffmpeg()?;
let tmp_dir = tempfile::tempdir()?;
crate::write_frame_pngs(frames, tmp_dir.path())?;
let fps_str = format!("{fps}");
let input_pattern = tmp_dir.path().join("%04d.png");
let status = Command::new(&ffmpeg)
.args([
"-y",
"-r",
&fps_str,
"-i",
input_pattern.to_str().unwrap(),
"-c:v",
"prores_ks",
"-profile:v",
"4444",
"-pix_fmt",
"yuva444p10le",
output_path.to_str().unwrap(),
])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::piped())
.status()?;
if !status.success() {
return Err(Error::FfmpegFailed(format!(
"ffmpeg exited with status {status}"
)));
}
Ok(())
}
fn which_ffmpeg() -> Result<String> {
let output = Command::new("which")
.arg("ffmpeg")
.output()
.map_err(|_| Error::FfmpegNotFound)?;
if output.status.success() {
let path = String::from_utf8_lossy(&output.stdout).trim().to_string();
if !path.is_empty() {
return Ok(path);
}
}
Err(Error::FfmpegNotFound)
}