use std::future::Future;
use std::path::PathBuf;
use suno_core::{AudioFormat, Ffmpeg, FfmpegError, WebpEncodeSettings};
pub struct FfmpegAdapter {
scratch: PathBuf,
}
impl FfmpegAdapter {
pub fn new(scratch: impl Into<PathBuf>) -> Self {
Self {
scratch: scratch.into(),
}
}
}
impl Ffmpeg for FfmpegAdapter {
fn wav_to_lossless(
&self,
wav: &[u8],
format: AudioFormat,
) -> impl Future<Output = Result<Vec<u8>, FfmpegError>> + Send {
let scratch = self.scratch.clone();
let wav = wav.to_vec();
async move {
if let Err(err) = std::fs::create_dir_all(&scratch) {
return Err(crate::diskspace::ffmpeg_error(
&err,
format!("could not create scratch {}: {err}", scratch.display()),
));
}
tokio::task::spawn_blocking(move || {
crate::transcode::wav_to_lossless(&wav, format, &scratch)
})
.await
.map_err(|err| FfmpegError::new(format!("transcode task failed: {err}")))?
.map_err(|err| crate::diskspace::ffmpeg_error_from_anyhow(&err, err.to_string()))
}
}
fn mp4_to_webp(
&self,
mp4: &[u8],
settings: WebpEncodeSettings,
) -> impl Future<Output = Result<Vec<u8>, FfmpegError>> + Send {
let mp4 = mp4.to_vec();
async move {
tokio::task::spawn_blocking(move || crate::transcode::mp4_to_webp(&mp4, settings))
.await
.map_err(|err| FfmpegError::new(format!("transcode task failed: {err}")))?
.map_err(|err| FfmpegError::new(err.to_string()))
}
}
}