diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/Cargo.toml | 3 | ||||
-rw-r--r-- | tools/src/bin/gen_meta.rs | 112 |
2 files changed, 112 insertions, 3 deletions
diff --git a/tools/Cargo.toml b/tools/Cargo.toml index 239aae8..ece3140 100644 --- a/tools/Cargo.toml +++ b/tools/Cargo.toml @@ -4,12 +4,13 @@ version = "0.1.0" edition = "2021" [dependencies] +clap = { version = "4.0.32", features = ["derive"] } jellycommon = { path = "../common" } webm-iterable = "0.4.2" log = "0.4.17" anyhow = "1.0.68" - +serde_json = "1.0.91" [[bin]] path = "src/bin/gen_meta.rs" diff --git a/tools/src/bin/gen_meta.rs b/tools/src/bin/gen_meta.rs index 3783460..b09f4a1 100644 --- a/tools/src/bin/gen_meta.rs +++ b/tools/src/bin/gen_meta.rs @@ -1,4 +1,112 @@ +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, +}; -fn main() { - +#[derive(Parser)] +struct Args { + #[clap(short = 'I', long)] + identifier: String, + #[clap(short = 'O', long)] + write_json: bool, + #[clap(short, long)] + title: String, + #[clap(short = 'i', long)] + inputs: Vec<PathBuf>, +} + +fn main() -> anyhow::Result<()> { + let args = Args::parse(); + + let mut source = vec![]; + for fname in args.inputs { + let mut tracks = BTreeMap::new(); + let mut input = File::open(fname.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, + ) = (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), + _ => (), + } + } + } + MatroskaSpec::Video(master) => { + for c in master.get_children() { + match c { + MatroskaSpec::PixelWidth(v) => width = Some(v as usize), + MatroskaSpec::PixelHeight(v) => height = Some(v as usize), + _ => (), + } + } + } + _ => (), + } + } + tracks.insert( + index.unwrap(), + match kind.ok_or(anyhow!("track type required"))? { + 1 => SourceTrack::Video { + language: language.unwrap(), + codec: codec.unwrap(), + width: width.unwrap(), + height: height.unwrap(), + }, + 2 => SourceTrack::Audio { + channels: channels.unwrap(), + codec: codec.unwrap(), + sample_rate: sample_rate.unwrap(), + language: language.unwrap(), + }, + _ => bail!("invalid track type"), + }, + ); + } + MatroskaSpec::Tags(Master::End) => break, + _ => (), + } + } + source.push(Source { + file: fname.clone(), + tracks, + }) + } + + let k = serde_json::to_string_pretty(&ItemInfo { + title: args.title, + source, + })?; + + if args.write_json { + let mut f = File::create(format!("{}.json", args.identifier))?; + f.write_all(k.as_bytes())?; + } else { + println!("{k}") + } + + Ok(()) } |