/* 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. Copyright (C) 2024 metamuffin */ use anyhow::{anyhow, bail, Context, Result}; use jellybase::CONF; use jellycommon::{stream::StreamSpec, LocalTrack, Node}; use jellyremuxer::extract::extract_track; use jellytranscoder::subtitles::webvtt_from_ass_blocks; use tokio::io::{AsyncWriteExt, DuplexStream}; pub async fn webvtt_stream( node: Node, local_tracks: Vec, spec: StreamSpec, mut b: DuplexStream, ) -> Result<()> { // TODO cache // TODO should use snippets too? big films take too long... let tracki = *spec.tracks.get(0).ok_or(anyhow!("no track selected"))?; let local_track = local_tracks.get(0).ok_or(anyhow!("no tracks"))?.clone(); let track = &node.public.media.unwrap().tracks[tracki]; match track.codec.as_str() { "S_TEXT/UTF8" => bail!("no subrip yet"), "S_VOBSUB" => bail!("no vobsub yet"), "S_TEXT/ASS" => { let codec_private = local_track .codec_private .clone() .ok_or(anyhow!("ASS is missing required codec private data"))?; let ass_blocks = tokio::task::spawn_blocking(move || { extract_track(CONF.library_path.clone(), local_track) }) .await??; let webvtt = webvtt_from_ass_blocks( node.public.title.clone().unwrap_or_default(), codec_private, ass_blocks, ) .context("transcoding subtitles")?; tokio::task::spawn(async move { let _ = b.write_all(webvtt.as_bytes()).await; }); } _ => bail!("unknown sub codec"), }; Ok(()) }