diff options
Diffstat (limited to 'remuxer/src/import/mod.rs')
-rw-r--r-- | remuxer/src/import/mod.rs | 82 |
1 files changed, 76 insertions, 6 deletions
diff --git a/remuxer/src/import/mod.rs b/remuxer/src/import/mod.rs index d2e0f3c..cf37b78 100644 --- a/remuxer/src/import/mod.rs +++ b/remuxer/src/import/mod.rs @@ -4,7 +4,7 @@ Copyright (C) 2023 metamuffin <metamuffin.org> */ use anyhow::{anyhow, bail, Context, Result}; -use jellycommon::{LocalTrack, SourceTrack, SourceTrackKind}; +use jellycommon::{Chapter, LocalTrack, SourceTrack, SourceTrackKind}; use jellymatroska::{ matroska::MatroskaTag, read::EbmlReader, @@ -13,7 +13,7 @@ use jellymatroska::{ use log::{debug, error, info, warn}; use std::{path::PathBuf, time::Instant}; -#[derive(Default)] +#[derive(Default, Debug)] pub struct MatroskaMetadata { pub title: Option<String>, pub description: Option<String>, @@ -22,6 +22,7 @@ pub struct MatroskaMetadata { pub track_sources: Vec<LocalTrack>, pub cover: Option<(String, Vec<u8>)>, pub infojson: Option<String>, + pub chapters: Vec<Chapter>, pub duration: f64, } @@ -71,8 +72,13 @@ fn import_read_segment(segment: &mut Unflatten) -> Result<MatroskaMetadata> { let (mut timestamp_scale, mut duration) = (None, None); let mut m = MatroskaMetadata::default(); - let (mut info_found, mut tags_found, mut attachments_found, mut tracks_found) = - (false, false, false, false); + let ( + mut info_found, + mut tags_found, + mut attachments_found, + mut tracks_found, + mut found_chapters, + ) = (false, false, false, false, false); while let Some(Ok(Unflat { children, item, .. })) = segment.n() { match item { @@ -175,7 +181,71 @@ fn import_read_segment(segment: &mut Unflatten) -> Result<MatroskaMetadata> { } } MatroskaTag::Cues(_) => {} - MatroskaTag::Chapters(_) => {} + MatroskaTag::Chapters(_) => { + found_chapters = true; + let mut children = children.unwrap(); + while let Some(Ok(Unflat { children, item, .. })) = children.n() { + match item { + MatroskaTag::EditionEntry(_) => { + let mut children = children.unwrap(); + while let Some(Ok(Unflat { children, item, .. })) = children.n() { + match item { + MatroskaTag::EditionUID(_) + | MatroskaTag::EditionFlagHidden(_) + | MatroskaTag::EditionFlagDefault(_) => {} + MatroskaTag::ChapterAtom(_) => { + let mut children = children.unwrap(); + let mut chap = Chapter::default(); + while let Some(Ok(Unflat { children, item, .. })) = + children.n() + { + match item { + MatroskaTag::ChapterFlagEnabled(_) + | MatroskaTag::ChapterFlagHidden(_) + | MatroskaTag::ChapterUID(_) => (), + MatroskaTag::ChapterTimeStart(t) => { + chap.time_start = Some(t as f64 * 1e-9) + } + MatroskaTag::ChapterTimeEnd(t) => { + chap.time_end = Some(t as f64 * 1e-9) + } + MatroskaTag::ChapterDisplay(_) => { + let mut string = String::new(); + let mut lang = String::new(); + let mut children = children.unwrap(); + while let Some(Ok(Unflat { item, .. })) = + children.n() + { + match item { + MatroskaTag::ChapString(s) => { + string = s + } + MatroskaTag::ChapLanguage(l) => { + lang = l + } + _ => warn!( + "(rscead) tag ignored: {item:?}" + ), + } + } + chap.labels.push((lang, string)) + } + _ => warn!("(rscea) tag ignored: {item:?}"), + } + } + m.chapters.push(chap); + } + _ => warn!("(rsce) tag ignored: {item:?}"), + } + } + if !m.chapters.is_empty() { + info!("{} chapters added", m.chapters.len()); + } + } + _ => warn!("(rsc) tag ignored: {item:?}"), + } + } + } MatroskaTag::Tracks(_) => { tracks_found = true; let mut children = children.unwrap(); @@ -276,7 +346,7 @@ fn import_read_segment(segment: &mut Unflatten) -> Result<MatroskaMetadata> { _ => warn!("(rs) tag ignored: {item:?}"), }; - if info_found && tracks_found && attachments_found && tags_found { + if info_found && tracks_found && attachments_found && tags_found && found_chapters { debug!("we found all we need, stopping read early"); break; } |