add more filters
This commit is contained in:
parent
5083c62ec7
commit
83317b4378
@ -4,15 +4,15 @@ use std::path::Path;
|
||||
use crate::utils::{is_close, Config, Program};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Filters {
|
||||
pub audio_chain: Option<String>,
|
||||
pub video_chain: Option<String>,
|
||||
pub audio_map: Option<String>,
|
||||
pub video_map: Option<String>,
|
||||
struct Filters {
|
||||
audio_chain: Option<String>,
|
||||
video_chain: Option<String>,
|
||||
audio_map: Option<String>,
|
||||
video_map: Option<String>,
|
||||
}
|
||||
|
||||
impl Filters {
|
||||
pub fn new() -> Self {
|
||||
fn new() -> Self {
|
||||
Filters {
|
||||
audio_chain: None,
|
||||
video_chain: None,
|
||||
@ -32,7 +32,11 @@ impl Filters {
|
||||
}
|
||||
}
|
||||
None => {
|
||||
self.audio_chain = Some(filter);
|
||||
if filter.contains("aevalsrc") || filter.contains("anoisesrc") {
|
||||
self.audio_chain = Some(filter);
|
||||
} else {
|
||||
self.audio_chain = Some(format!("[0:a]{filter}"));
|
||||
}
|
||||
self.audio_map = Some("[aout1]".to_string());
|
||||
}
|
||||
},
|
||||
@ -45,7 +49,7 @@ impl Filters {
|
||||
}
|
||||
}
|
||||
None => {
|
||||
self.video_chain = Some(filter);
|
||||
self.video_chain = Some(format!("[0:v]{filter}"));
|
||||
self.video_map = Some("[vout1]".to_string());
|
||||
}
|
||||
},
|
||||
@ -142,7 +146,7 @@ fn overlay(node: &mut Program, chain: &mut Filters, config: &Config, last_ad: bo
|
||||
config.processing.logo_opacity
|
||||
);
|
||||
let logo_loop = "loop=loop=-1:size=1:start=0";
|
||||
let mut logo_chain = format!("[v];movie={},{logo_loop},{opacity}", config.processing.logo);
|
||||
let mut logo_chain = format!("null[v];movie={},{logo_loop},{opacity}", config.processing.logo);
|
||||
|
||||
if last_ad {
|
||||
logo_chain.push_str(",fade=in:st=0:d=1.0:alpha=1")
|
||||
@ -161,6 +165,54 @@ fn overlay(node: &mut Program, chain: &mut Filters, config: &Config, last_ad: bo
|
||||
}
|
||||
}
|
||||
|
||||
fn extend_video(node: &mut Program, chain: &mut Filters) {
|
||||
let video_streams = node.probe.clone().unwrap().video_streams.unwrap();
|
||||
if video_streams.len() > 0 {
|
||||
let video_duration = &video_streams[0].duration;
|
||||
|
||||
if video_duration.is_some() {
|
||||
let duration_float = video_duration.clone().unwrap().parse::<f64>().unwrap();
|
||||
|
||||
if node.out - node.seek > duration_float - node.seek + 0.1 {
|
||||
chain.add_filter(format!("tpad=stop_mode=add:stop_duration={}", (node.out - node.seek) - (duration_float - node.seek)) , "video".into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_audio(node: &mut Program, chain: &mut Filters) {
|
||||
let audio_streams = node.probe.clone().unwrap().audio_streams.unwrap();
|
||||
if audio_streams.len() == 0 {
|
||||
println!("Clip: '{}' has no audio!", node.source);
|
||||
let audio = format!(
|
||||
"aevalsrc=0:channel_layout=stereo:duration={}:sample_rate=48000",
|
||||
node.out - node.seek
|
||||
);
|
||||
chain.add_filter(audio, "audio".into());
|
||||
}
|
||||
}
|
||||
|
||||
fn extend_audio(node: &mut Program, chain: &mut Filters) {
|
||||
let audio_streams = node.probe.clone().unwrap().audio_streams.unwrap();
|
||||
if audio_streams.len() > 0 {
|
||||
let audio_duration = &audio_streams[0].duration;
|
||||
|
||||
if audio_duration.is_some() {
|
||||
let duration_float = audio_duration.clone().unwrap().parse::<f64>().unwrap();
|
||||
|
||||
if node.out - node.seek > duration_float- node.seek + 0.1 {
|
||||
chain.add_filter(format!("apad=whole_dur={}", node.out - node.seek), "audio".into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn audio_volume(chain: &mut Filters, config: &Config) {
|
||||
if config.processing.volume != 1.0 {
|
||||
chain.add_filter(format!("volume={}", config.processing.volume), "audio".into())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filter_chains(node: &mut Program, config: &Config, last: bool, next: bool) -> Vec<String> {
|
||||
let mut filters = Filters::new();
|
||||
let probe = node.probe.clone();
|
||||
@ -189,48 +241,48 @@ pub fn filter_chains(node: &mut Program, config: &Config, last: bool, next: bool
|
||||
&mut filters,
|
||||
&config,
|
||||
);
|
||||
fade(node, &mut filters, "audio".into());
|
||||
extend_video(node, &mut filters);
|
||||
fade(node, &mut filters, "video".into());
|
||||
overlay(node, &mut filters, &config, last, next);
|
||||
|
||||
add_audio(node, &mut filters);
|
||||
extend_audio(node, &mut filters);
|
||||
fade(node, &mut filters, "audio".into());
|
||||
audio_volume(&mut filters, &config);
|
||||
}
|
||||
None => {
|
||||
println!("Clip has no media probe object. No filter applied!")
|
||||
}
|
||||
}
|
||||
|
||||
let mut filter_cmd = vec!["-filter_complex".to_string()];
|
||||
let mut filter_cmd = vec![];
|
||||
let mut filter_str: String = "".to_string();
|
||||
let mut filter_map: Vec<String> = vec![];
|
||||
|
||||
if filters.audio_chain.is_some() {
|
||||
filter_str.push_str(
|
||||
format!(
|
||||
"[0:a]{}{};",
|
||||
filters.audio_chain.unwrap(),
|
||||
filters.audio_map.clone().unwrap()
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
filter_str.push_str(filters.audio_chain.unwrap().as_str());
|
||||
filter_str.push_str(filters.audio_map.clone().unwrap().as_str());
|
||||
filter_map.append(&mut vec!["-map".to_string(), filters.audio_map.unwrap()]);
|
||||
} else {
|
||||
filter_map.append(&mut vec!["-map".to_string(), "0:a".to_string()]);
|
||||
}
|
||||
|
||||
if filters.video_chain.is_some() {
|
||||
filter_str.push_str(
|
||||
format!(
|
||||
"[0:v]{}{}",
|
||||
filters.video_chain.unwrap(),
|
||||
filters.video_map.clone().unwrap()
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
if filter_str.len() > 10 {
|
||||
filter_str.push_str(";")
|
||||
}
|
||||
filter_str.push_str(filters.video_chain.unwrap().as_str());
|
||||
filter_str.push_str(filters.video_map.clone().unwrap().as_str());
|
||||
filter_map.append(&mut vec!["-map".to_string(), filters.video_map.unwrap()]);
|
||||
} else {
|
||||
filter_map.append(&mut vec!["-map".to_string(), "0:v".to_string()]);
|
||||
}
|
||||
|
||||
filter_cmd.push(filter_str);
|
||||
if filter_str.len() > 10 {
|
||||
filter_cmd.push("-filter_complex".to_string());
|
||||
filter_cmd.push(filter_str);
|
||||
}
|
||||
|
||||
filter_cmd.append(&mut filter_map);
|
||||
|
||||
filter_cmd
|
||||
|
@ -9,16 +9,33 @@ use crate::utils::{program, sec_to_time, Config};
|
||||
pub fn play(config: Config) -> io::Result<()> {
|
||||
let get_source = program(config.clone());
|
||||
let dec_settings = config.processing.settings.unwrap();
|
||||
let mut enc_cmd = vec![
|
||||
"-hide_banner",
|
||||
"-nostats",
|
||||
"-v",
|
||||
"level+error",
|
||||
"-i",
|
||||
"pipe:0",
|
||||
];
|
||||
|
||||
let mut enc_filter: Vec<String> = vec![];
|
||||
|
||||
if config.text.add_text && !config.text.over_pre {
|
||||
let text_filter: String = format!(
|
||||
"null,zmq=b=tcp\\\\://'{}',drawtext=text='':fontfile='{}'",
|
||||
config.text.bind_address.replace(":", "\\:"),
|
||||
config.text.fontfile
|
||||
);
|
||||
|
||||
enc_filter = vec!["-vf".to_string(), text_filter];
|
||||
}
|
||||
|
||||
enc_cmd.append(&mut enc_filter.iter().map(String::as_str).collect());
|
||||
|
||||
println!("Encoder CMD: '{:?}'", enc_cmd);
|
||||
|
||||
let mut enc_proc = Command::new("ffplay")
|
||||
.args([
|
||||
"-hide_banner",
|
||||
"-nostats",
|
||||
"-v",
|
||||
"level+error",
|
||||
"-i",
|
||||
"pipe:0",
|
||||
])
|
||||
.args(enc_cmd)
|
||||
.stdin(Stdio::piped())
|
||||
// .stderr(Stdio::piped())
|
||||
.spawn()
|
||||
@ -28,22 +45,23 @@ pub fn play(config: Config) -> io::Result<()> {
|
||||
// let mut buffer = vec![0; 65376];
|
||||
|
||||
if let Some(mut enc_input) = enc_proc.stdin.take() {
|
||||
for node in get_source {
|
||||
// println!("Play: {:#?}", node);
|
||||
for node in get_source {
|
||||
println!("Node begin: {:?}", sec_to_time(node.begin.unwrap()));
|
||||
//println!("Play: {:#?}", node.filter);
|
||||
|
||||
let cmd = node.cmd.unwrap();
|
||||
let filter = node.filter.unwrap();
|
||||
|
||||
let mut dec_cmd = vec![
|
||||
"-v",
|
||||
"level+error",
|
||||
"-hide_banner",
|
||||
"-nostats"
|
||||
];
|
||||
let mut dec_cmd = vec!["-v", "level+error", "-hide_banner", "-nostats"];
|
||||
|
||||
dec_cmd.append(&mut cmd.iter().map(String::as_str).collect());
|
||||
dec_cmd.append(&mut filter.iter().map(String::as_str).collect());
|
||||
|
||||
if filter.len() > 1 {
|
||||
dec_cmd.append(&mut filter.iter().map(String::as_str).collect());
|
||||
}
|
||||
|
||||
dec_cmd.append(&mut dec_settings.iter().map(String::as_str).collect());
|
||||
println!("Play: {:?}", dec_cmd);
|
||||
|
||||
let mut dec_proc = Command::new("ffmpeg")
|
||||
.args(dec_cmd)
|
||||
@ -59,14 +77,20 @@ pub fn play(config: Config) -> io::Result<()> {
|
||||
let dec_output = dec_proc.wait_with_output()?;
|
||||
|
||||
if dec_output.stderr.len() > 0 {
|
||||
println!("[Encoder] {}", String::from_utf8(dec_output.stderr).unwrap());
|
||||
println!(
|
||||
"[Encoder] {}",
|
||||
String::from_utf8(dec_output.stderr).unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enc_proc.wait()?;
|
||||
let enc_output = enc_proc.wait_with_output()?;
|
||||
println!("[Encoder] {}", String::from_utf8(enc_output.stderr).unwrap());
|
||||
println!(
|
||||
"[Encoder] {}",
|
||||
String::from_utf8(enc_output.stderr).unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -38,7 +38,7 @@ pub struct Args {
|
||||
pub output: Option<String>,
|
||||
|
||||
#[clap(short, long, help = "set audio volume")]
|
||||
pub volume: Option<String>,
|
||||
pub volume: Option<f64>,
|
||||
}
|
||||
|
||||
pub fn get_args() -> Args {
|
||||
|
@ -60,7 +60,7 @@ pub struct Processing {
|
||||
pub loud_tp: f32,
|
||||
pub loud_lra: f32,
|
||||
pub output_count: u32,
|
||||
pub volume: String,
|
||||
pub volume: f64,
|
||||
pub settings: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
@ -91,6 +91,7 @@ pub struct Text {
|
||||
pub add_text: bool,
|
||||
pub over_pre: bool,
|
||||
pub bind_address: String,
|
||||
pub fontfile: String,
|
||||
pub text_from_filename: bool,
|
||||
pub style: String,
|
||||
pub regex: String,
|
||||
|
Loading…
x
Reference in New Issue
Block a user