use super::mkv_discard::{Matroska, matroska_trims};
use super::mp4_edit::{Edit, audio_track};
use crate::wav::layout::wav_layout;
const MP4_EXTENSIONS: [&str; 6] = ["mp4", "m4a", "m4v", "mov", "3gp", "m4b"];
const MKV_EXTENSIONS: [&str; 3] = ["mkv", "webm", "mka"];
#[derive(Debug, Clone, Copy, Default)]
pub(super) struct Trims {
pub(super) edit: Option<Edit>,
pub(super) media_scale: Option<u32>,
pub(super) matroska: Option<Matroska>,
pub(super) wav: Option<WavHeader>,
}
#[derive(Debug, Clone, Copy)]
pub(super) struct WavHeader {
pub(super) layout: Option<u64>,
}
const WAV_PREFIX: u64 = 1 << 20;
impl Trims {
pub(super) fn of<R: std::io::Read + std::io::Seek>(
r: &mut R,
head: &[u8],
hint: Option<&str>,
) -> Self {
let named =
|list: &[&str]| hint.is_some_and(|h| list.iter().any(|e| e.eq_ignore_ascii_case(h)));
if head.get(4..8) == Some(b"ftyp") || named(&MP4_EXTENSIONS) {
let track = audio_track(r).unwrap_or_default();
Self {
edit: track.edit,
media_scale: track.media_scale,
..Self::default()
}
} else if head.starts_with(&[0x1A, 0x45, 0xDF, 0xA3]) || named(&MKV_EXTENSIONS) {
Self {
matroska: matroska_trims(r),
..Self::default()
}
} else if head.starts_with(b"RIFF") {
let mut prefix = Vec::new();
let read = r.seek(std::io::SeekFrom::Start(0)).is_ok()
&& std::io::Read::read_to_end(
&mut std::io::Read::take(&mut *r, WAV_PREFIX),
&mut prefix,
)
.is_ok();
Self {
wav: (read && prefix.get(8..12) == Some(b"WAVE")).then(|| WavHeader {
layout: wav_layout(&prefix),
}),
..Self::default()
}
} else {
Self::default()
}
}
}