diff --git a/Cargo.lock b/Cargo.lock index f672e953..7659f4e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -941,7 +941,7 @@ dependencies = [ [[package]] name = "ffplayout" -version = "0.15.0" +version = "0.15.1" dependencies = [ "chrono", "clap", @@ -990,7 +990,7 @@ dependencies = [ [[package]] name = "ffplayout-lib" -version = "0.15.0" +version = "0.15.1" dependencies = [ "chrono", "crossbeam-channel", diff --git a/ffplayout-engine/Cargo.toml b/ffplayout-engine/Cargo.toml index b7cddfea..5c9826c8 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.15.0" +version = "0.15.1" edition = "2021" [dependencies] diff --git a/lib/Cargo.toml b/lib/Cargo.toml index f406a48b..2f9e38a7 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.15.0" +version = "0.15.1" edition = "2021" [dependencies] diff --git a/lib/src/filter/mod.rs b/lib/src/filter/mod.rs index 03231508..c5d22692 100644 --- a/lib/src/filter/mod.rs +++ b/lib/src/filter/mod.rs @@ -173,11 +173,11 @@ fn overlay(node: &mut Media, chain: &mut Filters, config: &PlayoutConfig) { { let mut logo_chain = v_overlay::filter_node(config, false); - if node.last_ad.unwrap() { + if node.last_ad.unwrap_or(false) { logo_chain.push_str(",fade=in:st=0:d=1.0:alpha=1") } - if node.next_ad.unwrap() { + if node.next_ad.unwrap_or(false) { logo_chain.push_str( format!(",fade=out:st={}:d=1.0:alpha=1", node.out - node.seek - 1.0).as_str(), ) diff --git a/lib/src/utils/json_validate.rs b/lib/src/utils/json_validate.rs index 2eb9930e..aa676e84 100644 --- a/lib/src/utils/json_validate.rs +++ b/lib/src/utils/json_validate.rs @@ -1,11 +1,80 @@ -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, +use std::{ + io::{BufRead, BufReader, Error, ErrorKind}, + process::{Command, Stdio}, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, Mutex, + }, }; use simplelog::*; -use crate::utils::{sec_to_time, valid_source, JsonPlaylist, MediaProbe, PlayoutConfig}; +use crate::utils::{ + format_log_line, sec_to_time, valid_source, vec_strings, Media, JsonPlaylist, PlayoutConfig, +}; + +/// check if ffmpeg can read the file and apply filter to it. +fn check_media(item: Media, begin: f64, config: &PlayoutConfig) -> Result<(), Error> { + let mut clip = item; + clip.add_probe(); + clip.add_filter(config, &Arc::new(Mutex::new(vec![]))); + + let enc_cmd = vec_strings![ + "-hide_banner", + "-nostats", + "-v", + "level+error", + "-ignore_chapters", + "1", + "-i", + clip.source, + "-t", + "0.25", + "-f", + "null", + "-" + ]; + + if clip.probe.and_then(|p| p.format).is_none() { + return Err(Error::new( + ErrorKind::Other, + format!( + "No Metadata at {}, from file \"{}\"", + sec_to_time(begin), + clip.source + ), + )); + } + + let mut enc_proc = match Command::new("ffmpeg") + .args(enc_cmd) + .stderr(Stdio::piped()) + .spawn() + { + Err(e) => return Err(e), + Ok(proc) => proc, + }; + + let enc_err = BufReader::new(enc_proc.stderr.take().unwrap()); + + for line in enc_err.lines() { + let line = line?; + + if line.contains("[error]") { + error!( + "[Validator] {}", + format_log_line(line, "error") + ); + } else if line.contains("[fatal]") { + error!( + "[Validator] {}", + format_log_line(line, "fatal") + ) + } + } + + Ok(()) +} /// Validate a given playlist, to check if: /// @@ -33,15 +102,9 @@ pub fn validate_playlist( } if valid_source(&item.source) { - let probe = MediaProbe::new(&item.source); - - if probe.format.is_none() { - error!( - "No Metadata at {}, from file \"{}\"", - sec_to_time(begin), - item.source - ); - } + if let Err(e) = check_media(item.clone(), begin, &config) { + error!("{e}"); + }; } else { error!( "Source on position {} not exists: \"{}\"",