diff --git a/Cargo.lock b/Cargo.lock index 341b5c1f..7e14611c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1826,6 +1826,7 @@ dependencies = [ "thiserror", "tokio", "tokio-stream", + "url", ] [[package]] @@ -1892,9 +1893,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -2609,9 +2610,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -3908,9 +3909,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "phf" @@ -6563,12 +6564,12 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna 0.4.0", + "idna 0.5.0", "percent-encoding", ] diff --git a/rs/packages/db/src/models/media_session/mod.rs b/rs/packages/db/src/models/media_session/mod.rs index f21f7907..d06974d1 100644 --- a/rs/packages/db/src/models/media_session/mod.rs +++ b/rs/packages/db/src/models/media_session/mod.rs @@ -1,3 +1,4 @@ +use crate::deployment::{Deployment, DeploymentState}; use crate::Model; use mongodb::{ bson::{doc, SerializerOptions}, @@ -114,15 +115,14 @@ impl MediaSession { pub async fn get_current_for_station( station_id: &str, ) -> Result, mongodb::error::Error> { - // TODO: improve this - let open_deployment_ids = crate::deployment::Deployment::cl().distinct( - crate::deployment::Deployment::KEY_ID, - doc! { - crate::deployment::Deployment::KEY_STATE: crate::deployment::DeploymentState::KEY_ENUM_VARIANT_ACTIVE - }, - None - ).await?; + let open_deployment_ids = crate::deployment::Deployment::cl() + .distinct( + Deployment::KEY_ID, + doc! { Deployment::KEY_STATE: DeploymentState::KEY_ENUM_VARIANT_ACTIVE }, + None, + ) + .await?; let filter = doc! { MediaSession::KEY_DEPLOYMENT_ID: { "$in": open_deployment_ids }, diff --git a/rs/packages/ffmpeg/Cargo.toml b/rs/packages/ffmpeg/Cargo.toml index 812680e5..74b4d131 100644 --- a/rs/packages/ffmpeg/Cargo.toml +++ b/rs/packages/ffmpeg/Cargo.toml @@ -16,6 +16,7 @@ stream-util = { version = "0.1.0", path = "../stream-util" } thiserror = "1.0.49" tokio = { version = "1.29.0", features = [ "full" ] } tokio-stream = "0.1.11" +url = "2.5.0" [dev-dependencies] async-stream = "0.3.3" diff --git a/rs/packages/ffmpeg/src/lib.rs b/rs/packages/ffmpeg/src/lib.rs index cd447e07..b1c758ba 100644 --- a/rs/packages/ffmpeg/src/lib.rs +++ b/rs/packages/ffmpeg/src/lib.rs @@ -1,5 +1,6 @@ use bytes::Bytes; use log::*; +use std::collections::BTreeMap; use std::fmt::{self, Display, Formatter}; use std::process::{ExitStatus, Stdio}; use stream_util::IntoTryBytesStream; @@ -92,6 +93,28 @@ pub struct FfmpegConfig { pub readrate_initial_burst: f64, pub copycodec: bool, + pub headers: BTreeMap, +} + +pub fn headers_for_url(url: &str) -> BTreeMap { + let mut headers = BTreeMap::::new(); + headers.insert("user-agent".into(), "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36".into()); + headers.insert("origin".into(), url.into()); + headers.insert("referer".into(), url.into()); + // if let Ok(url) = url::Url::parse(url) { + // Ok(url) => headers.insert("origin".into(), url.origin().ascii_serialization()), + // } + + headers.insert( + "sec-ch-ua".into(), + r#""Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24""#.into(), + ); + headers.insert("sec-ch-ua-mobile".into(), "?0".into()); + headers.insert("sec-ch-ua-platform".into(), "Linux".into()); + headers.insert("sec-fetch-dest".into(), "audio".into()); + headers.insert("sec-fetch-mode".into(), "no-cors".into()); + headers.insert("sec-fetch-site".into(), "same-origin".into()); + headers } impl FfmpegConfig { @@ -151,6 +174,7 @@ impl Default for FfmpegConfig { readrate: Self::READRATE, readrate_initial_burst: Self::READRATE_INITIAL_BURST, copycodec: Self::COPYCODEC, + headers: BTreeMap::new(), } } } @@ -185,6 +209,19 @@ impl Ffmpeg { Some(input) => cmd.arg(input), }; + if !self.config.headers.is_empty() { + let v = self + .config + .headers + .iter() + .map(|(k, v)| format!("{}:{}", k, v)) + .collect::>() + .join("\r\n"); + + cmd.arg("-headers"); + cmd.arg(v); + } + // copy codec if self.config.copycodec { cmd.arg("-c:a"); diff --git a/rs/packages/ffmpeg/src/probe.rs b/rs/packages/ffmpeg/src/probe.rs index 64f0b6d7..291e1260 100644 --- a/rs/packages/ffmpeg/src/probe.rs +++ b/rs/packages/ffmpeg/src/probe.rs @@ -3,6 +3,8 @@ use std::process::Stdio; use tokio::io::AsyncReadExt; use tokio::process::Command; +use crate::headers_for_url; + #[derive(Debug, thiserror::Error)] pub enum FfprobeError { #[error("io: {0}")] @@ -24,6 +26,8 @@ pub type Object = Map; pub async fn get(url: &str) -> Result { let mut cmd = Command::new("ffprobe"); + let headers = headers_for_url(url); + cmd.kill_on_drop(true); // verbosity @@ -37,6 +41,15 @@ pub async fn get(url: &str) -> Result { cmd.arg("-print_format"); cmd.arg("json"); + cmd.arg("-headers"); + cmd.arg( + headers + .iter() + .map(|(k, v)| format!("{k}:{v}")) + .collect::>() + .join("\r\n"), + ); + cmd.arg(url); cmd.stdin(Stdio::null()); diff --git a/rs/packages/media/src/handle/external_relay.rs b/rs/packages/media/src/handle/external_relay.rs index 6935cbdf..be99d8b0 100644 --- a/rs/packages/media/src/handle/external_relay.rs +++ b/rs/packages/media/src/handle/external_relay.rs @@ -79,11 +79,14 @@ pub fn run_external_relay_source( ))); let fut = async move { + let headers = ffmpeg::headers_for_url(&url); + let ffmpeg_config = FfmpegConfig { input: Some(url), kbitrate: STREAM_KBITRATE, readrate: true, readrate_initial_burst: STREAM_BURST_LENGTH as f64, + headers, ..FfmpegConfig::default() };