use super::ui::error::MyError; use crate::AppState; use anyhow::anyhow; use anyhow::Context; use log::debug; use log::warn; use rocket::{get, http::ContentType, response::stream::ReaderStream, State}; use std::path::PathBuf; use tokio::io::{duplex, DuplexStream}; use tokio_util::io::SyncIoBridge; #[get("/stream/?")] pub fn r_stream( path: PathBuf, selection: String, state: &State, ) -> Result<(ContentType, ReaderStream![DuplexStream]), MyError> { let (a, b) = duplex(1024); let path = path.to_str().unwrap().to_string(); let item = state .library .nested(&path) .context("retrieving library node")? .get_item()?; let remuxer = state.remuxer.clone(); let selection = selection .split(",") .map(|e| e.parse().map_err(|_| anyhow!("invalid number"))) .into_iter() .collect::, _>>()?; let b = SyncIoBridge::new(b); tokio::task::spawn_blocking(move || { if let Err(e) = remuxer.generate_into( b, 0, item.fs_path.parent().unwrap().to_path_buf(), item.data.clone(), selection, ) { warn!("stream stopped: {e}") } }); debug!("starting stream"); Ok((ContentType::WEBM, ReaderStream::one(a))) }