From b07bafa8eda0daa472d47e17042e9804f1d1ba66 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 14 May 2024 00:25:19 +0200 Subject: better handle BlockGroup without duration --- remuxer/src/extract.rs | 8 ++++---- transcoder/src/subtitles.rs | 18 +++++++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/remuxer/src/extract.rs b/remuxer/src/extract.rs index bef5d4d..e70adf4 100644 --- a/remuxer/src/extract.rs +++ b/remuxer/src/extract.rs @@ -13,7 +13,7 @@ use std::{fs::File, io::BufReader, path::PathBuf}; pub fn extract_track( path_base: PathBuf, track_info: LocalTrack, -) -> anyhow::Result)>> { +) -> anyhow::Result, Vec)>> { let source_path = path_base.join(track_info.path); let file = File::open(&source_path)?; let mut reader = EbmlReader::new(BufReader::new(file)); @@ -35,7 +35,7 @@ pub fn extract_track( Ok(out) } -pub fn read_group(segment: &mut EbmlReader) -> anyhow::Result<(u64, Block)> { +pub fn read_group(segment: &mut EbmlReader) -> anyhow::Result<(Option, Block)> { let (mut dur, mut block) = (None, None); for _ in 0..10 { let (_, item) = segment.next().ok_or(anyhow!("eof"))??; @@ -45,10 +45,10 @@ pub fn read_group(segment: &mut EbmlReader) -> anyhow::Result<(u64, Block)> { MatroskaTag::Cluster(_) => bail!("unexpected cluster"), MatroskaTag::Timestamp(_) => (), MatroskaTag::SimpleBlock(block) => { - return Ok((1000, block)); // HDMV/PGS does not use duration?! + return Ok((None, block)); // HDMV/PGS does not use duration?! } MatroskaTag::BlockGroup(Master::Start) => (), - MatroskaTag::BlockGroup(Master::End) => return Ok((dur.unwrap(), block.unwrap())), + MatroskaTag::BlockGroup(Master::End) => return Ok((dur, block.unwrap())), MatroskaTag::BlockDuration(duration) => dur = Some(duration), MatroskaTag::Block(blk) => block = Some(blk), MatroskaTag::Cues(_) => bail!("reached cues, this is the end"), diff --git a/transcoder/src/subtitles.rs b/transcoder/src/subtitles.rs index 2532781..db23d5b 100644 --- a/transcoder/src/subtitles.rs +++ b/transcoder/src/subtitles.rs @@ -10,7 +10,7 @@ use std::fmt::Write; pub fn parse_subtitles( codec: &str, codec_private: Option>, - blocks: Vec<(u64, u64, Vec)>, + blocks: Vec<(u64, Option, Vec)>, ) -> anyhow::Result> { match codec { "D_WEBVTT/SUBTITLES" => parse_webvtt_blocks(blocks), @@ -46,26 +46,30 @@ pub fn write_webvtt(title: String, subtitles: &[SubtitleCue]) -> anyhow::Result< Ok(out) } -pub fn parse_webvtt_blocks(blocks: Vec<(u64, u64, Vec)>) -> anyhow::Result> { +pub fn parse_webvtt_blocks( + blocks: Vec<(u64, Option, Vec)>, +) -> anyhow::Result> { let mut out = Vec::new(); for (pts, dur, block) in blocks { let content = String::from_utf8_lossy(&block).trim().to_string(); out.push(SubtitleCue { content, start: pts as f64 / 1000., - end: (pts + dur) as f64 / 1000., + end: (pts + dur.unwrap_or(1000)) as f64 / 1000., }) } Ok(out) } -pub fn parse_subrip_blocks(blocks: Vec<(u64, u64, Vec)>) -> anyhow::Result> { +pub fn parse_subrip_blocks( + blocks: Vec<(u64, Option, Vec)>, +) -> anyhow::Result> { let mut out = Vec::new(); for (pts, dur, block) in blocks { let content = String::from_utf8_lossy(&block).trim().to_string(); out.push(SubtitleCue { content, start: pts as f64 / 1000., - end: (pts + dur) as f64 / 1000., + end: (pts + dur.unwrap_or(1000)) as f64 / 1000., }); } Ok(out) @@ -73,7 +77,7 @@ pub fn parse_subrip_blocks(blocks: Vec<(u64, u64, Vec)>) -> anyhow::Result, - blocks: Vec<(u64, u64, Vec)>, + blocks: Vec<(u64, Option, Vec)>, ) -> anyhow::Result> { // TODO dont ignore codec_private @@ -98,7 +102,7 @@ pub fn parse_ass_blocks( out.push(SubtitleCue { content: text.to_owned(), start: pts as f64 / 1000., - end: (pts + dur) as f64 / 1000., + end: (pts + dur.unwrap_or(1000)) as f64 / 1000., }) } Ok(out) -- cgit v1.2.3-70-g09d2