diff options
Diffstat (limited to 'stream')
| -rw-r--r-- | stream/src/fragment.rs | 3 | ||||
| -rw-r--r-- | stream/src/lib.rs | 25 | ||||
| -rw-r--r-- | stream/types/src/lib.rs | 3 | ||||
| -rw-r--r-- | stream/types/src/path.rs | 4 |
4 files changed, 30 insertions, 5 deletions
diff --git a/stream/src/fragment.rs b/stream/src/fragment.rs index c4de91f..0b5f04d 100644 --- a/stream/src/fragment.rs +++ b/stream/src/fragment.rs @@ -106,13 +106,12 @@ pub fn fragment_remux( .cues .get(index) .ok_or(anyhow!("fragment index out of range"))?; - let cluster_offset = start_cue.position; let mut clusters = { let media_file = File::open(media_path)?; let mut media = create_demuxer_autodetect(Box::new(media_file))? .ok_or(anyhow!("media container unknown"))?; - media.seek_cluster(Some(cluster_offset))?; + media.seek_cluster(Some(start_cue.position))?; let mut clusters = Vec::new(); for _ in 0..start_cue.clusters { clusters.push( diff --git a/stream/src/lib.rs b/stream/src/lib.rs index 8827aeb..9171595 100644 --- a/stream/src/lib.rs +++ b/stream/src/lib.rs @@ -12,17 +12,18 @@ pub mod metadata; mod stream_info; mod webvtt; -use anyhow::{Context, Result, anyhow, bail}; +use anyhow::{Context, Result, anyhow}; use fragment::fragment_stream; use fragment_index::fragment_index_stream; use hls::{hls_multivariant_stream, hls_variant_stream}; use jellycache::Cache; +use jellyremuxer::demuxers::create_demuxer_autodetect; use jellystream_types::{StreamSpec, TrackKind}; use serde::{Deserialize, Serialize}; use std::{ collections::BTreeSet, fs::File, - io::{Read, Seek, SeekFrom}, + io::{Cursor, Read, Seek, SeekFrom}, ops::Range, path::PathBuf, sync::Arc, @@ -68,6 +69,7 @@ pub fn stream_head(spec: &StreamSpec) -> StreamHead { FragmentInit { container, .. } => container.mime_type(kind), Fragment { container, .. } => container.mime_type(kind), Remux { container, .. } => container.mime_type(kind), + Attachment { name: _ } => "application/json", // TODO infer from ext }; StreamHead { content_type, @@ -98,7 +100,8 @@ pub fn stream( container, format, } => fragment_stream(info, track, index, format, container), - _ => bail!("todo"), + StreamSpec::Remux { .. } => todo!(), + StreamSpec::Attachment { name } => attachment_stream(info, name), } } @@ -118,3 +121,19 @@ fn original_stream( Ok(Box::new(file.take(range.end - range.start))) } + +fn attachment_stream(info: Arc<SMediaInfo>, name: String) -> Result<Box<dyn Read + Send + Sync>> { + let (iinfo, _info) = stream_info(&info)?; + let (file_index, _) = *iinfo.track_to_file.get(0).ok_or(anyhow!("unknown track"))?; + let file = File::open(&iinfo.paths[file_index]).context("opening source")?; + let mut dm = + create_demuxer_autodetect(Box::new(file))?.ok_or(anyhow!("unknown file format"))?; + let attachments = dm.attachments()?.unwrap_or_default(); + let file = attachments + .files + .iter() + .find(|f| f.name == name) + .ok_or(anyhow!("file not found"))?; + + Ok(Box::new(Cursor::new(file.data.to_owned()))) +} diff --git a/stream/types/src/lib.rs b/stream/types/src/lib.rs index cbf5dcb..d02073d 100644 --- a/stream/types/src/lib.rs +++ b/stream/types/src/lib.rs @@ -49,6 +49,9 @@ pub enum StreamSpec { Original { track: TrackNum, }, + Attachment { + name: String, + }, // Track { // segment: SegmentNum, // track: TrackNum, diff --git a/stream/types/src/path.rs b/stream/types/src/path.rs index 226d6e8..d0b1139 100644 --- a/stream/types/src/path.rs +++ b/stream/types/src/path.rs @@ -14,6 +14,7 @@ impl StreamSpec { StreamSpec::Info => "formats.json".to_string(), StreamSpec::HlsVariant { track, format } => format!("{track}/{format}/variant.m3u8"), StreamSpec::FragmentIndex { track } => format!("{track}/fragindex.json"), + StreamSpec::Attachment { name } => format!("attachment/{name}"), StreamSpec::FragmentInit { track, container, @@ -40,6 +41,9 @@ impl StreamSpec { "stream.mpd" => Ok(Self::Dash), "stream.m3u8" => Ok(Self::HlsMultiVariant), "formats.json" => Ok(Self::Info), + "attachment" => Ok(Self::Attachment { + name: segs.next().ok_or("attachment name expected")?.to_string(), + }), track => { let track = track.parse::<TrackNum>().ok().ok_or("invalid track")?; match *segs.next().ok_or("<track> is a directory")? { |