use std::time::Duration;
use crate::error::StreamError;
pub struct DashOutput {
output_dir: String,
input_path: Option<String>,
segment_duration: Duration,
}
impl DashOutput {
#[must_use]
pub fn new(output_dir: &str) -> Self {
Self {
output_dir: output_dir.to_owned(),
input_path: None,
segment_duration: Duration::from_secs(4),
}
}
#[must_use]
pub fn input(mut self, path: &str) -> Self {
self.input_path = Some(path.to_owned());
self
}
#[must_use]
pub fn segment_duration(mut self, d: Duration) -> Self {
self.segment_duration = d;
self
}
pub fn build(self) -> Result<Self, StreamError> {
if self.output_dir.is_empty() {
return Err(StreamError::InvalidConfig {
reason: "output_dir must not be empty".into(),
});
}
if self.input_path.is_none() {
return Err(StreamError::InvalidConfig {
reason: "input path is required".into(),
});
}
log::info!(
"dash output configured output_dir={} segment_duration={:.1}s",
self.output_dir,
self.segment_duration.as_secs_f64(),
);
Ok(self)
}
pub fn write(self) -> Result<(), StreamError> {
let input_path = self.input_path.ok_or_else(|| StreamError::InvalidConfig {
reason: "input path missing after build (internal error)".into(),
})?;
let seg_secs = self.segment_duration.as_secs_f64();
log::info!(
"dash write starting input={input_path} output_dir={} segment_duration={seg_secs:.1}s",
self.output_dir
);
crate::dash_inner::write_dash(&input_path, &self.output_dir, seg_secs)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_should_store_output_dir() {
let d = DashOutput::new("/tmp/dash");
assert_eq!(d.output_dir, "/tmp/dash");
}
#[test]
fn build_without_input_should_return_invalid_config() {
let result = DashOutput::new("/tmp/dash").build();
assert!(matches!(result, Err(StreamError::InvalidConfig { .. })));
}
#[test]
fn build_with_valid_config_should_succeed() {
let result = DashOutput::new("/tmp/dash").input("/src/video.mp4").build();
assert!(result.is_ok());
}
#[test]
fn write_without_build_should_return_invalid_config() {
let result = DashOutput::new("/tmp/dash").write();
assert!(matches!(result, Err(StreamError::InvalidConfig { .. })));
}
}