diff options
Diffstat (limited to 'server/src/routes')
-rw-r--r-- | server/src/routes/mod.rs | 6 | ||||
-rw-r--r-- | server/src/routes/stream.rs | 43 | ||||
-rw-r--r-- | server/src/routes/ui/player.rs | 16 |
3 files changed, 48 insertions, 17 deletions
diff --git a/server/src/routes/mod.rs b/server/src/routes/mod.rs index 6fe5018..94a7547 100644 --- a/server/src/routes/mod.rs +++ b/server/src/routes/mod.rs @@ -45,10 +45,7 @@ macro_rules! uri { }; } -pub fn build_rocket( - database: Database, - federation: Federation, -) -> Rocket<Build> { +pub fn build_rocket(database: Database, federation: Federation) -> Rocket<Build> { rocket::build() .configure(Config { address: std::env::var("BIND_ADDR") @@ -66,6 +63,7 @@ pub fn build_rocket( }) .as_bytes(), ), + ip_header: Some("x-forwarded-for".into()), ..Default::default() }) .manage(database) diff --git a/server/src/routes/stream.rs b/server/src/routes/stream.rs index c47f589..018fae5 100644 --- a/server/src/routes/stream.rs +++ b/server/src/routes/stream.rs @@ -10,14 +10,29 @@ use jellybase::CONF; use jellycommon::{stream::StreamSpec, MediaSource}; use log::{info, warn}; use rocket::{ - get, - http::{ContentType, Header, Status}, + get, head, + http::{Header, Status}, request::{self, FromRequest}, response::{self, Redirect, Responder}, Either, Request, Response, State, }; use std::{ops::Range, time::Duration}; -use tokio::io::DuplexStream; +use tokio::io::{duplex, DuplexStream}; + +#[head("/n/<_id>/stream?<spec>")] +pub async fn r_stream_head( + _sess: Session, + _id: &str, + spec: StreamSpec, +) -> Result<Either<StreamResponse, Redirect>, MyError> { + let head = jellystream::stream_head(&spec); + Ok(Either::Left(StreamResponse { + stream: duplex(0).0, + advertise_range: head.range_supported, + content_type: head.content_type, + range: None, + })) +} #[get("/n/<id>/stream?<spec>")] pub async fn r_stream( @@ -28,7 +43,10 @@ pub async fn r_stream( range: Option<RequestRange>, spec: StreamSpec, ) -> Result<Either<StreamResponse, Redirect>, MyError> { - let node = db.node.get(&id.to_string())?.ok_or(anyhow!("node does not exist"))?; + let node = db + .node + .get(&id.to_string())? + .ok_or(anyhow!("node does not exist"))?; let source = node .private .source @@ -70,8 +88,15 @@ pub async fn r_stream( None => 0..(isize::MAX as usize), }; + let head = jellystream::stream_head(&spec); + match jellystream::stream(node, spec, urange).await { - Ok(stream) => Ok(Either::Left(StreamResponse { stream, range })), + Ok(stream) => Ok(Either::Left(StreamResponse { + stream, + range, + advertise_range: head.range_supported, + content_type: head.content_type, + })), Err(e) => { warn!("stream error: {e}"); Err(MyError(e)) @@ -81,6 +106,8 @@ pub async fn r_stream( pub struct StreamResponse { stream: DuplexStream, + advertise_range: bool, + content_type: &'static str, range: Option<RequestRange>, } @@ -92,8 +119,10 @@ impl<'r> Responder<'r, 'static> for StreamResponse { b.status(Status::PartialContent); b.header(Header::new("content-range", range.to_cr_hv())); } - b.header(Header::new("accept-ranges", "bytes")) - .header(ContentType::WEBM) + if self.advertise_range { + b.header(Header::new("accept-ranges", "bytes")); + } + b.header(Header::new("content-type", self.content_type)) .streamed_body(self.stream) .ok() } diff --git a/server/src/routes/ui/player.rs b/server/src/routes/ui/player.rs index fa9657f..4a636e6 100644 --- a/server/src/routes/ui/player.rs +++ b/server/src/routes/ui/player.rs @@ -33,13 +33,16 @@ pub struct PlayerConfig { } #[get("/n/<id>/player?<conf..>", rank = 4)] -pub fn r_player( +pub fn r_player<'a>( _sess: Session, - db: &State<Database>, - id: String, + db: &'a State<Database>, + id: &'a str, conf: PlayerConfig, -) -> MyResult<DynLayoutPage<'_>> { - let item = db.node.get(&id)?.ok_or(anyhow!("node does not exist"))?; +) -> MyResult<DynLayoutPage<'a>> { + let item = db + .node + .get(&id.to_string())? + .ok_or(anyhow!("node does not exist"))?; let spec = StreamSpec { tracks: None @@ -48,7 +51,8 @@ pub fn r_player( .chain(conf.a.into_iter()) .chain(conf.s.into_iter()) .collect::<Vec<_>>(), - format: StreamFormat::Webm, + format: StreamFormat::Matroska, + webm: Some(true), ..Default::default() }; |