From d857684dd6358fb5ff979ca09ac78b5649b0f411 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sun, 1 Oct 2023 09:20:39 +0200 Subject: jhls server-side draft --- Cargo.lock | 1 + common/src/jhls.rs | 14 ++++++++++++++ common/src/lib.rs | 1 + remuxer/src/snippet.rs | 15 +++++++++------ stream/Cargo.toml | 1 + stream/src/hls.rs | 4 ++-- stream/src/jhls.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ stream/src/segment.rs | 4 ++-- 8 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 common/src/jhls.rs create mode 100644 stream/src/jhls.rs diff --git a/Cargo.lock b/Cargo.lock index 5147a18..ddcd85e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1451,6 +1451,7 @@ dependencies = [ "jellyremuxer", "jellytranscoder", "log", + "serde_json", "tokio", "tokio-util", ] diff --git a/common/src/jhls.rs b/common/src/jhls.rs new file mode 100644 index 0000000..e2cfa02 --- /dev/null +++ b/common/src/jhls.rs @@ -0,0 +1,14 @@ +use crate::SourceTrack; +use serde::{Deserialize, Serialize}; +use std::ops::Range; + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct JhlsMetadata { + pub tracks: Vec, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct JhlsTrack { + pub info: SourceTrack, + pub segments: Vec>, +} diff --git a/common/src/lib.rs b/common/src/lib.rs index c842924..6403469 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -9,6 +9,7 @@ pub mod r#impl; pub mod seek_index; pub mod stream; pub mod user; +pub mod jhls; #[cfg(feature = "rocket")] use rocket::{FromFormField, UriDisplayQuery}; diff --git a/remuxer/src/snippet.rs b/remuxer/src/snippet.rs index cd965ba..bc7f190 100644 --- a/remuxer/src/snippet.rs +++ b/remuxer/src/snippet.rs @@ -11,13 +11,13 @@ use anyhow::{anyhow, Context, Result}; use jellycommon::{seek_index::SeekIndex, LocalTrack, NodePublic}; use jellymatroska::{read::EbmlReader, write::EbmlWriter, Master, MatroskaTag}; use log::{debug, info}; -use std::{fs::File, io::Write, ops::Range, path::PathBuf}; +use std::{fs::File, io::Write, ops::Range, path::Path}; const SNIPPET_LENGTH: f64 = 2.; pub fn snippet_index( - path_base: PathBuf, - item: NodePublic, + path_base: &Path, + item: &NodePublic, track_sources: &Vec, track: usize, ) -> Result>> { @@ -49,8 +49,8 @@ pub fn snippet_index( pub fn write_snippet_into( writer: impl Write, - path_base: PathBuf, - item: NodePublic, + path_base: &Path, + item: &NodePublic, track_sources: Vec, track: usize, webm: bool, @@ -68,7 +68,10 @@ pub fn write_snippet_into( let private = &track_sources[track]; let source_path = path_base.join(&private.path); let mapped = 1; - info!("\t- {track} {source_path:?} ({} => {mapped})", private.track); + info!( + "\t- {track} {source_path:?} ({} => {mapped})", + private.track + ); info!("\t {}", info); let file = File::open(&source_path).context("opening source file")?; let mut index = File::open(source_path.with_extension(format!("si.{}", private.track))) diff --git a/stream/Cargo.toml b/stream/Cargo.toml index a03a85c..7228384 100644 --- a/stream/Cargo.toml +++ b/stream/Cargo.toml @@ -13,3 +13,4 @@ log = { workspace = true } anyhow = { workspace = true } tokio = { version = "1.32.0", features = ["io-util"] } tokio-util = { version = "0.7.9", features = ["io", "io-util"] } +serde_json = "1.0.107" diff --git a/stream/src/hls.rs b/stream/src/hls.rs index 81d0c8c..c5b7f91 100644 --- a/stream/src/hls.rs +++ b/stream/src/hls.rs @@ -48,8 +48,8 @@ pub async fn hls_variant_stream( ) -> Result<()> { let track = *spec.tracks.get(0).ok_or(anyhow!("no track"))?; let snips = jellyremuxer::snippet::snippet_index( - CONF.library_path.clone(), - node.public.clone(), + &CONF.library_path, + &node.public, &track_sources, track, )?; diff --git a/stream/src/jhls.rs b/stream/src/jhls.rs new file mode 100644 index 0000000..5e15d6f --- /dev/null +++ b/stream/src/jhls.rs @@ -0,0 +1,43 @@ +use anyhow::Result; +use jellybase::CONF; +use jellycommon::{ + jhls::{JhlsMetadata, JhlsTrack}, + stream::StreamSpec, + LocalTrack, Node, +}; +use tokio::io::{AsyncWriteExt, DuplexStream}; + +pub async fn jhls_stream( + node: Node, + track_sources: Vec, + _spec: StreamSpec, + mut b: DuplexStream, +) -> Result<()> { + let tracks = tokio::task::spawn_blocking(move || { + node.public + .media + .as_ref() + .unwrap() + .tracks + .iter() + .enumerate() + .map(|(i, t)| { + let segments = jellyremuxer::snippet::snippet_index( + &CONF.library_path, + &node.public, + &track_sources, + i, + )?; + Ok::<_, anyhow::Error>(JhlsTrack { + info: t.to_owned(), + segments, + }) + }) + .try_collect::>() + }) + .await??; + + let out = serde_json::to_string(&JhlsMetadata { tracks })?; + tokio::spawn(async move { b.write_all(out.as_bytes()).await }); + Ok(()) +} diff --git a/stream/src/segment.rs b/stream/src/segment.rs index 77f1238..78afc4f 100644 --- a/stream/src/segment.rs +++ b/stream/src/segment.rs @@ -27,8 +27,8 @@ pub async fn segment_stream( tokio::task::spawn_blocking(move || { if let Err(err) = jellyremuxer::write_snippet_into( b, - CONF.library_path.clone(), - node.public.clone(), + &CONF.library_path, + &node.public, track_sources, track, spec.webm.unwrap_or(false), -- cgit v1.2.3-70-g09d2