diff options
Diffstat (limited to 'stream')
-rw-r--r-- | stream/src/hls.rs | 5 | ||||
-rw-r--r-- | stream/src/jhls.rs | 9 | ||||
-rw-r--r-- | stream/src/lib.rs | 6 | ||||
-rw-r--r-- | stream/src/webvtt.rs | 46 |
4 files changed, 46 insertions, 20 deletions
diff --git a/stream/src/hls.rs b/stream/src/hls.rs index c036e98..4f83577 100644 --- a/stream/src/hls.rs +++ b/stream/src/hls.rs @@ -49,11 +49,14 @@ pub async fn hls_variant_stream( mut spec: StreamSpec, mut b: DuplexStream, ) -> Result<()> { + let local_track = local_tracks.get(0).ok_or(anyhow!("no track"))?.to_owned(); + let track_index = spec.tracks[0]; let snips = spawn_blocking(move || { jellyremuxer::snippet::snippet_index( &CONF.media_path, &node.public, - local_tracks.get(0).ok_or(anyhow!("no track"))?, + &local_track, + track_index, ) }) .await??; diff --git a/stream/src/jhls.rs b/stream/src/jhls.rs index d5bb575..e26df1b 100644 --- a/stream/src/jhls.rs +++ b/stream/src/jhls.rs @@ -16,7 +16,7 @@ use tokio::io::{AsyncWriteExt, DuplexStream}; pub async fn jhls_index( node: Node, local_tracks: &[LocalTrack], - _spec: StreamSpec, + spec: StreamSpec, mut b: DuplexStream, perms: &PermissionSet, ) -> Result<()> { @@ -26,7 +26,12 @@ pub async fn jhls_index( .to_owned(); let segments = tokio::task::spawn_blocking(move || { - jellyremuxer::snippet::snippet_index(&CONF.media_path, &node.public, &local_track) + jellyremuxer::snippet::snippet_index( + &CONF.media_path, + &node.public, + &local_track, + spec.tracks[0], + ) }) .await??; diff --git a/stream/src/lib.rs b/stream/src/lib.rs index ee47857..833af3e 100644 --- a/stream/src/lib.rs +++ b/stream/src/lib.rs @@ -25,7 +25,7 @@ use tokio::{ io::{duplex, AsyncReadExt, AsyncSeekExt, AsyncWriteExt, DuplexStream}, }; use tokio_util::io::SyncIoBridge; -use webvtt::webvtt_stream; +use webvtt::vtt_stream; pub struct StreamHead { pub content_type: &'static str, @@ -42,6 +42,7 @@ pub fn stream_head(spec: &StreamSpec) -> StreamHead { StreamFormat::JhlsIndex => StreamHead { content_type: "application/jellything-seekindex+json", range_supported: false }, StreamFormat::Webvtt => StreamHead { content_type: "text/vtt", range_supported: false }, StreamFormat::Snippet => StreamHead { content_type: webm_or_mkv, range_supported: false }, + StreamFormat::Jvtt => StreamHead { content_type: "applcation/jellything-vtt+json", range_supported: false }, } } @@ -87,7 +88,8 @@ pub async fn stream( StreamFormat::HlsVariant => hls_variant_stream(node, local_tracks, spec, b).await?, StreamFormat::JhlsIndex => jhls_index(node, &local_tracks, spec, b, perms).await?, StreamFormat::Snippet => segment_stream(node, local_tracks, spec, b, perms).await?, - StreamFormat::Webvtt => webvtt_stream(node, local_tracks, spec, b).await?, + StreamFormat::Webvtt => vtt_stream(false, node, local_tracks, spec, b).await?, + StreamFormat::Jvtt => vtt_stream(true, node, local_tracks, spec, b).await?, } Ok(a) diff --git a/stream/src/webvtt.rs b/stream/src/webvtt.rs index 48cf8d5..2de9835 100644 --- a/stream/src/webvtt.rs +++ b/stream/src/webvtt.rs @@ -5,12 +5,13 @@ */ use anyhow::{anyhow, bail, Context, Result}; use jellybase::CONF; -use jellycommon::{stream::StreamSpec, LocalTrack, Node}; +use jellycommon::{jhls::SubtitleCue, stream::StreamSpec, LocalTrack, Node}; use jellyremuxer::extract::extract_track; -use jellytranscoder::subtitles::webvtt_from_ass_blocks; +use jellytranscoder::subtitles::{parse_ass_blocks, parse_webvtt_blocks, write_webvtt}; use tokio::io::{AsyncWriteExt, DuplexStream}; -pub async fn webvtt_stream( +pub async fn vtt_stream( + json: bool, node: Node, local_tracks: Vec<LocalTrack>, spec: StreamSpec, @@ -24,7 +25,29 @@ pub async fn webvtt_stream( let local_track = local_tracks.get(0).ok_or(anyhow!("no tracks"))?.clone(); let track = &node.public.media.unwrap().tracks[tracki]; + let write = |blocks: Vec<SubtitleCue>| -> anyhow::Result<()> { + let output = if json { + serde_json::to_string(&blocks)? + } else { + write_webvtt(node.public.title.clone().unwrap_or_default(), blocks) + .context("writing webvtt")? + }; + tokio::task::spawn(async move { + let _ = b.write_all(output.as_bytes()).await; + }); + Ok(()) + }; + match track.codec.as_str() { + "D_WEBVTT/SUBTITLES" => { + let webvtt_blocks = tokio::task::spawn_blocking(move || { + extract_track(CONF.media_path.clone(), local_track) + }) + .await??; + + let subtitles = parse_webvtt_blocks(webvtt_blocks).context("parsing subtitles")?; + write(subtitles)?; + } "S_TEXT/UTF8" => bail!("no subrip yet"), "S_VOBSUB" => bail!("no vobsub yet"), "S_TEXT/ASS" => { @@ -34,23 +57,16 @@ pub async fn webvtt_stream( .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) + extract_track(CONF.media_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; - }); + let subtitles = + parse_ass_blocks(codec_private, ass_blocks).context("parsing subtitles")?; + write(subtitles)?; } - _ => bail!("unknown sub codec"), + x => bail!("unknown sub codec {x:?}"), }; Ok(()) } |