diff options
Diffstat (limited to 'stream/src/hls.rs')
-rw-r--r-- | stream/src/hls.rs | 72 |
1 files changed, 38 insertions, 34 deletions
diff --git a/stream/src/hls.rs b/stream/src/hls.rs index 27630b2..f06ac72 100644 --- a/stream/src/hls.rs +++ b/stream/src/hls.rs @@ -4,13 +4,10 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ +use crate::{stream_info, SMediaInfo}; use anyhow::{anyhow, Result}; -use jellybase::{ - common::{ - stream::{StreamContainer, StreamSpec}, - LocalTrack, Node, SourceTrackKind, - }, - CONF, +use jellybase::common::stream::{ + FormatNum, SegmentNum, StreamContainer, StreamSpec, TrackKind, TrackNum, }; use std::{fmt::Write, ops::Range, sync::Arc}; use tokio::{ @@ -19,20 +16,24 @@ use tokio::{ }; pub async fn hls_master_stream( - node: Arc<Node>, - _local_tracks: Vec<LocalTrack>, - segment: u64, - container: StreamContainer, mut b: DuplexStream, + info: Arc<SMediaInfo>, + segment: SegmentNum, + container: StreamContainer, ) -> Result<()> { - let media = node.media.as_ref().ok_or(anyhow!("no media"))?; + let (_iinfo, info) = stream_info(info).await?; + let seg = info + .segments + .get(segment) + .ok_or(anyhow!("segment not found"))?; + let mut out = String::new(); writeln!(out, "#EXTM3U")?; writeln!(out, "#EXT-X-VERSION:4")?; // writeln!(out, "#EXT-X-INDEPENDENT-SEGMENTS")?; - for (i, t) in media.tracks.iter().enumerate() { + for (i, t) in seg.tracks.iter().enumerate() { let uri = format!( - "stream?{}", + "stream{}", StreamSpec::HlsVariant { segment, track: i, @@ -42,10 +43,11 @@ pub async fn hls_master_stream( .to_query() ); let r#type = match t.kind { - SourceTrackKind::Video { .. } => "VIDEO", - SourceTrackKind::Audio { .. } => "AUDIO", - SourceTrackKind::Subtitles => "SUBTITLES", + TrackKind::Video => "VIDEO", + TrackKind::Audio => "AUDIO", + TrackKind::Subtitle => "SUBTITLES", }; + // TODO bw writeln!(out, "#EXT-X-STREAM-INF:BANDWIDTH=5000000,TYPE={type}")?; writeln!(out, "{uri}")?; } @@ -54,42 +56,44 @@ pub async fn hls_master_stream( } pub async fn hls_variant_stream( - node: Arc<Node>, - local_tracks: Vec<LocalTrack>, - segment: u64, - track: usize, - format: usize, - container: StreamContainer, mut b: DuplexStream, + info: Arc<SMediaInfo>, + segment: SegmentNum, + track: TrackNum, + format: FormatNum, + container: StreamContainer, ) -> Result<()> { - let local_track = local_tracks.first().ok_or(anyhow!("no track"))?.to_owned(); - let media_info = node.media.to_owned().ok_or(anyhow!("no media?"))?; + let (iinfo, info) = stream_info(info).await?; + let (file_index, track_num) = *iinfo + .track_to_file + .get(track) + .ok_or(anyhow!("track not found"))?; + let seg = info + .segments + .get(segment) + .ok_or(anyhow!("segment not found"))?; + let frags = spawn_blocking(move || { - jellyremuxer::fragment::fragment_index( - &CONF.media_path, - &node, - &local_track, - track as usize, - ) + jellyremuxer::fragment::fragment_index(&iinfo.paths[file_index], track_num) }) .await??; let mut out = String::new(); writeln!(out, "#EXTM3U")?; writeln!(out, "#EXT-X-PLAYLIST-TYPE:VOD")?; - writeln!(out, "#EXT-X-TARGETDURATION:{}", media_info.duration)?; + writeln!(out, "#EXT-X-TARGETDURATION:{}", seg.duration)?; writeln!(out, "#EXT-X-VERSION:4")?; writeln!(out, "#EXT-X-MEDIA-SEQUENCE:0")?; - for (i, Range { start, end }) in frags.iter().enumerate() { + for (index, Range { start, end }) in frags.iter().enumerate() { writeln!(out, "#EXTINF:{:},", end - start)?; writeln!( out, - "stream?{}", + "stream{}", StreamSpec::Fragment { segment, track, - index: i as u64, + index, container, format, } |