fix v_in in custom filter, add audio only mode
This commit is contained in:
parent
f3cd45af3c
commit
537f664c06
@ -57,6 +57,7 @@ processing:
|
||||
With 'custom_filter' it is possible, to apply further filters. The filter outputs
|
||||
should end with [c_v_out] for video filter, and [c_a_out] for audio filter.
|
||||
mode: playlist
|
||||
audio_only: false
|
||||
width: 1024
|
||||
height: 576
|
||||
aspect: 1.778
|
||||
|
@ -23,7 +23,7 @@ pub fn output(config: &PlayoutConfig, log_format: &str) -> process::Child {
|
||||
"ffplayout"
|
||||
];
|
||||
|
||||
if config.text.add_text && !config.text.text_from_filename {
|
||||
if config.text.add_text && !config.text.text_from_filename && !config.processing.audio_only {
|
||||
if let Some(socket) = config.text.zmq_stream_socket.clone() {
|
||||
debug!(
|
||||
"Using drawtext filter, listening on address: <yellow>{}</>",
|
||||
|
@ -35,5 +35,9 @@ pub fn filter_node(filter: &str) -> (String, String) {
|
||||
error!("Custom filter is not well formatted, use correct out link names (\"[c_v_out]\" and/or \"[c_a_out]\"). Filter skipped!")
|
||||
}
|
||||
|
||||
if filter.starts_with("[v_in]") {
|
||||
video_filter = format!("[v_in]{video_filter}");
|
||||
}
|
||||
|
||||
(video_filter, audio_filter)
|
||||
}
|
||||
|
@ -138,7 +138,10 @@ impl Filters {
|
||||
let mut cmd = vec![];
|
||||
|
||||
if !a_chain.is_empty() {
|
||||
f_chain.push(';');
|
||||
if !f_chain.is_empty() {
|
||||
f_chain.push(';');
|
||||
}
|
||||
|
||||
f_chain.push_str(&a_chain);
|
||||
}
|
||||
|
||||
@ -153,7 +156,7 @@ impl Filters {
|
||||
pub fn map(&mut self) -> Vec<String> {
|
||||
let mut o_map = self.output_map.clone();
|
||||
|
||||
if self.video_last == -1 {
|
||||
if self.video_last == -1 && !self.video_chain.is_empty() {
|
||||
let v_map = "0:v".to_string();
|
||||
|
||||
if !o_map.contains(&v_map) {
|
||||
@ -412,9 +415,19 @@ fn aspect_calc(aspect_string: &Option<String>, config: &PlayoutConfig) -> f64 {
|
||||
}
|
||||
|
||||
/// This realtime filter is important for HLS output to stay in sync.
|
||||
fn realtime(node: &mut Media, chain: &mut Filters, config: &PlayoutConfig) {
|
||||
fn realtime(
|
||||
node: &mut Media,
|
||||
chain: &mut Filters,
|
||||
config: &PlayoutConfig,
|
||||
filter_type: FilterType,
|
||||
) {
|
||||
if config.general.generate.is_none() && config.out.mode == HLS {
|
||||
let mut speed_filter = "realtime=speed=1".to_string();
|
||||
let prefix = match filter_type {
|
||||
Audio => "a",
|
||||
Video => "",
|
||||
};
|
||||
|
||||
let mut speed_filter = format!("{prefix}realtime=speed=1");
|
||||
|
||||
if let Some(begin) = &node.begin {
|
||||
let (delta, _) = get_delta(config, begin);
|
||||
@ -424,12 +437,12 @@ fn realtime(node: &mut Media, chain: &mut Filters, config: &PlayoutConfig) {
|
||||
let speed = duration / (duration + delta);
|
||||
|
||||
if speed > 0.0 && speed < 1.1 && delta < config.general.stop_threshold {
|
||||
speed_filter = format!("realtime=speed={speed}");
|
||||
speed_filter = format!("{prefix}realtime=speed={speed}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chain.add_filter(&speed_filter, 0, Video);
|
||||
chain.add_filter(&speed_filter, 0, filter_type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -504,54 +517,62 @@ pub fn filter_chains(
|
||||
let mut filters = Filters::new(config.processing.audio_tracks, 0);
|
||||
|
||||
if node.unit == Encoder {
|
||||
add_text(node, &mut filters, config, filter_chain);
|
||||
if !config.processing.audio_only {
|
||||
add_text(node, &mut filters, config, filter_chain);
|
||||
}
|
||||
|
||||
if let Some(f) = config.out.output_filter.clone() {
|
||||
process_output_filters(config, &mut filters, &f)
|
||||
} else if config.out.output_count > 1 {
|
||||
} else if config.out.output_count > 1 && !config.processing.audio_only {
|
||||
split_filter(&mut filters, config.out.output_count, 0, Video);
|
||||
}
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
if let Some(probe) = node.probe.as_ref() {
|
||||
if Path::new(&node.audio).is_file() {
|
||||
filters.audio_position = 1;
|
||||
if !config.processing.audio_only {
|
||||
if let Some(probe) = node.probe.as_ref() {
|
||||
if Path::new(&node.audio).is_file() {
|
||||
filters.audio_position = 1;
|
||||
}
|
||||
|
||||
if let Some(v_stream) = &probe.video_streams.get(0) {
|
||||
let aspect = aspect_calc(&v_stream.display_aspect_ratio, config);
|
||||
let frame_per_sec = fps_calc(&v_stream.r_frame_rate, 1.0);
|
||||
|
||||
deinterlace(&v_stream.field_order, &mut filters);
|
||||
pad(aspect, &mut filters, v_stream, config);
|
||||
fps(frame_per_sec, &mut filters, config);
|
||||
scale(
|
||||
v_stream.width,
|
||||
v_stream.height,
|
||||
aspect,
|
||||
&mut filters,
|
||||
config,
|
||||
);
|
||||
}
|
||||
|
||||
extend_video(node, &mut filters);
|
||||
} else {
|
||||
fps(0.0, &mut filters, config);
|
||||
scale(None, None, 1.0, &mut filters, config);
|
||||
}
|
||||
|
||||
if let Some(v_stream) = &probe.video_streams.get(0) {
|
||||
let aspect = aspect_calc(&v_stream.display_aspect_ratio, config);
|
||||
let frame_per_sec = fps_calc(&v_stream.r_frame_rate, 1.0);
|
||||
|
||||
deinterlace(&v_stream.field_order, &mut filters);
|
||||
pad(aspect, &mut filters, v_stream, config);
|
||||
fps(frame_per_sec, &mut filters, config);
|
||||
scale(
|
||||
v_stream.width,
|
||||
v_stream.height,
|
||||
aspect,
|
||||
&mut filters,
|
||||
config,
|
||||
);
|
||||
}
|
||||
|
||||
extend_video(node, &mut filters);
|
||||
} else {
|
||||
fps(0.0, &mut filters, config);
|
||||
scale(None, None, 1.0, &mut filters, config);
|
||||
add_text(node, &mut filters, config, filter_chain);
|
||||
fade(node, &mut filters, 0, Video);
|
||||
overlay(node, &mut filters, config);
|
||||
realtime(node, &mut filters, config, Video);
|
||||
}
|
||||
|
||||
add_text(node, &mut filters, config, filter_chain);
|
||||
fade(node, &mut filters, 0, Video);
|
||||
overlay(node, &mut filters, config);
|
||||
realtime(node, &mut filters, config);
|
||||
|
||||
let (proc_vf, proc_af) = custom::filter_node(&config.processing.custom_filter);
|
||||
let (list_vf, list_af) = custom::filter_node(&node.custom_filter);
|
||||
|
||||
custom(&proc_vf, &mut filters, 0, Video);
|
||||
custom(&list_vf, &mut filters, 0, Video);
|
||||
if config.processing.audio_only {
|
||||
realtime(node, &mut filters, config, Audio);
|
||||
} else {
|
||||
custom(&proc_vf, &mut filters, 0, Video);
|
||||
custom(&list_vf, &mut filters, 0, Video);
|
||||
}
|
||||
|
||||
for i in 0..config.processing.audio_tracks {
|
||||
if node
|
||||
|
@ -19,7 +19,7 @@ pub const IMAGE_FORMAT: [&str; 21] = [
|
||||
];
|
||||
|
||||
// Some well known errors can be safely ignore
|
||||
pub const FFMPEG_IGNORE_ERRORS: [&str; 10] = [
|
||||
pub const FFMPEG_IGNORE_ERRORS: [&str; 11] = [
|
||||
"ac-tex damaged",
|
||||
"codec s302m, is muxed as a private data stream",
|
||||
"corrupt decoded frame in stream",
|
||||
@ -30,6 +30,7 @@ pub const FFMPEG_IGNORE_ERRORS: [&str; 10] = [
|
||||
"skipped MB in I-frame at",
|
||||
"Thread message queue blocking",
|
||||
"Warning MVs not available",
|
||||
"frame size not set",
|
||||
];
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
|
||||
@ -156,6 +157,8 @@ pub struct Logging {
|
||||
pub struct Processing {
|
||||
pub help_text: String,
|
||||
pub mode: ProcessMode,
|
||||
#[serde(default)]
|
||||
pub audio_only: bool,
|
||||
pub width: i64,
|
||||
pub height: i64,
|
||||
pub aspect: f64,
|
||||
@ -328,24 +331,30 @@ impl PlayoutConfig {
|
||||
(config.processing.width * config.processing.height / 16) / 2
|
||||
);
|
||||
|
||||
let mut process_cmd = vec_strings![
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
"-r",
|
||||
&config.processing.fps,
|
||||
"-c:v",
|
||||
"mpeg2video",
|
||||
"-g",
|
||||
"1",
|
||||
"-b:v",
|
||||
&bitrate,
|
||||
"-minrate",
|
||||
&bitrate,
|
||||
"-maxrate",
|
||||
&bitrate,
|
||||
"-bufsize",
|
||||
&buff_size
|
||||
];
|
||||
let mut process_cmd = vec_strings![];
|
||||
|
||||
if config.processing.audio_only {
|
||||
process_cmd.append(&mut vec_strings!["-vn"]);
|
||||
} else {
|
||||
process_cmd.append(&mut vec_strings![
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
"-r",
|
||||
&config.processing.fps,
|
||||
"-c:v",
|
||||
"mpeg2video",
|
||||
"-g",
|
||||
"1",
|
||||
"-b:v",
|
||||
&bitrate,
|
||||
"-minrate",
|
||||
&bitrate,
|
||||
"-maxrate",
|
||||
&bitrate,
|
||||
"-bufsize",
|
||||
&buff_size
|
||||
]);
|
||||
}
|
||||
|
||||
process_cmd.append(&mut pre_audio_codec(
|
||||
config.processing.add_loudnorm,
|
||||
|
Loading…
Reference in New Issue
Block a user