From 958c5ecfd1ffbb43425c3737dc3eb1ea50fc92f6 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 10 Mar 2026 21:51:02 +0100 Subject: attachment stream --- stream/src/lib.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'stream/src/lib.rs') 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, name: String) -> Result> { + 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()))) +} -- cgit v1.3