use std::path::Path;
use std::time::Duration;
use crate::color::ColorSpace;
use crate::error::{Error, Result};
use crate::identify::{Container, Encoding};
use crate::media::{Packet, Rational};
mod mp4;
mod webm;
#[derive(Clone, Debug)]
pub struct VideoTrack {
pub encoding: Encoding,
pub width: u32,
pub height: u32,
pub frame_rate: Rational,
pub color: ColorSpace,
pub config_record: Vec<u8>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Written {
pub samples: u64,
pub duration: Duration,
pub bytes: u64,
}
pub trait Muxer: Send {
fn write(&mut self, packet: Packet) -> Result<()>;
fn finish(self: Box<Self>) -> Result<Written>;
}
pub fn container_for(encoding: Encoding) -> Result<Container> {
match encoding {
Encoding::H264 => Ok(Container::Mp4),
Encoding::Av1 => Ok(Container::WebM),
other => Err(Error::NoEncoder {
encoding: other,
remedy: "vtome writes H.264 and AV1 only".to_string(),
}),
}
}
pub fn create(path: &Path, track: VideoTrack) -> Result<Box<dyn Muxer>> {
match container_for(track.encoding)? {
Container::Mp4 => Ok(Box::new(mp4::Mp4Muxer::create(path, track)?)),
_ => Ok(Box::new(webm::WebmMuxer::create(path, track)?)),
}
}
fn frame_duration(rate: Rational) -> Duration {
let duration = rate.frame_duration();
if duration.is_zero() {
Duration::from_millis(40)
} else {
duration
}
}
fn mux_error(reason: impl Into<String>) -> Error {
Error::Encode {
reason: reason.into(),
}
}