1use crate::{
10 Result, bail, data, parser,
11 parser::Mp4Parser,
12 sub::{Subtitles, ttml},
13};
14
15pub struct StppSubsParser;
17
18impl StppSubsParser {
19 pub fn from_init(data: &[u8]) -> Result<Self> {
21 let saw_stpp = data!(false);
22 let saw_stpp_c = saw_stpp.clone();
23
24 Mp4Parser::new()
25 .base_box("moov", parser::children)
26 .base_box("trak", parser::children)
27 .base_box("mdia", parser::children)
28 .base_box("minf", parser::children)
29 .base_box("stbl", parser::children)
30 .full_box("stsd", parser::sample_description)
31 .base_box("stpp", move |box_| {
32 *saw_stpp_c.borrow_mut() = true;
33 box_.parser.stop();
34 Ok(())
35 })
36 .parse(data, false, false)?;
37
38 if !saw_stpp.take() {
39 bail!("STPP box not found.");
40 }
41
42 Ok(Self)
43 }
44
45 pub fn parse(&self, data: &[u8]) -> Result<Subtitles> {
47 let saw_mdat = data!(false);
48 let subtitles = data!(Subtitles::new());
49
50 let saw_mdat_c = saw_mdat.clone();
51 let subtitles_c = subtitles.clone();
52
53 Mp4Parser::new()
54 .base_box(
55 "mdat",
56 parser::alldata(move |data| {
57 *saw_mdat_c.borrow_mut() = true;
58 let xml = String::from_utf8(data)?;
61 subtitles_c
62 .borrow_mut()
63 .extend_cues(ttml::parse(&xml)?.into_cues());
64 Ok(())
65 }),
66 )
67 .parse(data, false, false)?;
68
69 if !saw_mdat.take() {
70 bail!("MDAT box not found.");
71 }
72
73 Ok(subtitles.take())
74 }
75}