diff options
Diffstat (limited to 'tools/src/bin/gen_meta.rs')
-rw-r--r-- | tools/src/bin/gen_meta.rs | 147 |
1 files changed, 83 insertions, 64 deletions
diff --git a/tools/src/bin/gen_meta.rs b/tools/src/bin/gen_meta.rs index 871836b..4abbb8b 100644 --- a/tools/src/bin/gen_meta.rs +++ b/tools/src/bin/gen_meta.rs @@ -1,11 +1,14 @@ use anyhow::{anyhow, bail}; use clap::Parser; -use jellycommon::{ItemInfo, Source, SourceTrack}; -use std::{collections::BTreeMap, fs::File, io::Write, path::PathBuf}; -use webm_iterable::{ - matroska_spec::{Master, MatroskaSpec}, - WebmIterator, +use jellycommon::{ItemInfo, Source, SourceTrack, SourceTrackKind}; +use jellyebml::{ + matroska::MatroskaTag, + read::EbmlReader, + unflatten::{Unflat, Unflatten}, + Master, }; +use log::error; +use std::{collections::BTreeMap, fs::File, io::Write, path::PathBuf}; #[derive(Parser)] struct Args { @@ -20,77 +23,93 @@ struct Args { } fn main() -> anyhow::Result<()> { + env_logger::init_from_env("LOG"); let args = Args::parse(); let mut tracks = BTreeMap::new(); - let mut input = File::open(args.input.clone()).unwrap(); - for tag in WebmIterator::new(&mut input, &[MatroskaSpec::TrackEntry(Master::Start)]) { - let tag = tag?; - match tag { - MatroskaSpec::TrackEntry(master) => { - let ( - mut index, - mut language, - mut codec, - mut kind, - mut sample_rate, - mut channels, - mut width, - mut height, - mut name, - ) = (None, None, None, None, None, None, None, None, None); - for c in master.get_children() { - match c { - MatroskaSpec::CodecID(b) => codec = Some(b), - MatroskaSpec::Language(v) => language = Some(v), - MatroskaSpec::TrackNumber(v) => index = Some(v), - MatroskaSpec::TrackType(v) => kind = Some(v), - MatroskaSpec::Audio(master) => { - for c in master.get_children() { - match c { - MatroskaSpec::Channels(v) => channels = Some(v as usize), - MatroskaSpec::SamplingFrequency(v) => sample_rate = Some(v), - _ => (), + let input = File::open(args.input.clone()).unwrap(); + let mut input = EbmlReader::new(input); + + // TODO dont traverse the entire file, if the tracks are listed at the end + while let Some(item) = input.next() { + let item = item?; + match item { + MatroskaTag::Tracks(_) => { + let mut iter = Unflatten::new(&mut input); + while let Some(Ok(Unflat { children, item })) = iter.next() { + if !matches!(item, MatroskaTag::TrackEntry(_)) { + panic!("no") + } + let mut children = children.unwrap(); + let ( + mut index, + mut language, + mut codec, + mut kind, + mut sample_rate, + mut channels, + mut width, + mut height, + mut name, + ) = (None, None, None, None, None, None, None, None, None); + while let Some(Ok(Unflat { children, item })) = children.next() { + match item { + MatroskaTag::CodecID(b) => codec = Some(b), + MatroskaTag::Language(v) => language = Some(v), + MatroskaTag::TrackNumber(v) => index = Some(v), + MatroskaTag::TrackType(v) => kind = Some(v), + MatroskaTag::Name(v) => name = Some(v), + MatroskaTag::Audio(_) => { + let mut children = children.unwrap(); + while let Some(Ok(Unflat { item, .. })) = children.next() { + match item { + MatroskaTag::Channels(v) => channels = Some(v as usize), + MatroskaTag::SamplingFrequency(v) => sample_rate = Some(v), + _ => (), + } } } - } - MatroskaSpec::Video(master) => { - for c in master.get_children() { - match c { - MatroskaSpec::PixelWidth(v) => width = Some(v), - MatroskaSpec::PixelHeight(v) => height = Some(v), - _ => (), + MatroskaTag::Video(_) => { + let mut children = children.unwrap(); + while let Some(Ok(Unflat { item, .. })) = children.next() { + match item { + MatroskaTag::PixelWidth(v) => width = Some(v), + MatroskaTag::PixelHeight(v) => height = Some(v), + _ => (), + } } } + _ => (), } - MatroskaSpec::Name(v) => name = Some(v), - _ => (), } - } - tracks.insert( - index.unwrap(), - match kind.ok_or(anyhow!("track type required"))? { - 1 => SourceTrack::Video { - language: language.unwrap_or("none".to_string()), + tracks.insert( + index.unwrap(), + SourceTrack { + name: name.unwrap_or_else(|| "unnamed".to_string()), codec: codec.unwrap(), - width: width.unwrap(), - height: height.unwrap(), + language: language.unwrap_or_else(|| "none".to_string()), + kind: match kind.ok_or(anyhow!("track type required"))? { + 1 => SourceTrackKind::Video { + fps: 0.0, // TODO + width: width.unwrap(), + height: height.unwrap(), + }, + 2 => SourceTrackKind::Audio { + bit_depth: 0, // TODO + channels: channels.unwrap(), + sample_rate: sample_rate.unwrap(), + }, + 17 => SourceTrackKind::Subtitles, + _ => bail!("invalid track type"), + }, }, - 2 => SourceTrack::Audio { - channels: channels.unwrap(), - codec: codec.unwrap(), - sample_rate: sample_rate.unwrap(), - language: language.unwrap(), - }, - 17 => SourceTrack::Subtitles { - language: name.unwrap_or("unknown".to_string()), - codec: codec.unwrap(), - }, - _ => bail!("invalid track type"), - }, - ); + ); + } + error!("break!"); + drop(iter); + error!("break done!"); + break; } - MatroskaSpec::Tags(Master::End) => break, _ => (), } } |