mod media_inner;
use std::path::PathBuf;
use crate::error::EncodeError;
pub struct AudioReplacement {
video_input: PathBuf,
audio_input: PathBuf,
output: PathBuf,
}
impl AudioReplacement {
pub fn new(
video_input: impl Into<PathBuf>,
audio_input: impl Into<PathBuf>,
output: impl Into<PathBuf>,
) -> Self {
Self {
video_input: video_input.into(),
audio_input: audio_input.into(),
output: output.into(),
}
}
pub fn run(self) -> Result<(), EncodeError> {
log::debug!(
"audio replacement start video_input={} audio_input={} output={}",
self.video_input.display(),
self.audio_input.display(),
self.output.display(),
);
media_inner::run_audio_replacement(&self.video_input, &self.audio_input, &self.output)
}
}
pub struct AudioExtractor {
input: PathBuf,
output: PathBuf,
stream_index: Option<usize>,
}
impl AudioExtractor {
pub fn new(input: impl Into<PathBuf>, output: impl Into<PathBuf>) -> Self {
Self {
input: input.into(),
output: output.into(),
stream_index: None,
}
}
#[must_use]
pub fn stream_index(mut self, idx: usize) -> Self {
self.stream_index = Some(idx);
self
}
pub fn run(self) -> Result<(), EncodeError> {
log::debug!(
"audio extraction start input={} output={} stream_index={:?}",
self.input.display(),
self.output.display(),
self.stream_index,
);
media_inner::run_audio_extraction(&self.input, &self.output, self.stream_index)
}
}
pub struct AudioAdder {
video_input: PathBuf,
audio_input: PathBuf,
output: PathBuf,
loop_audio: bool,
}
impl AudioAdder {
pub fn new(
video_input: impl Into<PathBuf>,
audio_input: impl Into<PathBuf>,
output: impl Into<PathBuf>,
) -> Self {
Self {
video_input: video_input.into(),
audio_input: audio_input.into(),
output: output.into(),
loop_audio: false,
}
}
#[must_use]
pub fn loop_audio(mut self) -> Self {
self.loop_audio = true;
self
}
pub fn run(self) -> Result<(), EncodeError> {
log::debug!(
"audio addition start video_input={} audio_input={} output={} loop_audio={}",
self.video_input.display(),
self.audio_input.display(),
self.output.display(),
self.loop_audio,
);
media_inner::run_audio_addition(
&self.video_input,
&self.audio_input,
&self.output,
self.loop_audio,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn audio_replacement_run_with_nonexistent_video_input_should_fail() {
let result =
AudioReplacement::new("nonexistent_video.mp4", "nonexistent_audio.mp3", "out.mp4")
.run();
assert!(
result.is_err(),
"expected error for nonexistent video input, got Ok(())"
);
}
#[test]
fn audio_extractor_run_with_nonexistent_input_should_fail() {
let result = AudioExtractor::new("nonexistent_input.mp4", "out.mp3").run();
assert!(
result.is_err(),
"expected error for nonexistent input, got Ok(())"
);
}
#[test]
fn audio_adder_run_with_nonexistent_video_input_should_fail() {
let result =
AudioAdder::new("nonexistent_video.mp4", "nonexistent_audio.mp3", "out.mp4").run();
assert!(
result.is_err(),
"expected error for nonexistent video input, got Ok(())"
);
}
}