diff --git a/Cargo.lock b/Cargo.lock index c5987b0f..d1becc18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1009,7 +1009,7 @@ dependencies = [ [[package]] name = "ffplayout" -version = "0.10.3" +version = "0.10.4" dependencies = [ "clap", "crossbeam-channel 0.5.5", @@ -1056,7 +1056,7 @@ dependencies = [ [[package]] name = "ffplayout-lib" -version = "0.10.3" +version = "0.10.4" dependencies = [ "chrono 0.4.20-beta.1", "crossbeam-channel 0.5.5", diff --git a/assets/ffpapi.service b/assets/ffpapi.service index a00aff53..b1168fc8 100644 --- a/assets/ffpapi.service +++ b/assets/ffpapi.service @@ -4,7 +4,6 @@ After=network.target remote-fs.target [Service] ExecStart=/usr/bin/ffpapi -l 127.0.0.1:8000 -ExecReload=/bin/kill -1 $MAINPID Restart=always RestartSec=1 User=www-data diff --git a/assets/ffplayout.service b/assets/ffplayout.service index 474d7ee2..f3d63cf0 100644 --- a/assets/ffplayout.service +++ b/assets/ffplayout.service @@ -4,7 +4,6 @@ After=network.target remote-fs.target [Service] ExecStart=/usr/bin/ffplayout -ExecReload=/bin/kill -1 $MAINPID Restart=always RestartSec=1 User=www-data diff --git a/ffplayout-engine/Cargo.toml b/ffplayout-engine/Cargo.toml index 6c34e7fc..204fb8d6 100644 --- a/ffplayout-engine/Cargo.toml +++ b/ffplayout-engine/Cargo.toml @@ -4,7 +4,7 @@ description = "24/7 playout based on rust and ffmpeg" license = "GPL-3.0" authors = ["Jonathan Baecker jonbae77@gmail.com"] readme = "README.md" -version = "0.10.3" +version = "0.10.4" edition = "2021" [dependencies] diff --git a/ffplayout-engine/src/main.rs b/ffplayout-engine/src/main.rs index 9d2b835f..30c8b386 100644 --- a/ffplayout-engine/src/main.rs +++ b/ffplayout-engine/src/main.rs @@ -50,7 +50,7 @@ fn status_file(stat_file: &str, playout_stat: &PlayoutStatus) { let json: String = serde_json::to_string(&data).expect("Serialize status data failed"); if let Err(e) = fs::write(stat_file, &json) { - error!("Unable to write status file: {e}"); + error!("Unable to write to status file {stat_file}: {e}"); }; } else { let stat_file = File::options() @@ -83,7 +83,10 @@ fn main() { let logging = init_logging(&config, Some(proc_ctl1), Some(messages.clone())); CombinedLogger::init(logging).unwrap(); - validate_ffmpeg(&config); + if let Err(e) = validate_ffmpeg(&config) { + error!("{e}"); + exit(1); + }; if config.general.generate.is_some() { // run a simple playlist generator and save them to disk diff --git a/lib/Cargo.toml b/lib/Cargo.toml index f7de474f..13353080 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -4,7 +4,7 @@ description = "Library for ffplayout" license = "GPL-3.0" authors = ["Jonathan Baecker jonbae77@gmail.com"] readme = "README.md" -version = "0.10.3" +version = "0.10.4" edition = "2021" [dependencies] diff --git a/lib/src/utils/mod.rs b/lib/src/utils/mod.rs index fcfa347c..fc5ee454 100644 --- a/lib/src/utils/mod.rs +++ b/lib/src/utils/mod.rs @@ -4,7 +4,7 @@ use std::{ io::{BufRead, BufReader, Error}, net::TcpListener, path::Path, - process::{exit, ChildStderr, Command, Stdio}, + process::{ChildStderr, Command, Stdio}, time::{self, UNIX_EPOCH}, }; @@ -228,7 +228,10 @@ pub fn write_status(config: &PlayoutConfig, date: &str, shift: f64) { let status_data: String = serde_json::to_string(&data).expect("Serialize status data failed"); if let Err(e) = fs::write(&config.general.stat_file, &status_data) { - error!("Unable to write status file: {e:?}") + error!( + "Unable to write to status file {}: {e}", + config.general.stat_file + ) }; } @@ -541,43 +544,37 @@ pub fn stderr_reader(buffer: BufReader, suffix: &str) -> Result<(), } /// Run program to test if it is in system. -fn is_in_system(name: &str) { - if let Ok(mut proc) = Command::new(name) +fn is_in_system(name: &str) -> Result<(), String> { + match Command::new(name) .stderr(Stdio::null()) .stdout(Stdio::null()) .spawn() { - if let Err(e) = proc.wait() { - error!("{e:?}") - }; - } else { - error!("{name} not found on system!"); - exit(0x0100); + Ok(mut proc) => { + if let Err(e) = proc.wait() { + return Err(format!("{e}")); + }; + } + Err(e) => return Err(format!("{name} not found on system! {e}")), } + + Ok(()) } -fn ffmpeg_libs_and_filter() -> (Vec, Vec) { +fn ffmpeg_libs() -> Result, String> { let mut libs: Vec = vec![]; - let mut filters: Vec = vec![]; - - // filter lines which contains filter - let re: Regex = Regex::new(r"^[T.][S.][C.]").unwrap(); let mut ff_proc = match Command::new("ffmpeg") - .arg("-filters") .stderr(Stdio::piped()) - .stdout(Stdio::piped()) .spawn() { Err(e) => { - error!("couldn't spawn ffmpeg process: {}", e); - exit(0x0100); + return Err(format!("couldn't spawn ffmpeg process: {e}")); } Ok(proc) => proc, }; let err_buffer = BufReader::new(ff_proc.stderr.take().unwrap()); - let out_buffer = BufReader::new(ff_proc.stdout.take().unwrap()); // stderr shows only the ffmpeg configuration // get codec library's @@ -594,53 +591,45 @@ fn ffmpeg_libs_and_filter() -> (Vec, Vec) { } } - // stdout shows filter help text - // get filters - for line in out_buffer.lines().flatten() { - if re.captures(line.as_str().trim()).is_some() { - let filter_line = line.split_whitespace(); - - filters.push(filter_line.collect::>()[1].to_string()); - } - } - if let Err(e) = ff_proc.wait() { error!("{:?}", e) }; - (libs, filters) + Ok(libs) } /// Validate ffmpeg/ffprobe/ffplay. /// -/// Check if they are in system and has all filters and codecs we need. -pub fn validate_ffmpeg(config: &PlayoutConfig) { - is_in_system("ffmpeg"); - is_in_system("ffprobe"); +/// Check if they are in system and has all libs and codecs we need. +pub fn validate_ffmpeg(config: &PlayoutConfig) -> Result<(), String> { + is_in_system("ffmpeg")?; + is_in_system("ffprobe")?; if config.out.mode == "desktop" { - is_in_system("ffplay"); + is_in_system("ffplay")?; } - let (libs, filters) = ffmpeg_libs_and_filter(); + let libs = ffmpeg_libs()?; if !libs.contains(&"libx264".to_string()) { - error!("ffmpeg contains no libx264!"); - exit(0x0100); + return Err("ffmpeg contains no libx264!".to_string()); + } + + if config.text.add_text + && !config.text.text_from_filename + && !libs.contains(&"libzmq".to_string()) + { + return Err( + "ffmpeg contains no libzmq! Disable add_text in config or compile ffmpeg with libzmq." + .to_string(), + ); } if !libs.contains(&"libfdk-aac".to_string()) { warn!("ffmpeg contains no libfdk-aac! Can't use high quality aac encoder..."); } - if !filters.contains(&"tpad".to_string()) { - error!("ffmpeg contains no tpad filter!"); - exit(0x0100); - } - - if !filters.contains(&"zmq".to_string()) { - warn!("ffmpeg contains no zmq filter! Text messages will not work..."); - } + Ok(()) } /// get a free tcp socket