set correct fps for logo - fix #198, ignore some harmless ffmpeg errors
This commit is contained in:
parent
69a3e59e35
commit
2ebb4c6822
@ -85,7 +85,7 @@ pub fn json_rpc_server(
|
|||||||
{
|
{
|
||||||
let filter = get_filter_from_json(map["message"].to_string());
|
let filter = get_filter_from_json(map["message"].to_string());
|
||||||
|
|
||||||
// TODO: in Rust 1.64 use let_chains instead
|
// TODO: in Rust 1.65 use let_chains instead
|
||||||
if !filter.is_empty() && config.text.zmq_stream_socket.is_some() {
|
if !filter.is_empty() && config.text.zmq_stream_socket.is_some() {
|
||||||
let mut clips_filter = playout_stat.chain.lock().unwrap();
|
let mut clips_filter = playout_stat.chain.lock().unwrap();
|
||||||
*clips_filter = vec![filter.clone()];
|
*clips_filter = vec![filter.clone()];
|
||||||
|
@ -171,7 +171,7 @@ fn overlay(node: &mut Media, chain: &mut Filters, config: &PlayoutConfig) {
|
|||||||
&& Path::new(&config.processing.logo).is_file()
|
&& Path::new(&config.processing.logo).is_file()
|
||||||
&& &node.category != "advertisement"
|
&& &node.category != "advertisement"
|
||||||
{
|
{
|
||||||
let mut logo_chain = v_overlay::filter_node(config, false);
|
let mut logo_chain = v_overlay::filter_node(config);
|
||||||
|
|
||||||
if node.last_ad.unwrap_or(false) {
|
if node.last_ad.unwrap_or(false) {
|
||||||
logo_chain.push_str(",fade=in:st=0:d=1.0:alpha=1")
|
logo_chain.push_str(",fade=in:st=0:d=1.0:alpha=1")
|
||||||
@ -183,9 +183,6 @@ fn overlay(node: &mut Media, chain: &mut Filters, config: &PlayoutConfig) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
logo_chain
|
|
||||||
.push_str(format!("[l];[v][l]{}:shortest=1", config.processing.logo_filter).as_str());
|
|
||||||
|
|
||||||
chain.add_filter(&logo_chain, Video);
|
chain.add_filter(&logo_chain, Video);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ pub fn filter_node(
|
|||||||
None => config.text.zmq_stream_socket.clone(),
|
None => config.text.zmq_stream_socket.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: in Rust 1.64 use let_chains instead
|
// TODO: in Rust 1.65 use let_chains instead
|
||||||
if config.text.text_from_filename && node.is_some() {
|
if config.text.text_from_filename && node.is_some() {
|
||||||
let source = node
|
let source = node
|
||||||
.unwrap_or(&Media::new(0, String::new(), false))
|
.unwrap_or(&Media::new(0, String::new(), false))
|
||||||
|
@ -3,30 +3,24 @@ use crate::utils::PlayoutConfig;
|
|||||||
/// Overlay Filter
|
/// Overlay Filter
|
||||||
///
|
///
|
||||||
/// When a logo is set, we create here the filter for the server.
|
/// When a logo is set, we create here the filter for the server.
|
||||||
pub fn filter_node(config: &PlayoutConfig, add_tail: bool) -> String {
|
pub fn filter_node(config: &PlayoutConfig) -> String {
|
||||||
let mut logo_chain = String::new();
|
let mut fps = config.processing.fps;
|
||||||
|
let mut fps_filter = String::new();
|
||||||
|
|
||||||
if !config.processing.add_logo {
|
if !config.processing.add_logo {
|
||||||
return logo_chain;
|
return String::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(fps) = config.processing.logo_fps {
|
if let Some(f) = config.processing.logo_fps {
|
||||||
let opacity = format!(
|
fps = f;
|
||||||
"format=rgba,colorchannelmixer=aa={}",
|
|
||||||
config.processing.logo_opacity
|
|
||||||
);
|
|
||||||
let pts = format!("setpts=N/({fps}*TB)");
|
|
||||||
logo_chain = format!(
|
|
||||||
"null[v];movie={}:loop=0,{pts},{opacity}",
|
|
||||||
config.processing.logo
|
|
||||||
);
|
|
||||||
|
|
||||||
if add_tail {
|
|
||||||
logo_chain.push_str(
|
|
||||||
format!("[l];[v][l]{}:shortest=1", config.processing.logo_filter).as_str(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
logo_chain
|
if config.processing.fps != fps {
|
||||||
|
fps_filter = format!(",fps={}", config.processing.fps);
|
||||||
|
}
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"null[v];movie={}:loop=0,setpts=N/({fps}*TB),format=rgba,colorchannelmixer=aa={}{fps_filter}[l];[v][l]{}:shortest=1",
|
||||||
|
config.processing.logo, config.processing.logo_opacity, config.processing.logo_filter
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,13 @@ pub const IMAGE_FORMAT: [&str; 21] = [
|
|||||||
"png", "psd", "ppm", "sgi", "svg", "tga", "tif", "webp",
|
"png", "psd", "ppm", "sgi", "svg", "tga", "tif", "webp",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Some well known errors can be safely ignore
|
||||||
|
pub const FFMPEG_IGNORE_ERRORS: [&str; 3] = [
|
||||||
|
"Referenced QT chapter track not found",
|
||||||
|
"ac-tex damaged",
|
||||||
|
"Warning MVs not available",
|
||||||
|
];
|
||||||
|
|
||||||
/// Global Config
|
/// Global Config
|
||||||
///
|
///
|
||||||
/// This we init ones, when ffplayout is starting and use them globally in the hole program.
|
/// This we init ones, when ffplayout is starting and use them globally in the hole program.
|
||||||
|
@ -92,9 +92,7 @@ impl ProcessControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = self.wait(unit) {
|
self.wait(unit)?;
|
||||||
return Err(e);
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,9 @@ mod logging;
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
mod windows;
|
mod windows;
|
||||||
|
|
||||||
pub use config::{self as playout_config, PlayoutConfig, DUMMY_LEN, IMAGE_FORMAT};
|
pub use config::{
|
||||||
|
self as playout_config, PlayoutConfig, DUMMY_LEN, FFMPEG_IGNORE_ERRORS, IMAGE_FORMAT,
|
||||||
|
};
|
||||||
pub use controller::{PlayerControl, PlayoutStatus, ProcessControl, ProcessUnit::*};
|
pub use controller::{PlayerControl, PlayoutStatus, ProcessControl, ProcessUnit::*};
|
||||||
pub use generator::generate_playlist;
|
pub use generator::generate_playlist;
|
||||||
pub use json_serializer::{read_json, JsonPlaylist};
|
pub use json_serializer::{read_json, JsonPlaylist};
|
||||||
@ -497,14 +499,6 @@ pub fn seek_and_length(node: &Media) -> Vec<String> {
|
|||||||
source_cmd.append(&mut vec_strings!["-ss", node.seek])
|
source_cmd.append(&mut vec_strings!["-ss", node.seek])
|
||||||
}
|
}
|
||||||
|
|
||||||
if file_extension(Path::new(&node.source))
|
|
||||||
.unwrap_or_default()
|
|
||||||
.to_lowercase()
|
|
||||||
== "mp4"
|
|
||||||
{
|
|
||||||
source_cmd.append(&mut vec_strings!["-ignore_chapters", "1"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
source_cmd.append(&mut vec_strings!["-i", node.source.clone()]);
|
source_cmd.append(&mut vec_strings!["-i", node.source.clone()]);
|
||||||
|
|
||||||
if Path::new(&node.audio).is_file() {
|
if Path::new(&node.audio).is_file() {
|
||||||
@ -719,7 +713,9 @@ pub fn stderr_reader(
|
|||||||
"<bright black>[{suffix}]</> {}",
|
"<bright black>[{suffix}]</> {}",
|
||||||
format_log_line(line, "warning")
|
format_log_line(line, "warning")
|
||||||
)
|
)
|
||||||
} else if line.contains("[error]") || line.contains("[fatal]") {
|
} else if (line.contains("[error]") || line.contains("[fatal]"))
|
||||||
|
&& !FFMPEG_IGNORE_ERRORS.iter().any(|i| line.contains(*i))
|
||||||
|
{
|
||||||
error!(
|
error!(
|
||||||
"<bright black>[{suffix}]</> {}",
|
"<bright black>[{suffix}]</> {}",
|
||||||
line.replace("[error]", "").replace("[fatal]", "")
|
line.replace("[error]", "").replace("[fatal]", "")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user