aboutsummaryrefslogtreecommitdiff
path: root/server/src/routes/stream.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/routes/stream.rs')
-rw-r--r--server/src/routes/stream.rs46
1 files changed, 46 insertions, 0 deletions
diff --git a/server/src/routes/stream.rs b/server/src/routes/stream.rs
new file mode 100644
index 0000000..6ff6982
--- /dev/null
+++ b/server/src/routes/stream.rs
@@ -0,0 +1,46 @@
+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/<path..>?<selection>")]
+pub fn r_stream(
+ path: PathBuf,
+ selection: String,
+ state: &State<AppState>,
+) -> 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::<Result<Vec<_>, _>>()?;
+
+ 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)))
+}