feat: Add ffmpeg remuxing for faststart

This commit is contained in:
2026-04-13 16:37:52 +02:00
parent fbf8681df0
commit 73692b0a02
7 changed files with 420 additions and 236 deletions
+1
View File
@@ -3,6 +3,7 @@ pub mod config;
pub mod error;
pub mod models;
pub mod routes;
pub mod transcribe;
use std::sync::Arc;
+70
View File
@@ -0,0 +1,70 @@
use std::path::Path;
use std::process::Stdio;
use tempfile::NamedTempFile;
use tokio::process::Command;
use tracing::debug;
#[derive(Debug)]
pub enum FfmpegError {
Spawn(std::io::Error),
NonZeroExit { code: Option<i32>, stderr: String },
TempFile(std::io::Error),
}
impl std::fmt::Display for FfmpegError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Spawn(e) => write!(f, "failed to spawn ffmpeg: {e}"),
Self::NonZeroExit { code, stderr } => {
write!(f, "ffmpeg exited with {code:?}: {stderr}")
}
Self::TempFile(e) => write!(f, "failed to create temp file: {e}"),
}
}
}
impl std::error::Error for FfmpegError {}
/// Remux an m4a file with `-movflags faststart` so the `moov` atom sits at the
/// start of the file. Returns a NamedTempFile that is auto-deleted on drop.
///
/// Lossless — just a container-level rewrite, typically <1s for dictation-sized files.
pub async fn remux_faststart(input: &Path) -> Result<NamedTempFile, FfmpegError> {
let output = tempfile::Builder::new()
.prefix("doctate-remux-")
.suffix(".m4a")
.tempfile()
.map_err(FfmpegError::TempFile)?;
let output_path = output.path().to_owned();
let result = Command::new("ffmpeg")
.arg("-hide_banner")
.arg("-loglevel")
.arg("error")
.arg("-y")
.arg("-i")
.arg(input)
.arg("-c")
.arg("copy")
.arg("-movflags")
.arg("faststart")
.arg(&output_path)
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::piped())
.output()
.await
.map_err(FfmpegError::Spawn)?;
if !result.status.success() {
return Err(FfmpegError::NonZeroExit {
code: result.status.code(),
stderr: String::from_utf8_lossy(&result.stderr).into_owned(),
});
}
debug!(?output_path, "ffmpeg remux completed");
Ok(output)
}
+1
View File
@@ -0,0 +1 @@
pub mod ffmpeg;