add missing advanced filter, cleanup, add aevalsrc
This commit is contained in:
parent
bc56aaf9d2
commit
419d3c293f
@ -20,6 +20,7 @@ decoder:
|
|||||||
tpad: # tpad=stop_mode=add:stop_duration={}
|
tpad: # tpad=stop_mode=add:stop_duration={}
|
||||||
drawtext_from_file: # drawtext=text='{}':{}{}
|
drawtext_from_file: # drawtext=text='{}':{}{}
|
||||||
drawtext_from_zmq: # zmq=b=tcp\\\\://'{}',drawtext@dyntext={}
|
drawtext_from_zmq: # zmq=b=tcp\\\\://'{}',drawtext@dyntext={}
|
||||||
|
aevalsrc: # aevalsrc=0:channel_layout=stereo:duration={}:sample_rate=48000
|
||||||
apad: # apad=whole_dur={}
|
apad: # apad=whole_dur={}
|
||||||
volume: # volume={}
|
volume: # volume={}
|
||||||
split: # split={}{}
|
split: # split={}{}
|
||||||
|
@ -184,11 +184,14 @@ impl Default for Filters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deinterlace(field_order: &Option<String>, chain: &mut Filters) {
|
fn deinterlace(field_order: &Option<String>, chain: &mut Filters) {
|
||||||
if let Some(deinterlace) = &ADVANCED_CONFIG.decoder.filters.deinterlace {
|
if let Some(order) = field_order {
|
||||||
chain.add_filter(&deinterlace, 0, Video)
|
|
||||||
} else if let Some(order) = field_order {
|
|
||||||
if order != "progressive" {
|
if order != "progressive" {
|
||||||
chain.add_filter("yadif=0:-1:0", 0, Video)
|
let deinterlace = match &ADVANCED_CONFIG.decoder.filters.deinterlace {
|
||||||
|
Some(deinterlace) => deinterlace.clone(),
|
||||||
|
None => "yadif=0:-1:0".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
chain.add_filter(&deinterlace, 0, Video);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,54 +202,45 @@ fn pad(aspect: f64, chain: &mut Filters, v_stream: &ffprobe::Stream, config: &Pl
|
|||||||
|
|
||||||
if let (Some(w), Some(h)) = (v_stream.width, v_stream.height) {
|
if let (Some(w), Some(h)) = (v_stream.width, v_stream.height) {
|
||||||
if w > config.processing.width && aspect > config.processing.aspect {
|
if w > config.processing.width && aspect > config.processing.aspect {
|
||||||
match &ADVANCED_CONFIG.decoder.filters.pad_scale_w {
|
scale = match &ADVANCED_CONFIG.decoder.filters.pad_scale_w {
|
||||||
Some(pad_scale_w) => {
|
Some(pad_scale_w) => custom_format(pad_scale_w, &[&config.processing.width]),
|
||||||
scale = custom_format(pad_scale_w, &[&config.processing.width])
|
None => format!("scale={}:-1,", config.processing.width),
|
||||||
}
|
|
||||||
None => scale = format!("scale={}:-1,", config.processing.width),
|
|
||||||
};
|
};
|
||||||
} else if h > config.processing.height && aspect < config.processing.aspect {
|
} else if h > config.processing.height && aspect < config.processing.aspect {
|
||||||
match &ADVANCED_CONFIG.decoder.filters.pad_scale_h {
|
scale = match &ADVANCED_CONFIG.decoder.filters.pad_scale_h {
|
||||||
Some(pad_scale_h) => {
|
Some(pad_scale_h) => custom_format(pad_scale_h, &[&config.processing.width]),
|
||||||
scale = custom_format(pad_scale_h, &[&config.processing.width])
|
None => format!("scale=-1:{},", config.processing.height),
|
||||||
}
|
|
||||||
None => scale = format!("scale=-1:{},", config.processing.height),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(pad_video) = &ADVANCED_CONFIG.decoder.filters.pad_video {
|
let pad = match &ADVANCED_CONFIG.decoder.filters.pad_video {
|
||||||
chain.add_filter(
|
Some(pad_video) => custom_format(
|
||||||
&custom_format(
|
pad_video,
|
||||||
pad_video,
|
&[
|
||||||
&[
|
&scale,
|
||||||
&scale,
|
&config.processing.width.to_string(),
|
||||||
&config.processing.width.to_string(),
|
&config.processing.height.to_string(),
|
||||||
&config.processing.height.to_string(),
|
],
|
||||||
],
|
),
|
||||||
),
|
None => format!(
|
||||||
0,
|
"{}pad=max(iw\\,ih*({1}/{2})):ow/({1}/{2}):(ow-iw)/2:(oh-ih)/2",
|
||||||
Video,
|
scale, config.processing.width, config.processing.height
|
||||||
)
|
),
|
||||||
} else {
|
};
|
||||||
chain.add_filter(
|
|
||||||
&format!(
|
chain.add_filter(&pad, 0, Video)
|
||||||
"{}pad=max(iw\\,ih*({1}/{2})):ow/({1}/{2}):(ow-iw)/2:(oh-ih)/2",
|
|
||||||
scale, config.processing.width, config.processing.height
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
Video,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fps(fps: f64, chain: &mut Filters, config: &PlayoutConfig) {
|
fn fps(fps: f64, chain: &mut Filters, config: &PlayoutConfig) {
|
||||||
if fps != config.processing.fps {
|
if fps != config.processing.fps {
|
||||||
match &ADVANCED_CONFIG.decoder.filters.fps {
|
let fps_filter = match &ADVANCED_CONFIG.decoder.filters.fps {
|
||||||
Some(fps) => chain.add_filter(&custom_format(fps, &[&config.processing.fps]), 0, Video),
|
Some(fps) => custom_format(fps, &[&config.processing.fps]),
|
||||||
None => chain.add_filter(&format!("fps={}", config.processing.fps), 0, Video),
|
None => format!("fps={}", config.processing.fps),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
chain.add_filter(&fps_filter, 0, Video)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,77 +254,49 @@ fn scale(
|
|||||||
// width: i64, height: i64
|
// width: i64, height: i64
|
||||||
if let (Some(w), Some(h)) = (width, height) {
|
if let (Some(w), Some(h)) = (width, height) {
|
||||||
if w != config.processing.width || h != config.processing.height {
|
if w != config.processing.width || h != config.processing.height {
|
||||||
match &ADVANCED_CONFIG.decoder.filters.scale {
|
let scale = match &ADVANCED_CONFIG.decoder.filters.scale {
|
||||||
Some(scale) => chain.add_filter(
|
Some(scale) => custom_format(
|
||||||
&custom_format(
|
scale,
|
||||||
scale,
|
&[&config.processing.width, &config.processing.height],
|
||||||
&[&config.processing.width, &config.processing.height],
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
Video,
|
|
||||||
),
|
),
|
||||||
None => {
|
None => format!(
|
||||||
chain.add_filter(
|
"scale={}:{}",
|
||||||
&format!(
|
config.processing.width, config.processing.height
|
||||||
"scale={}:{}",
|
),
|
||||||
config.processing.width, config.processing.height
|
};
|
||||||
),
|
|
||||||
0,
|
chain.add_filter(&scale, 0, Video);
|
||||||
Video,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
chain.add_filter("null", 0, Video);
|
chain.add_filter("null", 0, Video);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !is_close(aspect, config.processing.aspect, 0.03) {
|
if !is_close(aspect, config.processing.aspect, 0.03) {
|
||||||
match &ADVANCED_CONFIG.decoder.filters.set_dar {
|
let dar = match &ADVANCED_CONFIG.decoder.filters.set_dar {
|
||||||
Some(set_dar) => chain.add_filter(
|
Some(set_dar) => custom_format(set_dar, &[&config.processing.aspect]),
|
||||||
&custom_format(set_dar, &[&config.processing.aspect]),
|
None => format!("setdar=dar={}", config.processing.aspect),
|
||||||
0,
|
};
|
||||||
Video,
|
|
||||||
),
|
chain.add_filter(&dar, 0, Video);
|
||||||
None => chain.add_filter(
|
|
||||||
&format!("setdar=dar={}", config.processing.aspect),
|
|
||||||
0,
|
|
||||||
Video,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match &ADVANCED_CONFIG.decoder.filters.scale {
|
let scale = match &ADVANCED_CONFIG.decoder.filters.scale {
|
||||||
Some(scale) => chain.add_filter(
|
Some(scale) => custom_format(
|
||||||
&custom_format(
|
scale,
|
||||||
scale,
|
&[&config.processing.width, &config.processing.height],
|
||||||
&[&config.processing.width, &config.processing.height],
|
),
|
||||||
),
|
None => format!(
|
||||||
0,
|
"scale={}:{}",
|
||||||
Video,
|
config.processing.width, config.processing.height
|
||||||
),
|
),
|
||||||
None => {
|
|
||||||
chain.add_filter(
|
|
||||||
&format!(
|
|
||||||
"scale={}:{}",
|
|
||||||
config.processing.width, config.processing.height
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
Video,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
match &ADVANCED_CONFIG.decoder.filters.set_dar {
|
chain.add_filter(&scale, 0, Video);
|
||||||
Some(set_dar) => chain.add_filter(
|
|
||||||
&custom_format(set_dar, &[&config.processing.aspect]),
|
let dar = match &ADVANCED_CONFIG.decoder.filters.set_dar {
|
||||||
0,
|
Some(set_dar) => custom_format(set_dar, &[&config.processing.aspect]),
|
||||||
Video,
|
None => format!("setdar=dar={}", config.processing.aspect),
|
||||||
),
|
};
|
||||||
None => chain.add_filter(
|
|
||||||
&format!("setdar=dar={}", config.processing.aspect),
|
chain.add_filter(&dar, 0, Video);
|
||||||
0,
|
|
||||||
Video,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,25 +313,21 @@ fn fade(node: &mut Media, chain: &mut Filters, nr: i32, filter_type: FilterType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if node.seek > 0.0 || node.unit == Ingest {
|
if node.seek > 0.0 || node.unit == Ingest {
|
||||||
match &ADVANCED_CONFIG.decoder.filters.fade_in {
|
let fade_in = match &ADVANCED_CONFIG.decoder.filters.fade_in {
|
||||||
Some(fade_in) => chain.add_filter(&custom_format(fade_in, &[t]), 0, Video),
|
Some(fade) => custom_format(fade, &[t]),
|
||||||
None => chain.add_filter(&format!("{t}fade=in:st=0:d=0.5"), nr, filter_type),
|
None => format!("{t}fade=in:st=0:d=0.5"),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
chain.add_filter(&fade_in, nr, filter_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.out != node.duration && node.out - node.seek > 1.0) || fade_audio {
|
if (node.out != node.duration && node.out - node.seek > 1.0) || fade_audio {
|
||||||
match &ADVANCED_CONFIG.decoder.filters.fade_out {
|
let fade_out = match &ADVANCED_CONFIG.decoder.filters.fade_out {
|
||||||
Some(fade_out) => chain.add_filter(
|
Some(fade) => custom_format(fade, &[t, &(node.out - node.seek - 1.0).to_string()]),
|
||||||
&custom_format(fade_out, &[t, &(node.out - node.seek - 1.0).to_string()]),
|
None => format!("{t}fade=out:st={}:d=1.0", (node.out - node.seek - 1.0)),
|
||||||
0,
|
};
|
||||||
Video,
|
|
||||||
),
|
chain.add_filter(&fade_out, nr, filter_type);
|
||||||
None => chain.add_filter(
|
|
||||||
&format!("{t}fade=out:st={}:d=1.0", (node.out - node.seek - 1.0)),
|
|
||||||
nr,
|
|
||||||
filter_type,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,11 +339,9 @@ fn overlay(node: &mut Media, chain: &mut Filters, config: &PlayoutConfig) {
|
|||||||
let mut scale = String::new();
|
let mut scale = String::new();
|
||||||
|
|
||||||
if !config.processing.logo_scale.is_empty() {
|
if !config.processing.logo_scale.is_empty() {
|
||||||
match &ADVANCED_CONFIG.decoder.filters.overlay_logo_scale {
|
scale = match &ADVANCED_CONFIG.decoder.filters.overlay_logo_scale {
|
||||||
Some(logo_scale) => {
|
Some(logo_scale) => custom_format(logo_scale, &[&config.processing.logo_scale]),
|
||||||
scale = custom_format(logo_scale, &[&config.processing.logo_scale])
|
None => format!(",scale={}", config.processing.logo_scale),
|
||||||
}
|
|
||||||
None => scale = format!(",scale={}", config.processing.logo_scale),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,10 +416,14 @@ fn add_text(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_audio(node: &Media, chain: &mut Filters, nr: i32) {
|
fn add_audio(node: &Media, chain: &mut Filters, nr: i32) {
|
||||||
let audio = format!(
|
let audio = match &ADVANCED_CONFIG.decoder.filters.aevalsrc {
|
||||||
"aevalsrc=0:channel_layout=stereo:duration={}:sample_rate=48000",
|
Some(aevalsrc) => custom_format(aevalsrc, &[node.out - node.seek]),
|
||||||
node.out - node.seek
|
None => format!(
|
||||||
);
|
"aevalsrc=0:channel_layout=stereo:duration={}:sample_rate=48000",
|
||||||
|
node.out - node.seek
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
chain.add_filter(&audio, nr, Audio);
|
chain.add_filter(&audio, nr, Audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,11 +438,12 @@ fn extend_audio(node: &mut Media, chain: &mut Filters, nr: i32) {
|
|||||||
{
|
{
|
||||||
if node.out - node.seek > audio_duration - node.seek + 0.1 && node.duration >= node.out
|
if node.out - node.seek > audio_duration - node.seek + 0.1 && node.duration >= node.out
|
||||||
{
|
{
|
||||||
chain.add_filter(
|
let apad = match &ADVANCED_CONFIG.decoder.filters.apad {
|
||||||
&format!("apad=whole_dur={}", node.out - node.seek),
|
Some(apad) => custom_format(apad, &[node.out - node.seek]),
|
||||||
nr,
|
None => format!("apad=whole_dur={}", node.out - node.seek),
|
||||||
Audio,
|
};
|
||||||
)
|
|
||||||
|
chain.add_filter(&apad, nr, Audio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,7 +451,12 @@ fn extend_audio(node: &mut Media, chain: &mut Filters, nr: i32) {
|
|||||||
|
|
||||||
fn audio_volume(chain: &mut Filters, config: &PlayoutConfig, nr: i32) {
|
fn audio_volume(chain: &mut Filters, config: &PlayoutConfig, nr: i32) {
|
||||||
if config.processing.volume != 1.0 {
|
if config.processing.volume != 1.0 {
|
||||||
chain.add_filter(&format!("volume={}", config.processing.volume), nr, Audio)
|
let volume = match &ADVANCED_CONFIG.decoder.filters.volume {
|
||||||
|
Some(volume) => custom_format(volume, &[config.processing.volume]),
|
||||||
|
None => format!("volume={}", config.processing.volume),
|
||||||
|
};
|
||||||
|
|
||||||
|
chain.add_filter(&volume, nr, Audio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,8 +487,12 @@ pub fn split_filter(chain: &mut Filters, count: usize, nr: i32, filter_type: Fil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let split_filter = format!("split={count}{}", out_link.join(""));
|
let split = match &ADVANCED_CONFIG.decoder.filters.split {
|
||||||
chain.add_filter(&split_filter, nr, filter_type);
|
Some(split) => custom_format(split, &[count.to_string(), out_link.join("")]),
|
||||||
|
None => format!("split={count}{}", out_link.join("")),
|
||||||
|
};
|
||||||
|
|
||||||
|
chain.add_filter(&split, nr, filter_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@ use std::{
|
|||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::utils::{controller::ProcessUnit::*, Media, PlayoutConfig};
|
use crate::utils::{controller::ProcessUnit::*, custom_format, Media, PlayoutConfig};
|
||||||
|
use crate::ADVANCED_CONFIG;
|
||||||
|
|
||||||
pub fn filter_node(
|
pub fn filter_node(
|
||||||
config: &PlayoutConfig,
|
config: &PlayoutConfig,
|
||||||
@ -43,7 +44,11 @@ pub fn filter_node(
|
|||||||
.replace('\'', "'\\\\\\''")
|
.replace('\'', "'\\\\\\''")
|
||||||
.replace('%', "\\\\\\%")
|
.replace('%', "\\\\\\%")
|
||||||
.replace(':', "\\:");
|
.replace(':', "\\:");
|
||||||
filter = format!("drawtext=text='{escaped_text}':{}{font}", config.text.style)
|
|
||||||
|
filter = match &ADVANCED_CONFIG.decoder.filters.drawtext_from_file {
|
||||||
|
Some(drawtext) => custom_format(drawtext, &[&escaped_text, &config.text.style, &font]),
|
||||||
|
None => format!("drawtext=text='{escaped_text}':{}{font}", config.text.style),
|
||||||
|
};
|
||||||
} else if let Some(socket) = zmq_socket {
|
} else if let Some(socket) = zmq_socket {
|
||||||
let mut filter_cmd = format!("text=''{font}");
|
let mut filter_cmd = format!("text=''{font}");
|
||||||
|
|
||||||
@ -53,10 +58,13 @@ pub fn filter_node(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filter = format!(
|
filter = match &ADVANCED_CONFIG.decoder.filters.drawtext_from_zmq {
|
||||||
"zmq=b=tcp\\\\://'{}',drawtext@dyntext={filter_cmd}",
|
Some(drawtext) => custom_format(drawtext, &[&socket.replace(':', "\\:"), &filter_cmd]),
|
||||||
socket.replace(':', "\\:")
|
None => format!(
|
||||||
)
|
"zmq=b=tcp\\\\://'{}',drawtext@dyntext={filter_cmd}",
|
||||||
|
socket.replace(':', "\\:")
|
||||||
|
),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
filter
|
filter
|
||||||
|
@ -58,6 +58,7 @@ pub struct Filters {
|
|||||||
pub tpad: Option<String>,
|
pub tpad: Option<String>,
|
||||||
pub drawtext_from_file: Option<String>,
|
pub drawtext_from_file: Option<String>,
|
||||||
pub drawtext_from_zmq: Option<String>,
|
pub drawtext_from_zmq: Option<String>,
|
||||||
|
pub aevalsrc: Option<String>,
|
||||||
pub apad: Option<String>,
|
pub apad: Option<String>,
|
||||||
pub volume: Option<String>,
|
pub volume: Option<String>,
|
||||||
pub split: Option<String>,
|
pub split: Option<String>,
|
||||||
@ -80,19 +81,19 @@ impl AdvancedConfig {
|
|||||||
config = serde_yaml::from_reader(f).expect("Could not read advanced config file");
|
config = serde_yaml::from_reader(f).expect("Could not read advanced config file");
|
||||||
|
|
||||||
if let Some(input_parm) = &config.decoder.input_param {
|
if let Some(input_parm) = &config.decoder.input_param {
|
||||||
config.decoder.input_cmd = split(&input_parm);
|
config.decoder.input_cmd = split(input_parm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(output_param) = &config.decoder.output_param {
|
if let Some(output_param) = &config.decoder.output_param {
|
||||||
config.decoder.output_cmd = split(&output_param);
|
config.decoder.output_cmd = split(output_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(input_param) = &config.encoder.input_param {
|
if let Some(input_param) = &config.encoder.input_param {
|
||||||
config.encoder.input_cmd = split(&input_param);
|
config.encoder.input_cmd = split(input_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(input_param) = &config.ingest.input_param {
|
if let Some(input_param) = &config.ingest.input_param {
|
||||||
config.ingest.input_cmd = split(&input_param);
|
config.ingest.input_cmd = split(input_param);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user