From 46fe19f1c0814fa3975f60dcdd17c1680b161c3c Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 29 Jan 2024 20:20:42 +0100 Subject: caching subtitles --- base/src/cache.rs | 4 ++-- common/src/jhls.rs | 3 ++- stream/src/webvtt.rs | 32 +++++++++++++++++++++++++------- transcoder/src/subtitles.rs | 4 ++-- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/base/src/cache.rs b/base/src/cache.rs index 5e47d0e..68f191e 100644 --- a/base/src/cache.rs +++ b/base/src/cache.rs @@ -176,10 +176,10 @@ where pub async fn async_cache_memory( seed: &[&str], - mut generate: Fun, + generate: Fun, ) -> Result, anyhow::Error> where - Fun: FnMut() -> Fut, + Fun: FnOnce() -> Fut, Fut: Future>, T: Encode + Decode + Send + Sync + 'static, { diff --git a/common/src/jhls.rs b/common/src/jhls.rs index f4448b6..12fa2d6 100644 --- a/common/src/jhls.rs +++ b/common/src/jhls.rs @@ -1,3 +1,4 @@ +use bincode::{Decode, Encode}; /* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. @@ -32,7 +33,7 @@ pub enum EncodingProfile { }, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Encode, Decode)] pub struct SubtitleCue { pub start: f64, pub end: f64, diff --git a/stream/src/webvtt.rs b/stream/src/webvtt.rs index e9d03bf..b29c7c5 100644 --- a/stream/src/webvtt.rs +++ b/stream/src/webvtt.rs @@ -4,7 +4,7 @@ Copyright (C) 2024 metamuffin */ use anyhow::{anyhow, Context, Result}; -use jellybase::CONF; +use jellybase::{cache::async_cache_memory, CONF}; use jellycommon::{stream::StreamSpec, LocalTrack, Node}; use jellyremuxer::extract::extract_track; use jellytranscoder::subtitles::{parse_subtitles, write_webvtt}; @@ -26,16 +26,34 @@ pub async fn vtt_stream( let track = &node.public.media.unwrap().tracks[tracki]; let cp = local_track.codec_private.clone(); - let blocks = - tokio::task::spawn_blocking(move || extract_track(CONF.media_path.clone(), local_track)) + let subtitles = async_cache_memory( + &[ + "vtt", + &format!( + "{} {}", + local_track.path.to_str().unwrap(), + local_track.track + ), + ], + move || async move { + let blocks = tokio::task::spawn_blocking(move || { + extract_track(CONF.media_path.clone(), local_track) + }) .await??; + let subtitles = parse_subtitles(&track.codec, cp, blocks)?; + Ok(subtitles) + }, + ) + .await?; - let subtitles = parse_subtitles(&track.codec, cp, blocks)?; let output = if json { - serde_json::to_string(&subtitles)? + serde_json::to_string(subtitles.as_ref())? } else { - write_webvtt(node.public.title.clone().unwrap_or_default(), subtitles) - .context("writing webvtt")? + write_webvtt( + node.public.title.clone().unwrap_or_default(), + subtitles.as_ref(), + ) + .context("writing webvtt")? }; tokio::task::spawn(async move { let _ = b.write_all(output.as_bytes()).await; diff --git a/transcoder/src/subtitles.rs b/transcoder/src/subtitles.rs index 9118ebc..2532781 100644 --- a/transcoder/src/subtitles.rs +++ b/transcoder/src/subtitles.rs @@ -28,7 +28,7 @@ pub fn parse_subtitles( .context(anyhow!("parsing {codec} subtitles")) } -pub fn write_webvtt(title: String, subtitles: Vec) -> anyhow::Result { +pub fn write_webvtt(title: String, subtitles: &[SubtitleCue]) -> anyhow::Result { let mut out = String::new(); writeln!(out, "WEBVTT - {title}")?; // TODO ensure title does not contain "-->" @@ -39,7 +39,7 @@ pub fn write_webvtt(title: String, subtitles: Vec) -> anyhow::Resul content, } in subtitles { - writeln!(out, "{} --> {}", format_time(start), format_time(end))?; + writeln!(out, "{} --> {}", format_time(*start), format_time(*end))?; writeln!(out, "- {content}")?; writeln!(out)?; } -- cgit v1.2.3-70-g09d2