From 9912405e4e976b99be9d174fa9cc54700984d5a9 Mon Sep 17 00:00:00 2001 From: jb-alvarado Date: Mon, 18 Dec 2023 21:28:35 +0100 Subject: [PATCH] improve live sources, fix #473 Live sources are potentially unstable and are therefore not officially supported. Use at your own risk. --- ffplayout-api/src/main.rs | 2 +- ffplayout-engine/src/input/playlist.rs | 2 +- lib/src/utils/json_validate.rs | 2 +- lib/src/utils/mod.rs | 19 +++++++++++++------ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ffplayout-api/src/main.rs b/ffplayout-api/src/main.rs index 68bdd4ad..eb559d10 100644 --- a/ffplayout-api/src/main.rs +++ b/ffplayout-api/src/main.rs @@ -89,7 +89,7 @@ async fn main() -> std::io::Result<()> { let port = ip_port[1].parse::().unwrap(); let engine_process = web::Data::new(ProcessControl::new()); - info!("running ffplayout API, listen on {conn}"); + info!("running ffplayout API, listen on http://{conn}"); // no 'allow origin' here, give it to the reverse proxy HttpServer::new(move || { diff --git a/ffplayout-engine/src/input/playlist.rs b/ffplayout-engine/src/input/playlist.rs index 1a5a58ba..f9ae57ea 100644 --- a/ffplayout-engine/src/input/playlist.rs +++ b/ffplayout-engine/src/input/playlist.rs @@ -618,7 +618,7 @@ pub fn gen_source( { node.cmd = Some(loop_image(&node)); } else { - node.cmd = Some(seek_and_length(&node)); + node.cmd = Some(seek_and_length(&mut node)); } } else { trace!( diff --git a/lib/src/utils/json_validate.rs b/lib/src/utils/json_validate.rs index 8a45ed58..4246aceb 100644 --- a/lib/src/utils/json_validate.rs +++ b/lib/src/utils/json_validate.rs @@ -58,7 +58,7 @@ fn check_media( { node.cmd = Some(loop_image(&node)); } else { - node.cmd = Some(seek_and_length(&node)); + node.cmd = Some(seek_and_length(&mut node)); } node.add_filter(&config, &None); diff --git a/lib/src/utils/mod.rs b/lib/src/utils/mod.rs index 6497456b..87cc5775 100644 --- a/lib/src/utils/mod.rs +++ b/lib/src/utils/mod.rs @@ -273,7 +273,8 @@ impl MediaProbe { }) } Err(e) => { - if !Path::new(input).is_file() { + println!("{e}"); + if !Path::new(input).is_file() && !is_remote(input) { Err(ProcError::Custom(format!("File '{input}' not exist!"))) } else { Err(ProcError::Ffprobe(e)) @@ -521,18 +522,22 @@ pub fn loop_filler(node: &Media) -> Vec { } /// Set clip seek in and length value. -pub fn seek_and_length(node: &Media) -> Vec { +pub fn seek_and_length(node: &mut Media) -> Vec { let mut source_cmd = vec![]; let mut cut_audio = false; let mut loop_audio = false; + let remote_source = is_remote(&node.source); - if node.seek > 0.5 { + if remote_source && node.probe.clone().and_then(|f| f.format.duration).is_none() { + node.out -= node.seek; + node.seek = 0.0; + } else if node.seek > 0.5 { source_cmd.append(&mut vec_strings!["-ss", node.seek]) } source_cmd.append(&mut vec_strings!["-i", node.source.clone()]); - if node.duration > node.out { + if node.duration > node.out || remote_source { source_cmd.append(&mut vec_strings!["-t", node.out - node.seek]); } @@ -550,7 +555,7 @@ pub fn seek_and_length(node: &Media) -> Vec { source_cmd.append(&mut vec_strings!["-i", node.audio.clone()]); - if cut_audio || loop_audio { + if cut_audio || loop_audio || remote_source { source_cmd.append(&mut vec_strings!["-t", node.out - node.seek]); } } @@ -601,7 +606,9 @@ pub fn gen_dummy(config: &PlayoutConfig, duration: f64) -> (String, Vec) // } pub fn is_remote(path: &str) -> bool { - Regex::new(r"^https?://.*").unwrap().is_match(path) + Regex::new(r"^(https?|rtmps?|rtp|rtsp|udp|tcp|srt)://.*") + .unwrap() + .is_match(&path.to_lowercase()) } /// Check if file can include or has to exclude.