aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-01-16 10:57:40 +0100
committermetamuffin <metamuffin@disroot.org>2023-01-16 10:57:40 +0100
commit9f9449ddd58eb07d20e14e7a75c7387c9cc17ebe (patch)
tree52e39085589303d3d2e386a3575152fb6594bb61
parente3f1a8ac9f4c9a015e9eac769fb3262e3bd16bad (diff)
downloadjellything-9f9449ddd58eb07d20e14e7a75c7387c9cc17ebe.tar
jellything-9f9449ddd58eb07d20e14e7a75c7387c9cc17ebe.tar.bz2
jellything-9f9449ddd58eb07d20e14e7a75c7387c9cc17ebe.tar.zst
write more code
-rw-r--r--Cargo.lock4
-rw-r--r--Cargo.toml2
-rw-r--r--common/src/impl.rs11
-rw-r--r--common/src/lib.rs11
-rw-r--r--matroska/Cargo.toml (renamed from ebml/Cargo.toml)2
-rw-r--r--matroska/src/bin/experiment.rs (renamed from ebml/src/bin/experiment.rs)2
-rw-r--r--matroska/src/bin/mkvdump.rs (renamed from ebml/src/bin/mkvdump.rs)2
-rw-r--r--matroska/src/lib.rs (renamed from ebml/src/lib.rs)0
-rw-r--r--matroska/src/matroska.rs (renamed from ebml/src/matroska.rs)0
-rw-r--r--matroska/src/read.rs (renamed from ebml/src/read.rs)4
-rw-r--r--matroska/src/size.rs (renamed from ebml/src/size.rs)0
-rw-r--r--matroska/src/unflatten.rs (renamed from ebml/src/unflatten.rs)10
-rw-r--r--matroska/src/write.rs (renamed from ebml/src/write.rs)0
-rw-r--r--tools/Cargo.toml10
-rw-r--r--tools/src/bin/create_item.rs32
-rw-r--r--tools/src/bin/gen_meta.rs133
-rw-r--r--tools/src/bin/import.rs187
17 files changed, 260 insertions, 150 deletions
diff --git a/Cargo.lock b/Cargo.lock
index bd455e3..c210350 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -777,7 +777,7 @@ dependencies = [
]
[[package]]
-name = "jellyebml"
+name = "jellymatroska"
version = "0.1.0"
dependencies = [
"anyhow",
@@ -824,7 +824,7 @@ dependencies = [
"clap",
"env_logger",
"jellycommon",
- "jellyebml",
+ "jellymatroska",
"log",
"serde_json",
]
diff --git a/Cargo.toml b/Cargo.toml
index db44f21..709b88f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,2 +1,2 @@
[workspace]
-members = ["server", "remuxer", "common", "tools", "ebml", "ebml_derive"]
+members = ["server", "remuxer", "common", "tools", "matroska", "ebml_derive"]
diff --git a/common/src/impl.rs b/common/src/impl.rs
new file mode 100644
index 0000000..0808eb8
--- /dev/null
+++ b/common/src/impl.rs
@@ -0,0 +1,11 @@
+use crate::SourceTrackKind;
+
+impl SourceTrackKind {
+ pub fn letter(&self) -> char {
+ match self {
+ SourceTrackKind::Video { .. } => 'v',
+ SourceTrackKind::Audio { .. } => 'a',
+ SourceTrackKind::Subtitles => 's',
+ }
+ }
+}
diff --git a/common/src/lib.rs b/common/src/lib.rs
index e329d2e..d5fc3fc 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -1,6 +1,7 @@
-use std::{collections::BTreeMap, path::PathBuf};
+pub mod r#impl;
use serde::{Deserialize, Serialize};
+use std::collections::BTreeMap;
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DirectoryInfo {
@@ -10,12 +11,6 @@ pub struct DirectoryInfo {
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ItemInfo {
pub title: String,
- pub source: Source,
-}
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-pub struct Source {
- pub path: PathBuf,
pub tracks: BTreeMap<u64, SourceTrack>,
}
@@ -28,7 +23,7 @@ pub struct SourceTrack {
}
#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(rename_all = "snake_case", tag = "kind")]
+#[serde(rename_all = "snake_case")]
pub enum SourceTrackKind {
Video {
width: u64,
diff --git a/ebml/Cargo.toml b/matroska/Cargo.toml
index 6dfc8f9..0d6e492 100644
--- a/ebml/Cargo.toml
+++ b/matroska/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "jellyebml"
+name = "jellymatroska"
version = "0.1.0"
edition = "2021"
diff --git a/ebml/src/bin/experiment.rs b/matroska/src/bin/experiment.rs
index f7dfc0c..caeae09 100644
--- a/ebml/src/bin/experiment.rs
+++ b/matroska/src/bin/experiment.rs
@@ -1,4 +1,4 @@
-use jellyebml::{matroska::MatroskaTag, read::EbmlReader, write::EbmlWriter};
+use jellymatroska::{matroska::MatroskaTag, read::EbmlReader, write::EbmlWriter};
use std::{
fs::File,
io::{stdout, BufReader, BufWriter},
diff --git a/ebml/src/bin/mkvdump.rs b/matroska/src/bin/mkvdump.rs
index 9602f61..d5b6de4 100644
--- a/ebml/src/bin/mkvdump.rs
+++ b/matroska/src/bin/mkvdump.rs
@@ -1,4 +1,4 @@
-use jellyebml::{read::EbmlReader, matroska::MatroskaTag};
+use jellymatroska::{matroska::MatroskaTag, read::EbmlReader};
use std::{fs::File, io::BufReader};
fn main() -> anyhow::Result<()> {
diff --git a/ebml/src/lib.rs b/matroska/src/lib.rs
index bcba8fd..bcba8fd 100644
--- a/ebml/src/lib.rs
+++ b/matroska/src/lib.rs
diff --git a/ebml/src/matroska.rs b/matroska/src/matroska.rs
index b4078ab..b4078ab 100644
--- a/ebml/src/matroska.rs
+++ b/matroska/src/matroska.rs
diff --git a/ebml/src/read.rs b/matroska/src/read.rs
index 1b4159d..95a98b5 100644
--- a/ebml/src/read.rs
+++ b/matroska/src/read.rs
@@ -151,6 +151,10 @@ impl Iterator for EbmlReader {
fn next(&mut self) -> Option<Self::Item> {
if let Some(t) = self.queue.pop_front() {
+ // match t {
+ // MatroskaTag::SimpleBlock(_) | MatroskaTag::Block(_) => (),
+ // _ => debug!("reader yield: {t:?}"),
+ // };
Some(Ok(t))
} else {
match self.read_stuff() {
diff --git a/ebml/src/size.rs b/matroska/src/size.rs
index e774f0a..e774f0a 100644
--- a/ebml/src/size.rs
+++ b/matroska/src/size.rs
diff --git a/ebml/src/unflatten.rs b/matroska/src/unflatten.rs
index e1dd0a2..03ca0f5 100644
--- a/ebml/src/unflatten.rs
+++ b/matroska/src/unflatten.rs
@@ -20,6 +20,16 @@ impl<'a> Unflatten<'a> {
end: None,
}
}
+ pub fn new_with_end(
+ inner: &'a mut dyn Iterator<Item = Result<MatroskaTag>>,
+ start: MatroskaTag,
+ ) -> Self {
+ Self {
+ inner,
+ stop: false,
+ end: Some(MatroskaTag::construct_master(start.id(), Master::End).unwrap()),
+ }
+ }
pub fn next(&mut self) -> Option<Result<Unflat>> {
if self.stop {
diff --git a/ebml/src/write.rs b/matroska/src/write.rs
index fc12ffc..fc12ffc 100644
--- a/ebml/src/write.rs
+++ b/matroska/src/write.rs
diff --git a/tools/Cargo.toml b/tools/Cargo.toml
index 6a1bcfa..c49dea1 100644
--- a/tools/Cargo.toml
+++ b/tools/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
[dependencies]
jellycommon = { path = "../common" }
-jellyebml = {path = "../ebml"}
+jellymatroska = {path = "../matroska"}
clap = { version = "4.0.32", features = ["derive"] }
@@ -15,5 +15,9 @@ anyhow = "1.0.68"
serde_json = "1.0.91"
[[bin]]
-path = "src/bin/gen_meta.rs"
-name = "jellything-gen-meta"
+path = "src/bin/create_item.rs"
+name = "jellything-create-item"
+
+[[bin]]
+path = "src/bin/import.rs"
+name = "jellything-import"
diff --git a/tools/src/bin/create_item.rs b/tools/src/bin/create_item.rs
new file mode 100644
index 0000000..7628f95
--- /dev/null
+++ b/tools/src/bin/create_item.rs
@@ -0,0 +1,32 @@
+use std::{fs::File, io::Write, path::PathBuf};
+
+use clap::Parser;
+use jellycommon::ItemInfo;
+
+#[derive(Parser)]
+struct Args {
+ #[clap(short = 'I', long)]
+ item: PathBuf,
+ #[clap(short = 'd', long)]
+ dry: bool,
+ #[clap(short, long)]
+ title: String,
+}
+
+fn main() -> anyhow::Result<()> {
+ let args = Args::parse();
+
+ let iteminfo = ItemInfo {
+ title: args.title,
+ tracks: Default::default(),
+ };
+
+ let k = serde_json::to_string_pretty(&iteminfo)?;
+ if args.dry {
+ println!("{k}")
+ } else {
+ let mut f = File::create(args.item)?;
+ f.write_all(k.as_bytes())?;
+ }
+ Ok(())
+}
diff --git a/tools/src/bin/gen_meta.rs b/tools/src/bin/gen_meta.rs
deleted file mode 100644
index 4abbb8b..0000000
--- a/tools/src/bin/gen_meta.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-use anyhow::{anyhow, bail};
-use clap::Parser;
-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 {
- #[clap(short = 'I', long)]
- identifier: String,
- #[clap(short = 'O', long)]
- write_json: bool,
- #[clap(short, long)]
- title: String,
- #[clap(short = 'i', long)]
- input: PathBuf,
-}
-
-fn main() -> anyhow::Result<()> {
- env_logger::init_from_env("LOG");
- let args = Args::parse();
-
- let mut tracks = BTreeMap::new();
- 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),
- _ => (),
- }
- }
- }
- 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),
- _ => (),
- }
- }
- }
- _ => (),
- }
- }
- tracks.insert(
- index.unwrap(),
- SourceTrack {
- name: name.unwrap_or_else(|| "unnamed".to_string()),
- codec: codec.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"),
- },
- },
- );
- }
- error!("break!");
- drop(iter);
- error!("break done!");
- break;
- }
- _ => (),
- }
- }
-
- let k = serde_json::to_string_pretty(&ItemInfo {
- title: args.title,
- source: Source {
- path: args.input.clone(),
- tracks,
- },
- })?;
-
- if args.write_json {
- let mut f = File::create(format!("{}.json", args.identifier))?;
- f.write_all(k.as_bytes())?;
- } else {
- println!("{k}")
- }
-
- Ok(())
-}
diff --git a/tools/src/bin/import.rs b/tools/src/bin/import.rs
new file mode 100644
index 0000000..dfa5267
--- /dev/null
+++ b/tools/src/bin/import.rs
@@ -0,0 +1,187 @@
+use anyhow::{anyhow, bail, Result};
+use clap::Parser;
+use jellycommon::{ItemInfo, SourceTrack, SourceTrackKind};
+use jellymatroska::{
+ matroska::MatroskaTag,
+ read::EbmlReader,
+ unflatten::{Unflat, Unflatten},
+ Master,
+};
+use log::{debug, error, info, trace, warn};
+use std::{fs::File, io::Write, path::PathBuf};
+
+#[derive(Parser)]
+struct Args {
+ #[clap(short = 'I', long)]
+ item: PathBuf,
+ #[clap(short = 'd', long)]
+ dry: bool,
+ #[clap(short = 'i', long)]
+ input: PathBuf,
+}
+
+fn main() -> anyhow::Result<()> {
+ env_logger::init_from_env("LOG");
+ let args = Args::parse();
+
+ let mut iteminfo: ItemInfo = serde_json::from_reader(File::open(&args.item)?)?;
+ // let iteminfo_orig = iteminfo.clone();
+
+ let input = File::open(args.input.clone()).unwrap();
+ let mut input = EbmlReader::new(input);
+
+ read(&mut input, &mut iteminfo)?;
+
+ let k = serde_json::to_string_pretty(&iteminfo)?;
+ if args.dry {
+ println!("{k}")
+ } else {
+ let mut f = File::create(args.item)?;
+ f.write_all(k.as_bytes())?;
+ }
+
+ Ok(())
+}
+
+pub fn read(input: &mut EbmlReader, iteminfo: &mut ItemInfo) -> Result<()> {
+ // TODO dont traverse the entire file, if the tracks are listed at the end
+ let mut sbc = 0;
+ while let Some(item) = input.next() {
+ let item = item?;
+ match item {
+ MatroskaTag::Cluster(_) => {
+ info!("start of cluster found");
+ let mut iter = Unflatten::new_with_end(input, item);
+ while let Some(Ok(Unflat { children, item })) = iter.next() {
+ match item {
+ MatroskaTag::BlockGroup(_) => {
+ debug!("group");
+ let mut iter = children.unwrap();
+ while let Some(Ok(Unflat { children, item })) = iter.next() {
+ match item {
+ MatroskaTag::Block(_) => (),
+ _ => trace!("{item:?}"),
+ }
+ }
+ }
+ MatroskaTag::SimpleBlock(_) => {
+ // debug!("simple");
+ }
+ _ => debug!("(rc) tag ignored: {item:?}"),
+ }
+ }
+ sbc += 1;
+ }
+ MatroskaTag::Tags(_) => {
+ Unflatten::new_with_end(input, item);
+ }
+ MatroskaTag::Cues(_) => {
+ let mut iter = Unflatten::new_with_end(input, item);
+ while let Some(Ok(Unflat { children, item })) = iter.next() {
+ match item {
+ MatroskaTag::CuePoint(_) => {
+ let mut children = children.unwrap();
+ while let Some(Ok(Unflat { children, item })) = children.next() {
+ // error!("{item:?}")
+ }
+ }
+ _ => (),
+ }
+ }
+ }
+ MatroskaTag::Chapters(_) => {
+ Unflatten::new_with_end(input, item);
+ }
+ MatroskaTag::Tracks(_) => {
+ let mut iter = Unflatten::new_with_end(input, item);
+ while let Some(Ok(Unflat { children, item })) = iter.next() {
+ match item {
+ MatroskaTag::TrackEntry(_) => {
+ 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,
+ mut fps,
+ mut bit_depth,
+ ) = (
+ None, None, 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)
+ }
+ MatroskaTag::BitDepth(v) => bit_depth = 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),
+ MatroskaTag::FrameRate(v) => fps = Some(v),
+ _ => (),
+ }
+ }
+ }
+ _ => (),
+ }
+ }
+ let index = index.unwrap();
+ let kind = match kind.ok_or(anyhow!("track type required"))? {
+ 1 => SourceTrackKind::Video {
+ fps: fps.unwrap_or(f64::NAN), // TODO
+ width: width.unwrap(),
+ height: height.unwrap(),
+ },
+ 2 => SourceTrackKind::Audio {
+ bit_depth: bit_depth.unwrap_or(0) as usize, // TODO
+ channels: channels.unwrap(),
+ sample_rate: sample_rate.unwrap(),
+ },
+ 17 => SourceTrackKind::Subtitles,
+ _ => bail!("invalid track type"),
+ };
+ iteminfo.tracks.insert(
+ index,
+ SourceTrack {
+ name: name.unwrap_or_else(|| "unnamed".to_string()),
+ codec: codec.unwrap(),
+ language: language.unwrap_or_else(|| "none".to_string()),
+ kind,
+ },
+ );
+ }
+ _ => debug!("(rt) tag ignored: {item:?}"),
+ }
+ }
+ }
+ MatroskaTag::Segment(Master::End) => break,
+ _ => debug!("(r) tag ignored: {item:?}"),
+ }
+ }
+ info!("clusters {sbc}");
+ Ok(())
+}