aboutsummaryrefslogtreecommitdiff
path: root/stream/src
diff options
context:
space:
mode:
authortpart <tpart120@proton.me>2023-12-09 11:10:22 +0100
committertpart <tpart120@proton.me>2023-12-09 11:10:22 +0100
commit6d87fe0b3c875ef3c7dd1d811d237e75567f787b (patch)
treea7531389b2a8ad6d8b89d92900b96fcf0e431774 /stream/src
parent5c7e30b15d1e42fa8d65d344dfdef0af73b3b6d4 (diff)
parent1d2ed0a54c21e0ab7dd01b5f3975bb5df12d40ea (diff)
downloadjellything-6d87fe0b3c875ef3c7dd1d811d237e75567f787b.tar
jellything-6d87fe0b3c875ef3c7dd1d811d237e75567f787b.tar.bz2
jellything-6d87fe0b3c875ef3c7dd1d811d237e75567f787b.tar.zst
Merge branch 'master' of codeberg.org:metamuffin/jellything
Diffstat (limited to 'stream/src')
-rw-r--r--stream/src/lib.rs4
-rw-r--r--stream/src/webvtt.rs37
2 files changed, 41 insertions, 0 deletions
diff --git a/stream/src/lib.rs b/stream/src/lib.rs
index e9b9a4b..604e3eb 100644
--- a/stream/src/lib.rs
+++ b/stream/src/lib.rs
@@ -7,6 +7,7 @@
pub mod hls;
pub mod jhls;
pub mod segment;
+pub mod webvtt;
use anyhow::{anyhow, bail, Context, Result};
use hls::{hls_master_stream, hls_variant_stream};
@@ -24,6 +25,7 @@ use tokio::{
io::{duplex, AsyncReadExt, AsyncSeekExt, AsyncWriteExt, DuplexStream},
};
use tokio_util::io::SyncIoBridge;
+use webvtt::webvtt_stream;
pub struct StreamHead {
pub content_type: &'static str,
@@ -38,6 +40,7 @@ pub fn stream_head(spec: &StreamSpec) -> StreamHead {
StreamFormat::Matroska => StreamHead { content_type: webm_or_mkv, range_supported: true },
StreamFormat::HlsMaster | StreamFormat::HlsVariant => StreamHead { content_type: "application/vnd.apple.mpegurl", range_supported: false },
StreamFormat::Jhls => StreamHead { content_type: "application/jellything-jhls+json", range_supported: false },
+ StreamFormat::Webvtt => StreamHead { content_type: "text/vtt", range_supported: false },
StreamFormat::Segment => StreamHead { content_type: webm_or_mkv, range_supported: false },
}
}
@@ -69,6 +72,7 @@ pub async fn stream(
StreamFormat::HlsVariant => hls_variant_stream(node, track_sources, spec, b).await?,
StreamFormat::Jhls => jhls_stream(node, track_sources, spec, b, perms).await?,
StreamFormat::Segment => segment_stream(node, track_sources, spec, b, perms).await?,
+ StreamFormat::Webvtt => webvtt_stream(node, track_sources, spec, b).await?,
}
Ok(a)
diff --git a/stream/src/webvtt.rs b/stream/src/webvtt.rs
new file mode 100644
index 0000000..74a12a5
--- /dev/null
+++ b/stream/src/webvtt.rs
@@ -0,0 +1,37 @@
+use anyhow::{anyhow, 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,
+ track_sources: Vec<LocalTrack>,
+ spec: StreamSpec,
+ mut b: DuplexStream,
+) -> Result<()> {
+ // TODO cache
+
+ let local_track = track_sources
+ .get(*spec.tracks.get(0).ok_or(anyhow!("no track selected"))?)
+ .ok_or(anyhow!("track does not exist"))?
+ .clone();
+
+ 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, codec_private, ass_blocks)
+ .context("transcoding subtitles")?;
+
+ tokio::task::spawn(async move {
+ let _ = b.write_all(webvtt.as_bytes()).await;
+ });
+ Ok(())
+}