From 2676e755286d117b100d379fce84ec3da6d8ae98 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 29 Jan 2024 13:22:21 +0100 Subject: consistent name for {snippet,segment?,fragment} --- stream/src/fragment.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ stream/src/hls.rs | 8 ++--- stream/src/jhls.rs | 2 +- stream/src/lib.rs | 8 ++--- stream/src/segment.rs | 84 -------------------------------------------------- stream/src/webvtt.rs | 2 +- 6 files changed, 94 insertions(+), 94 deletions(-) create mode 100644 stream/src/fragment.rs delete mode 100644 stream/src/segment.rs (limited to 'stream/src') diff --git a/stream/src/fragment.rs b/stream/src/fragment.rs new file mode 100644 index 0000000..f08114c --- /dev/null +++ b/stream/src/fragment.rs @@ -0,0 +1,84 @@ +/* + 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, Result}; +use jellybase::{permission::PermissionSetExt, CONF}; +use jellycommon::{ + stream::StreamSpec, + user::{PermissionSet, UserPermission}, + LocalTrack, Node, +}; +use jellytranscoder::fragment::transcode; +use log::warn; +use tokio::{fs::File, io::DuplexStream}; +use tokio_util::io::SyncIoBridge; + +pub async fn fragment_stream( + node: Node, + local_tracks: Vec, + spec: StreamSpec, + mut b: DuplexStream, + perms: &PermissionSet, +) -> Result<()> { + if spec.tracks.len() != 1 { + bail!("unsupported number of tracks for segment, must be exactly one"); + } + let track = spec.tracks[0]; + let n = spec.index.ok_or(anyhow!("segment index missing"))?; + + let local_track = local_tracks + .get(0) + .ok_or(anyhow!("track missing"))? + .to_owned(); + + if let Some(profile) = spec.profile { + perms.assert(&UserPermission::Transcode)?; + let location = transcode( + &format!("{track} {n} {:?}", node.private.source), // TODO maybe not use the entire source + CONF.transcoding_profiles + .get(profile) + .ok_or(anyhow!("profile out of range"))?, + move |b| { + tokio::task::spawn_blocking(move || { + if let Err(err) = jellyremuxer::write_fragment_into( + SyncIoBridge::new(b), + &CONF.media_path, + &node.public, + &local_track, + track, + false, + n, + ) { + warn!("segment stream error: {err}"); + } + }); + }, + ) + .await?; + let mut output = File::open(location.abs()).await?; + tokio::task::spawn(async move { + if let Err(err) = tokio::io::copy(&mut output, &mut b).await { + warn!("cannot write stream: {err}") + } + }); + } else { + let b = SyncIoBridge::new(b); + tokio::task::spawn_blocking(move || { + if let Err(err) = jellyremuxer::write_fragment_into( + b, + &CONF.media_path, + &node.public, + &local_track, + track, + spec.webm.unwrap_or(false), + n, + ) { + warn!("segment stream error: {err}"); + } + }); + } + + Ok(()) +} diff --git a/stream/src/hls.rs b/stream/src/hls.rs index 310c6b1..7f69d2c 100644 --- a/stream/src/hls.rs +++ b/stream/src/hls.rs @@ -53,8 +53,8 @@ pub async fn hls_variant_stream( let local_track = local_tracks.get(0).ok_or(anyhow!("no track"))?.to_owned(); let track_index = spec.tracks[0]; let media_info = node.public.media.to_owned().ok_or(anyhow!("no media?"))?; - let snips = spawn_blocking(move || { - jellyremuxer::snippet::snippet_index( + let frags = spawn_blocking(move || { + jellyremuxer::fragment::fragment_index( &CONF.media_path, &node.public, &local_track, @@ -70,8 +70,8 @@ pub async fn hls_variant_stream( writeln!(out, "#EXT-X-VERSION:4")?; writeln!(out, "#EXT-X-MEDIA-SEQUENCE:0")?; - spec.format = StreamFormat::Snippet; - for (i, Range { start, end }) in snips.iter().enumerate() { + spec.format = StreamFormat::Fragment; + for (i, Range { start, end }) in frags.iter().enumerate() { writeln!(out, "#EXTINF:{:},", end - start)?; spec.index = Some(i); writeln!(out, "stream?{}", spec.to_query())?; diff --git a/stream/src/jhls.rs b/stream/src/jhls.rs index e26df1b..1313c7a 100644 --- a/stream/src/jhls.rs +++ b/stream/src/jhls.rs @@ -26,7 +26,7 @@ pub async fn jhls_index( .to_owned(); let segments = tokio::task::spawn_blocking(move || { - jellyremuxer::snippet::snippet_index( + jellyremuxer::fragment::fragment_index( &CONF.media_path, &node.public, &local_track, diff --git a/stream/src/lib.rs b/stream/src/lib.rs index 906e638..4d96f8c 100644 --- a/stream/src/lib.rs +++ b/stream/src/lib.rs @@ -6,7 +6,7 @@ #![feature(iterator_try_collect)] pub mod hls; pub mod jhls; -pub mod segment; +pub mod fragment; pub mod webvtt; use anyhow::{anyhow, bail, Context, Result}; @@ -18,7 +18,7 @@ use jellycommon::{ LocalTrack, Node, TrackSource, }; use jhls::jhls_index; -use segment::segment_stream; +use fragment::fragment_stream; use std::{io::SeekFrom, ops::Range}; use tokio::{ fs::File, @@ -41,7 +41,7 @@ pub fn stream_head(spec: &StreamSpec) -> StreamHead { StreamFormat::HlsMaster | StreamFormat::HlsVariant => StreamHead { content_type: "application/vnd.apple.mpegurl", range_supported: false }, 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::Fragment => StreamHead { content_type: webm_or_mkv, range_supported: false }, StreamFormat::Jvtt => StreamHead { content_type: "application/jellything-vtt+json", range_supported: false }, } } @@ -87,7 +87,7 @@ pub async fn stream( StreamFormat::HlsMaster => hls_master_stream(node, local_tracks, spec, b).await?, 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::Fragment => fragment_stream(node, local_tracks, spec, b, perms).await?, StreamFormat::Webvtt => vtt_stream(false, node, local_tracks, spec, b).await?, StreamFormat::Jvtt => vtt_stream(true, node, local_tracks, spec, b).await?, } diff --git a/stream/src/segment.rs b/stream/src/segment.rs deleted file mode 100644 index a5162cd..0000000 --- a/stream/src/segment.rs +++ /dev/null @@ -1,84 +0,0 @@ -/* - 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, Result}; -use jellybase::{permission::PermissionSetExt, CONF}; -use jellycommon::{ - stream::StreamSpec, - user::{PermissionSet, UserPermission}, - LocalTrack, Node, -}; -use jellytranscoder::snippet::transcode; -use log::warn; -use tokio::{fs::File, io::DuplexStream}; -use tokio_util::io::SyncIoBridge; - -pub async fn segment_stream( - node: Node, - local_tracks: Vec, - spec: StreamSpec, - mut b: DuplexStream, - perms: &PermissionSet, -) -> Result<()> { - if spec.tracks.len() != 1 { - bail!("unsupported number of tracks for segment, must be exactly one"); - } - let track = spec.tracks[0]; - let n = spec.index.ok_or(anyhow!("segment index missing"))?; - - let local_track = local_tracks - .get(0) - .ok_or(anyhow!("track missing"))? - .to_owned(); - - if let Some(profile) = spec.profile { - perms.assert(&UserPermission::Transcode)?; - let location = transcode( - &format!("{track} {n} {:?}", node.private.source), // TODO maybe not use the entire source - CONF.transcoding_profiles - .get(profile) - .ok_or(anyhow!("profile out of range"))?, - move |b| { - tokio::task::spawn_blocking(move || { - if let Err(err) = jellyremuxer::write_snippet_into( - SyncIoBridge::new(b), - &CONF.media_path, - &node.public, - &local_track, - track, - false, - n, - ) { - warn!("segment stream error: {err}"); - } - }); - }, - ) - .await?; - let mut output = File::open(location.abs()).await?; - tokio::task::spawn(async move { - if let Err(err) = tokio::io::copy(&mut output, &mut b).await { - warn!("cannot write stream: {err}") - } - }); - } else { - let b = SyncIoBridge::new(b); - tokio::task::spawn_blocking(move || { - if let Err(err) = jellyremuxer::write_snippet_into( - b, - &CONF.media_path, - &node.public, - &local_track, - track, - spec.webm.unwrap_or(false), - n, - ) { - warn!("segment stream error: {err}"); - } - }); - } - - Ok(()) -} diff --git a/stream/src/webvtt.rs b/stream/src/webvtt.rs index 3c9ec41..ec26398 100644 --- a/stream/src/webvtt.rs +++ b/stream/src/webvtt.rs @@ -19,7 +19,7 @@ pub async fn vtt_stream( ) -> Result<()> { // TODO cache - // TODO should use snippets too? big films take too long... + // TODO should use fragments 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(); -- cgit v1.2.3-70-g09d2