move function prepare_output_cmd, add test video_audio_output
This commit is contained in:
parent
87c508be54
commit
b7a3e356d1
@ -28,10 +28,11 @@ use std::{
|
||||
use simplelog::*;
|
||||
|
||||
use crate::input::{ingest::log_line, source_generator};
|
||||
use crate::utils::prepare_output_cmd;
|
||||
use ffplayout_lib::filter::filter_chains;
|
||||
use ffplayout_lib::utils::{
|
||||
prepare_output_cmd, sec_to_time, stderr_reader, test_tcp_port, Encoder, Ingest, Media,
|
||||
PlayerControl, PlayoutConfig, PlayoutStatus, ProcessControl,
|
||||
sec_to_time, stderr_reader, test_tcp_port, Encoder, Ingest, Media, PlayerControl,
|
||||
PlayoutConfig, PlayoutStatus, ProcessControl,
|
||||
};
|
||||
use ffplayout_lib::vec_strings;
|
||||
|
||||
|
@ -5,8 +5,9 @@ use std::{
|
||||
|
||||
use simplelog::*;
|
||||
|
||||
use crate::utils::prepare_output_cmd;
|
||||
use ffplayout_lib::filter::v_drawtext;
|
||||
use ffplayout_lib::utils::{prepare_output_cmd, PlayoutConfig};
|
||||
use ffplayout_lib::utils::PlayoutConfig;
|
||||
use ffplayout_lib::vec_strings;
|
||||
|
||||
/// Streaming Output
|
||||
|
@ -6,8 +6,12 @@ use std::{
|
||||
pub mod arg_parse;
|
||||
|
||||
pub use arg_parse::Args;
|
||||
use ffplayout_lib::utils::{time_to_sec, PlayoutConfig};
|
||||
use ffplayout_lib::{
|
||||
utils::{time_to_sec, PlayoutConfig},
|
||||
vec_strings,
|
||||
};
|
||||
|
||||
/// Read command line arguments, and override the config with them.
|
||||
pub fn get_config(args: Args) -> PlayoutConfig {
|
||||
let cfg_path = match args.channel {
|
||||
Some(c) => {
|
||||
@ -80,4 +84,79 @@ pub fn get_config(args: Args) -> PlayoutConfig {
|
||||
|
||||
config
|
||||
}
|
||||
// Read command line arguments, and override the config with them.
|
||||
|
||||
/// Prepare output parameters
|
||||
///
|
||||
/// seek for multiple outputs and add mapping for it
|
||||
pub fn prepare_output_cmd(
|
||||
prefix: Vec<String>,
|
||||
mut filter: Vec<String>,
|
||||
params: Vec<String>,
|
||||
mode: &str,
|
||||
) -> Vec<String> {
|
||||
let params_len = params.len();
|
||||
let mut output_params = params.clone();
|
||||
let mut output_a_map = "[a_out1]".to_string();
|
||||
let mut output_v_map = "[v_out1]".to_string();
|
||||
let mut output_count = 1;
|
||||
let mut cmd = prefix;
|
||||
|
||||
if !filter.is_empty() {
|
||||
output_params.clear();
|
||||
|
||||
for (i, p) in params.iter().enumerate() {
|
||||
let mut param = p.clone();
|
||||
|
||||
param = param.replace("[0:v]", "[vout0]");
|
||||
param = param.replace("[0:a]", "[aout0]");
|
||||
|
||||
if param != "-filter_complex" {
|
||||
output_params.push(param.clone());
|
||||
}
|
||||
|
||||
if i > 0
|
||||
&& !param.starts_with('-')
|
||||
&& !params[i - 1].starts_with('-')
|
||||
&& i < params_len - 1
|
||||
{
|
||||
output_count += 1;
|
||||
let mut a_map = "0:a".to_string();
|
||||
let v_map = format!("[v_out{output_count}]");
|
||||
output_v_map.push_str(&v_map);
|
||||
|
||||
if mode == "hls" {
|
||||
a_map = format!("[a_out{output_count}]");
|
||||
}
|
||||
|
||||
output_a_map.push_str(&a_map);
|
||||
|
||||
let mut map = vec_strings!["-map", v_map, "-map", a_map];
|
||||
|
||||
output_params.append(&mut map);
|
||||
}
|
||||
}
|
||||
|
||||
if output_count > 1 && mode == "hls" {
|
||||
filter[1].push_str(&format!(";[vout0]split={output_count}{output_v_map}"));
|
||||
filter[1].push_str(&format!(";[aout0]asplit={output_count}{output_a_map}"));
|
||||
filter.drain(2..);
|
||||
cmd.append(&mut filter);
|
||||
cmd.append(&mut vec_strings!["-map", "[v_out1]", "-map", "[a_out1]"]);
|
||||
} else if output_count == 1 && mode == "hls" && output_params[0].contains("split") {
|
||||
let out_filter = output_params.remove(0);
|
||||
filter[1].push_str(&format!(";{out_filter}"));
|
||||
filter.drain(2..);
|
||||
cmd.append(&mut filter);
|
||||
} else if output_count > 1 && mode == "stream" {
|
||||
filter[1].push_str(&format!(",split={output_count}{output_v_map}"));
|
||||
cmd.append(&mut filter);
|
||||
cmd.append(&mut vec_strings!["-map", "[v_out1]", "-map", "0:a"]);
|
||||
} else {
|
||||
cmd.append(&mut filter);
|
||||
}
|
||||
}
|
||||
|
||||
cmd.append(&mut output_params);
|
||||
|
||||
cmd
|
||||
}
|
||||
|
@ -570,82 +570,6 @@ pub fn gen_dummy(config: &PlayoutConfig, duration: f64) -> (String, Vec<String>)
|
||||
// count
|
||||
// }
|
||||
|
||||
/// Prepare output parameters
|
||||
///
|
||||
/// seek for multiple outputs and add mapping for it
|
||||
pub fn prepare_output_cmd(
|
||||
prefix: Vec<String>,
|
||||
mut filter: Vec<String>,
|
||||
params: Vec<String>,
|
||||
mode: &str,
|
||||
) -> Vec<String> {
|
||||
let params_len = params.len();
|
||||
let mut output_params = params.clone();
|
||||
let mut output_a_map = "[a_out1]".to_string();
|
||||
let mut output_v_map = "[v_out1]".to_string();
|
||||
let mut output_count = 1;
|
||||
let mut cmd = prefix;
|
||||
|
||||
if !filter.is_empty() {
|
||||
output_params.clear();
|
||||
|
||||
for (i, p) in params.iter().enumerate() {
|
||||
let mut param = p.clone();
|
||||
|
||||
param = param.replace("[0:v]", "[vout0]");
|
||||
param = param.replace("[0:a]", "[aout0]");
|
||||
|
||||
if param != "-filter_complex" {
|
||||
output_params.push(param.clone());
|
||||
}
|
||||
|
||||
if i > 0
|
||||
&& !param.starts_with('-')
|
||||
&& !params[i - 1].starts_with('-')
|
||||
&& i < params_len - 1
|
||||
{
|
||||
output_count += 1;
|
||||
let mut a_map = "0:a".to_string();
|
||||
let v_map = format!("[v_out{output_count}]");
|
||||
output_v_map.push_str(&v_map);
|
||||
|
||||
if mode == "hls" {
|
||||
a_map = format!("[a_out{output_count}]");
|
||||
}
|
||||
|
||||
output_a_map.push_str(&a_map);
|
||||
|
||||
let mut map = vec_strings!["-map", v_map, "-map", a_map];
|
||||
|
||||
output_params.append(&mut map);
|
||||
}
|
||||
}
|
||||
|
||||
if output_count > 1 && mode == "hls" {
|
||||
filter[1].push_str(&format!(";[vout0]split={output_count}{output_v_map}"));
|
||||
filter[1].push_str(&format!(";[aout0]asplit={output_count}{output_a_map}"));
|
||||
filter.drain(2..);
|
||||
cmd.append(&mut filter);
|
||||
cmd.append(&mut vec_strings!["-map", "[v_out1]", "-map", "[a_out1]"]);
|
||||
} else if output_count == 1 && mode == "hls" && output_params[0].contains("split") {
|
||||
let out_filter = output_params.remove(0);
|
||||
filter[1].push_str(&format!(";{out_filter}"));
|
||||
filter.drain(2..);
|
||||
cmd.append(&mut filter);
|
||||
} else if output_count > 1 && mode == "stream" {
|
||||
filter[1].push_str(&format!(",split={output_count}{output_v_map}"));
|
||||
cmd.append(&mut filter);
|
||||
cmd.append(&mut vec_strings!["-map", "[v_out1]", "-map", "0:a"]);
|
||||
} else {
|
||||
cmd.append(&mut filter);
|
||||
}
|
||||
}
|
||||
|
||||
cmd.append(&mut output_params);
|
||||
|
||||
cmd
|
||||
}
|
||||
|
||||
pub fn is_remote(path: &str) -> bool {
|
||||
Regex::new(r"^https?://.*").unwrap().is_match(path)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use ffplayout::input::playlist::gen_source;
|
||||
use ffplayout::{input::playlist::gen_source, utils::prepare_output_cmd};
|
||||
use ffplayout_lib::{
|
||||
utils::{Media, PlayoutConfig},
|
||||
vec_strings,
|
||||
@ -80,3 +80,131 @@ fn dual_audio_input() {
|
||||
assert_eq!(media.cmd, Some(vec_strings!["-i", "assets/dual_audio.mp4"]));
|
||||
assert_eq!(media.filter, test_filter_cmd);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prepare_output_cmd() {
|
||||
let enc_prefix = vec_strings![
|
||||
"-hide_banner",
|
||||
"-nostats",
|
||||
"-v",
|
||||
"level+error",
|
||||
"-re",
|
||||
"-i",
|
||||
"pipe:0"
|
||||
];
|
||||
let filter = vec_strings![
|
||||
"-filter_complex",
|
||||
"[0:v]null,zmq=b=tcp\\\\://'127.0.0.1\\:5555',drawtext=text=''"
|
||||
];
|
||||
let params = vec_strings![
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-flags",
|
||||
"+global_header",
|
||||
"-f",
|
||||
"flv",
|
||||
"rtmp://localhost/live/stream",
|
||||
"-s",
|
||||
"512x288",
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-flags",
|
||||
"+global_header",
|
||||
"-f",
|
||||
"flv",
|
||||
"rtmp://localhost:1937/live/stream"
|
||||
];
|
||||
|
||||
let mut t1_params = enc_prefix.clone();
|
||||
t1_params.append(&mut params.clone());
|
||||
let cmd_two_outs =
|
||||
prepare_output_cmd(enc_prefix.clone(), vec_strings![], params.clone(), "stream");
|
||||
|
||||
assert_eq!(cmd_two_outs, t1_params);
|
||||
|
||||
let mut test_cmd = enc_prefix.clone();
|
||||
let mut test_params = params.clone();
|
||||
let mut t2_filter = filter.clone();
|
||||
t2_filter[1].push_str(",split=2[v_out1][v_out2]");
|
||||
test_cmd.append(&mut t2_filter);
|
||||
|
||||
test_params.insert(0, "-map".to_string());
|
||||
test_params.insert(1, "[v_out1]".to_string());
|
||||
test_params.insert(2, "-map".to_string());
|
||||
test_params.insert(3, "0:a".to_string());
|
||||
|
||||
test_params.insert(11, "-map".to_string());
|
||||
test_params.insert(12, "[v_out2]".to_string());
|
||||
test_params.insert(13, "-map".to_string());
|
||||
test_params.insert(14, "0:a".to_string());
|
||||
|
||||
test_cmd.append(&mut test_params);
|
||||
let cmd_two_outs_with_filter = prepare_output_cmd(enc_prefix, filter, params, "stream");
|
||||
|
||||
assert_eq!(cmd_two_outs_with_filter, test_cmd);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn video_audio_output() {
|
||||
let mut config = PlayoutConfig::new(Some("../assets/ffplayout.yml".to_string()));
|
||||
config.out.mode = "stream".to_string();
|
||||
config.processing.add_logo = false;
|
||||
config.out.output_cmd = Some(vec_strings![
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-c:a",
|
||||
"aac",
|
||||
"-ar",
|
||||
"44100",
|
||||
"-b:a",
|
||||
"128k",
|
||||
"-flags",
|
||||
"+global_header",
|
||||
"-f",
|
||||
"flv",
|
||||
"rtmp://localhost/live/stream"
|
||||
]);
|
||||
|
||||
let mut enc_cmd = vec![];
|
||||
let enc_filter = vec![];
|
||||
let mut output_cmd = config.out.output_cmd.as_ref().unwrap().clone();
|
||||
|
||||
let enc_prefix = vec_strings![
|
||||
"-hide_banner",
|
||||
"-nostats",
|
||||
"-v",
|
||||
"level+error",
|
||||
"-re",
|
||||
"-i",
|
||||
"pipe:0"
|
||||
];
|
||||
|
||||
enc_cmd.append(&mut output_cmd);
|
||||
|
||||
let enc_cmd = prepare_output_cmd(enc_prefix, enc_filter, enc_cmd, &config.out.mode);
|
||||
|
||||
let test_cmd = vec_strings![
|
||||
"-hide_banner",
|
||||
"-nostats",
|
||||
"-v",
|
||||
"level+error",
|
||||
"-re",
|
||||
"-i",
|
||||
"pipe:0",
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-c:a",
|
||||
"aac",
|
||||
"-ar",
|
||||
"44100",
|
||||
"-b:a",
|
||||
"128k",
|
||||
"-flags",
|
||||
"+global_header",
|
||||
"-f",
|
||||
"flv",
|
||||
"rtmp://localhost/live/stream"
|
||||
];
|
||||
|
||||
assert_eq!(enc_cmd, test_cmd);
|
||||
}
|
||||
|
@ -50,66 +50,3 @@ fn test_delta() {
|
||||
|
||||
assert!(delta < 2.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prepare_output_cmd() {
|
||||
let enc_prefix = vec_strings![
|
||||
"-hide_banner",
|
||||
"-nostats",
|
||||
"-v",
|
||||
"level+error",
|
||||
"-re",
|
||||
"-i",
|
||||
"pipe:0"
|
||||
];
|
||||
let filter = vec_strings![
|
||||
"-filter_complex",
|
||||
"[0:v]null,zmq=b=tcp\\\\://'127.0.0.1\\:5555',drawtext=text=''"
|
||||
];
|
||||
let params = vec_strings![
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-flags",
|
||||
"+global_header",
|
||||
"-f",
|
||||
"flv",
|
||||
"rtmp://localhost/live/stream",
|
||||
"-s",
|
||||
"512x288",
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-flags",
|
||||
"+global_header",
|
||||
"-f",
|
||||
"flv",
|
||||
"rtmp://localhost:1937/live/stream"
|
||||
];
|
||||
|
||||
let mut t1_params = enc_prefix.clone();
|
||||
t1_params.append(&mut params.clone());
|
||||
let cmd_two_outs =
|
||||
prepare_output_cmd(enc_prefix.clone(), vec_strings![], params.clone(), "stream");
|
||||
|
||||
assert_eq!(cmd_two_outs, t1_params);
|
||||
|
||||
let mut test_cmd = enc_prefix.clone();
|
||||
let mut test_params = params.clone();
|
||||
let mut t2_filter = filter.clone();
|
||||
t2_filter[1].push_str(",split=2[v_out1][v_out2]");
|
||||
test_cmd.append(&mut t2_filter);
|
||||
|
||||
test_params.insert(0, "-map".to_string());
|
||||
test_params.insert(1, "[v_out1]".to_string());
|
||||
test_params.insert(2, "-map".to_string());
|
||||
test_params.insert(3, "0:a".to_string());
|
||||
|
||||
test_params.insert(11, "-map".to_string());
|
||||
test_params.insert(12, "[v_out2]".to_string());
|
||||
test_params.insert(13, "-map".to_string());
|
||||
test_params.insert(14, "0:a".to_string());
|
||||
|
||||
test_cmd.append(&mut test_params);
|
||||
let cmd_two_outs_with_filter = prepare_output_cmd(enc_prefix, filter, params, "stream");
|
||||
|
||||
assert_eq!(cmd_two_outs_with_filter, test_cmd);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user