use crate::{
Result, bail, data, parser,
parser::Mp4Parser,
sub::{Subtitles, ttml},
};
pub struct StppSubsParser;
impl StppSubsParser {
pub fn from_init(data: &[u8]) -> Result<Self> {
let saw_stpp = data!(false);
let saw_stpp_c = saw_stpp.clone();
Mp4Parser::new()
.base_box("moov", parser::children)
.base_box("trak", parser::children)
.base_box("mdia", parser::children)
.base_box("minf", parser::children)
.base_box("stbl", parser::children)
.full_box("stsd", parser::sample_description)
.base_box("stpp", move |box_| {
*saw_stpp_c.borrow_mut() = true;
box_.parser.stop();
Ok(())
})
.parse(data, false, false)?;
if !saw_stpp.take() {
bail!("STPP box not found.");
}
Ok(Self)
}
pub fn parse(&self, data: &[u8]) -> Result<Subtitles> {
let saw_mdat = data!(false);
let subtitles = data!(Subtitles::new());
let saw_mdat_c = saw_mdat.clone();
let subtitles_c = subtitles.clone();
Mp4Parser::new()
.base_box(
"mdat",
parser::alldata(move |data| {
*saw_mdat_c.borrow_mut() = true;
let xml = String::from_utf8(data)?;
subtitles_c
.borrow_mut()
.extend_cues(ttml::parse(&xml)?.into_cues());
Ok(())
}),
)
.parse(data, false, false)?;
if !saw_mdat.take() {
bail!("MDAT box not found.");
}
Ok(subtitles.take())
}
}