use super::atom::Atom; use super::ilst::parse_ilst; use super::read::skip_unneeded; use super::trak::Trak; use crate::error::Result; use crate::types::tag::Tag; use byteorder::{BigEndian, ReadBytesExt}; use std::io::{Read, Seek, SeekFrom}; pub(crate) struct Moov { pub(crate) traks: Vec, // Represents a parsed moov.udta.meta.ilst since we don't need anything else pub(crate) meta: Option, } impl Moov { pub(crate) fn parse(data: &mut R) -> Result where R: Read + Seek, { let mut traks = Vec::new(); let mut meta = None; while let Ok(atom) = Atom::read(data) { match &*atom.ident { //"trak" => traks.push(Trak::parse(data, &atom)?), "udta" => { meta = meta_from_udta(data, atom.len - 8)?; }, _ => skip_unneeded(data, atom.extended, atom.len)?, } } Ok(Self { traks, meta }) } } fn meta_from_udta(data: &mut R, len: u64) -> Result> where R: Read + Seek, { let mut read = 8; let mut meta = (false, 0_u64); while read < len { let atom = Atom::read(data)?; if &*atom.ident == "meta" { meta = (true, atom.len); break; } read += atom.len; skip_unneeded(data, atom.extended, atom.len)?; } if !meta.0 { return Ok(None); } // The meta atom has 4 bytes we don't care about // Version (1) // Flags (3) let _version_flags = data.read_u32::()?; read = 8; let mut islt = (false, 0_u64); while read < meta.1 { let atom = Atom::read(data)?; if &*atom.ident == "ilst" { islt = (true, atom.len); break; } read += atom.len; skip_unneeded(data, atom.extended, atom.len)?; } if !islt.0 { return Ok(None); } parse_ilst(data, islt.1 - 8) }