use anyhow::{anyhow, bail, Result}; use jellybase::CONF; use jellycommon::{ stream::{StreamFormat, StreamSpec}, LocalTrack, MediaSource, Node, }; use std::ops::Range; use tokio::io::{duplex, DuplexStream}; use tokio_util::io::SyncIoBridge; pub async fn stream(node: Node, spec: StreamSpec, range: Range) -> Result { let (a, b) = duplex(4096); let track_sources = match node .private .source .as_ref() .ok_or(anyhow!("node has no media"))? { MediaSource::Local { tracks } => tracks.to_owned(), _ => bail!("node tracks are not local"), }; match spec.format { StreamFormat::Original => todo!(), StreamFormat::Matroska | StreamFormat::Webm => { remux_stream(node, track_sources, spec, range, b).await? } StreamFormat::Hls => todo!(), StreamFormat::Jhls => todo!(), StreamFormat::Segment => todo!(), } Ok(a) } async fn remux_stream( node: Node, track_sources: Vec, spec: StreamSpec, range: Range, b: DuplexStream, ) -> Result<()> { let b = SyncIoBridge::new(b); tokio::task::spawn_blocking(move || { jellyremuxer::remux_stream_into( b, range, CONF.library_path.to_owned(), node.public, track_sources, spec.tracks, spec.format == StreamFormat::Webm, ) }); Ok(()) }