Skip to content

Commit

Permalink
feat: simulate ffmpeg and ffprobe headers (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramiroaisen authored Dec 23, 2023
2 parents 840e8e7 + 7797467 commit b4ef34d
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 17 deletions.
19 changes: 10 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions rs/packages/db/src/models/media_session/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::deployment::{Deployment, DeploymentState};
use crate::Model;
use mongodb::{
bson::{doc, SerializerOptions},
Expand Down Expand Up @@ -114,15 +115,14 @@ impl MediaSession {
pub async fn get_current_for_station(
station_id: &str,
) -> Result<Option<MediaSession>, 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 },
Expand Down
1 change: 1 addition & 0 deletions rs/packages/ffmpeg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
37 changes: 37 additions & 0 deletions rs/packages/ffmpeg/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -92,6 +93,28 @@ pub struct FfmpegConfig {
pub readrate_initial_burst: f64,

pub copycodec: bool,
pub headers: BTreeMap<String, String>,
}

pub fn headers_for_url(url: &str) -> BTreeMap<String, String> {
let mut headers = BTreeMap::<String, String>::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 {
Expand Down Expand Up @@ -151,6 +174,7 @@ impl Default for FfmpegConfig {
readrate: Self::READRATE,
readrate_initial_burst: Self::READRATE_INITIAL_BURST,
copycodec: Self::COPYCODEC,
headers: BTreeMap::new(),
}
}
}
Expand Down Expand Up @@ -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::<Vec<_>>()
.join("\r\n");

cmd.arg("-headers");
cmd.arg(v);
}

// copy codec
if self.config.copycodec {
cmd.arg("-c:a");
Expand Down
13 changes: 13 additions & 0 deletions rs/packages/ffmpeg/src/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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}")]
Expand All @@ -24,6 +26,8 @@ pub type Object = Map<String, Value>;
pub async fn get(url: &str) -> Result<Object, FfprobeError> {
let mut cmd = Command::new("ffprobe");

let headers = headers_for_url(url);

cmd.kill_on_drop(true);

// verbosity
Expand All @@ -37,6 +41,15 @@ pub async fn get(url: &str) -> Result<Object, FfprobeError> {
cmd.arg("-print_format");
cmd.arg("json");

cmd.arg("-headers");
cmd.arg(
headers
.iter()
.map(|(k, v)| format!("{k}:{v}"))
.collect::<Vec<String>>()
.join("\r\n"),
);

cmd.arg(url);

cmd.stdin(Stdio::null());
Expand Down
3 changes: 3 additions & 0 deletions rs/packages/media/src/handle/external_relay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
};

Expand Down

0 comments on commit b4ef34d

Please sign in to comment.