aboutsummaryrefslogtreecommitdiff
path: root/tools/src
diff options
context:
space:
mode:
Diffstat (limited to 'tools/src')
-rw-r--r--tools/src/bin/gen_meta.rs112
1 files changed, 110 insertions, 2 deletions
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(())
}