From 1d2ed0a54c21e0ab7dd01b5f3975bb5df12d40ea Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 28 Nov 2023 13:31:28 +0100 Subject: ass to webvtt conversion --- transcoder/src/lib.rs | 1 + transcoder/src/subtitles.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 transcoder/src/subtitles.rs (limited to 'transcoder') diff --git a/transcoder/src/lib.rs b/transcoder/src/lib.rs index 673946b..ef663fb 100644 --- a/transcoder/src/lib.rs +++ b/transcoder/src/lib.rs @@ -9,5 +9,6 @@ use tokio::sync::Semaphore; pub mod image; pub mod snippet; +pub mod subtitles; static LOCAL_TRANSCODING_TASKS: Semaphore = Semaphore::const_new(2); diff --git a/transcoder/src/subtitles.rs b/transcoder/src/subtitles.rs new file mode 100644 index 0000000..987405b --- /dev/null +++ b/transcoder/src/subtitles.rs @@ -0,0 +1,48 @@ +use anyhow::anyhow; +use std::fmt::Write; + +pub fn webvtt_from_ass_blocks( + title: String, + codec_private: Vec, + blocks: Vec<(u64, u64, Vec)>, +) -> anyhow::Result { + let mut out = String::new(); + + writeln!(out, "WEBVTT - {title}")?; // TODO ensure title does not contain "-->" + writeln!(out)?; + + for (pts, dur, block) in blocks { + let block = String::from_utf8(block)?; + let text = convert_block(&block).ok_or(anyhow!("bad ass xD"))?; + writeln!(out, "{} --> {}", format_time(pts), format_time(pts + dur))?; + writeln!(out, "- {text}")?; + writeln!(out)?; + } + + Ok(out) +} + +fn format_time(t: u64) -> String { + let t = t as f64 / 1_000_000.; + + // let mmm = (t.fract() * 1000.).floor(); + // let mmm = ((t * 60.).fract() * 60.).floor(); + // let mmm = ((t / 60).fract() * 60.).floor(); + + // format!("{hh:4}:{mm:02}:{ss:02}.{mmm:03}") + format!("{t}") +} + +fn convert_block(s: &str) -> Option<&str> { + // ReadOrder, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, Text + let (_read_order, s) = s.split_once(',')?; + let (_layer, s) = s.split_once(',')?; + let (_style, s) = s.split_once(',')?; + let (_name, s) = s.split_once(',')?; + let (_marginl, s) = s.split_once(',')?; + let (_marginr, s) = s.split_once(',')?; + let (_marginv, s) = s.split_once(',')?; + let (_effect, text) = s.split_once(',')?; + + Some(text) +} -- cgit v1.2.3-70-g09d2