remove str/string conversions in vectors, log ingest url with match

This commit is contained in:
jb-alvarado 2022-05-09 15:16:40 +02:00
parent 83a8684d8e
commit 4cd6b885ff
9 changed files with 79 additions and 74 deletions

View File

@ -10,6 +10,7 @@ use simplelog::*;
use crate::filter::ingest_filter::filter_cmd; use crate::filter::ingest_filter::filter_cmd;
use crate::utils::{stderr_reader, GlobalConfig, Ingest, ProcessControl}; use crate::utils::{stderr_reader, GlobalConfig, Ingest, ProcessControl};
use crate::vec_strings;
/// ffmpeg Ingest Server /// ffmpeg Ingest Server
/// ///
@ -21,22 +22,18 @@ pub fn ingest_server(
) -> Result<(), Error> { ) -> Result<(), Error> {
let config = GlobalConfig::global(); let config = GlobalConfig::global();
let mut buffer: [u8; 65088] = [0; 65088]; let mut buffer: [u8; 65088] = [0; 65088];
let filter_list = filter_cmd(); let mut server_cmd = vec_strings!["-hide_banner", "-nostats", "-v", log_format];
let mut server_cmd = vec!["-hide_banner", "-nostats", "-v", log_format.as_str()];
let stream_input = config.ingest.input_cmd.clone().unwrap(); let stream_input = config.ingest.input_cmd.clone().unwrap();
let stream_settings = config.processing.settings.clone().unwrap();
server_cmd.append(&mut stream_input.iter().map(String::as_str).collect()); server_cmd.append(&mut stream_input.clone());
server_cmd.append(&mut filter_list.iter().map(String::as_str).collect()); server_cmd.append(&mut filter_cmd());
server_cmd.append(&mut stream_settings.iter().map(String::as_str).collect()); server_cmd.append(&mut config.processing.settings.clone().unwrap());
let mut is_running; let mut is_running;
info!( if let Some(url) = stream_input.iter().find(|s| s.contains("://")) {
"Start ingest server, listening on: <b><magenta>{}</></b>", info!("Start ingest server, listening on: <b><magenta>{url}</></b>",);
stream_input.last().unwrap() };
);
debug!( debug!(
"Server CMD: <bright-blue>\"ffmpeg {}\"</>", "Server CMD: <bright-blue>\"ffmpeg {}\"</>",

View File

@ -243,7 +243,6 @@ impl Iterator for CurrentProgram {
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if self.playout_stat.list_init.load(Ordering::SeqCst) { if self.playout_stat.list_init.load(Ordering::SeqCst) {
debug!("Playlist init");
self.check_update(true); self.check_update(true);
if self.json_path.is_some() { if self.json_path.is_some() {
@ -451,6 +450,7 @@ fn gen_source(mut node: Media) -> Media {
/// Handle init clip, but this clip can be the last one in playlist, /// Handle init clip, but this clip can be the last one in playlist,
/// this we have to figure out and calculate the right length. /// this we have to figure out and calculate the right length.
fn handle_list_init(mut node: Media) -> Media { fn handle_list_init(mut node: Media) -> Media {
debug!("Playlist init");
let (_, total_delta) = get_delta(&node.begin.unwrap()); let (_, total_delta) = get_delta(&node.begin.unwrap());
let mut out = node.out; let mut out = node.out;

View File

@ -4,6 +4,7 @@ use simplelog::*;
use crate::filter::v_drawtext; use crate::filter::v_drawtext;
use crate::utils::{GlobalConfig, Media}; use crate::utils::{GlobalConfig, Media};
use crate::vec_strings;
/// Desktop Output /// Desktop Output
/// ///
@ -13,7 +14,7 @@ pub fn output(log_format: &str) -> process::Child {
let mut enc_filter: Vec<String> = vec![]; let mut enc_filter: Vec<String> = vec![];
let mut enc_cmd = vec!["-hide_banner", "-nostats", "-v", log_format, "-i", "pipe:0"]; let mut enc_cmd = vec_strings!["-hide_banner", "-nostats", "-v", log_format, "-i", "pipe:0"];
if config.text.add_text && !config.text.over_pre { if config.text.add_text && !config.text.over_pre {
info!( info!(
@ -26,7 +27,7 @@ pub fn output(log_format: &str) -> process::Child {
enc_filter = vec!["-vf".to_string(), filter]; enc_filter = vec!["-vf".to_string(), filter];
} }
enc_cmd.append(&mut enc_filter.iter().map(String::as_str).collect()); enc_cmd.append(&mut enc_filter);
debug!( debug!(
"Encoder CMD: <bright-blue>\"ffplay {}\"</>", "Encoder CMD: <bright-blue>\"ffplay {}\"</>",

View File

@ -33,6 +33,7 @@ use crate::utils::{
sec_to_time, stderr_reader, Decoder, GlobalConfig, Ingest, PlayerControl, PlayoutStatus, sec_to_time, stderr_reader, Decoder, GlobalConfig, Ingest, PlayerControl, PlayoutStatus,
ProcessControl, ProcessControl,
}; };
use crate::vec_strings;
fn format_line(line: String, level: &str) -> String { fn format_line(line: String, level: &str) -> String {
line.replace(&format!("[{level: >5}] "), "") line.replace(&format!("[{level: >5}] "), "")
@ -44,23 +45,20 @@ fn ingest_to_hls_server(
mut proc_control: ProcessControl, mut proc_control: ProcessControl,
) -> Result<(), Error> { ) -> Result<(), Error> {
let config = GlobalConfig::global(); let config = GlobalConfig::global();
let dec_settings = config.out.clone().output_cmd.unwrap();
let playlist_init = playout_stat.list_init; let playlist_init = playout_stat.list_init;
let filter_list = filter_cmd();
let mut server_cmd = vec!["-hide_banner", "-nostats", "-v", "level+info"]; let mut server_cmd = vec_strings!["-hide_banner", "-nostats", "-v", "level+info"];
let stream_input = config.ingest.input_cmd.clone().unwrap(); let stream_input = config.ingest.input_cmd.clone().unwrap();
server_cmd.append(&mut stream_input.iter().map(String::as_str).collect()); server_cmd.append(&mut stream_input.clone());
server_cmd.append(&mut filter_list.iter().map(String::as_str).collect()); server_cmd.append(&mut filter_cmd());
server_cmd.append(&mut dec_settings.iter().map(String::as_str).collect()); server_cmd.append(&mut config.out.clone().output_cmd.unwrap());
let mut is_running; let mut is_running;
info!( if let Some(url) = stream_input.iter().find(|s| s.contains("://")) {
"Start ingest server, listening on: <b><magenta>{}</></b>", info!("Start ingest server, listening on: <b><magenta>{url}</></b>",);
stream_input.last().unwrap() };
);
debug!( debug!(
"Server CMD: <bright-blue>\"ffmpeg {}\"</>", "Server CMD: <bright-blue>\"ffmpeg {}\"</>",
@ -137,7 +135,6 @@ pub fn write_hls(
mut proc_control: ProcessControl, mut proc_control: ProcessControl,
) { ) {
let config = GlobalConfig::global(); let config = GlobalConfig::global();
let dec_settings = config.out.clone().output_cmd.unwrap();
let ff_log_format = format!("level+{}", config.logging.ffmpeg_level.to_lowercase()); let ff_log_format = format!("level+{}", config.logging.ffmpeg_level.to_lowercase());
let play_stat = playout_stat.clone(); let play_stat = playout_stat.clone();
let proc_control_c = proc_control.clone(); let proc_control_c = proc_control.clone();
@ -158,7 +155,7 @@ pub fn write_hls(
for node in get_source { for node in get_source {
*play_control.current_media.lock().unwrap() = Some(node.clone()); *play_control.current_media.lock().unwrap() = Some(node.clone());
let cmd = match node.cmd { let mut cmd = match node.cmd {
Some(cmd) => cmd, Some(cmd) => cmd,
None => break, None => break,
}; };
@ -173,15 +170,15 @@ pub fn write_hls(
node.source node.source
); );
let filter = node.filter.unwrap(); let mut filter = node.filter.unwrap();
let mut dec_cmd = vec!["-hide_banner", "-nostats", "-v", ff_log_format.as_str()]; let mut dec_cmd = vec_strings!["-hide_banner", "-nostats", "-v", &ff_log_format];
dec_cmd.append(&mut cmd.iter().map(String::as_str).collect()); dec_cmd.append(&mut cmd);
if filter.len() > 1 { if filter.len() > 1 {
dec_cmd.append(&mut filter.iter().map(String::as_str).collect()); dec_cmd.append(&mut filter);
} }
dec_cmd.append(&mut dec_settings.iter().map(String::as_str).collect()); dec_cmd.append(&mut config.out.clone().output_cmd.unwrap());
debug!( debug!(
"HLS writer CMD: <bright-blue>\"ffmpeg {}\"</>", "HLS writer CMD: <bright-blue>\"ffmpeg {}\"</>",

View File

@ -20,6 +20,7 @@ use crate::utils::{
sec_to_time, stderr_reader, Decoder, Encoder, GlobalConfig, PlayerControl, PlayoutStatus, sec_to_time, stderr_reader, Decoder, Encoder, GlobalConfig, PlayerControl, PlayoutStatus,
ProcessControl, ProcessControl,
}; };
use crate::vec_strings;
/// Player /// Player
/// ///
@ -36,7 +37,6 @@ pub fn player(
mut proc_control: ProcessControl, mut proc_control: ProcessControl,
) { ) {
let config = GlobalConfig::global(); let config = GlobalConfig::global();
let dec_settings = config.processing.clone().settings.unwrap();
let ff_log_format = format!("level+{}", config.logging.ffmpeg_level.to_lowercase()); let ff_log_format = format!("level+{}", config.logging.ffmpeg_level.to_lowercase());
let mut buffer = [0; 65088]; let mut buffer = [0; 65088];
let mut live_on = false; let mut live_on = false;
@ -80,7 +80,7 @@ pub fn player(
'source_iter: for node in get_source { 'source_iter: for node in get_source {
*play_control.current_media.lock().unwrap() = Some(node.clone()); *play_control.current_media.lock().unwrap() = Some(node.clone());
let cmd = match node.cmd { let mut cmd = match node.cmd {
Some(cmd) => cmd, Some(cmd) => cmd,
None => break, None => break,
}; };
@ -95,15 +95,15 @@ pub fn player(
node.source node.source
); );
let filter = node.filter.unwrap(); let mut filter = node.filter.unwrap();
let mut dec_cmd = vec!["-hide_banner", "-nostats", "-v", ff_log_format.as_str()]; let mut dec_cmd = vec_strings!["-hide_banner", "-nostats", "-v", &ff_log_format];
dec_cmd.append(&mut cmd.iter().map(String::as_str).collect()); dec_cmd.append(&mut cmd);
if filter.len() > 1 { if filter.len() > 1 {
dec_cmd.append(&mut filter.iter().map(String::as_str).collect()); dec_cmd.append(&mut filter);
} }
dec_cmd.append(&mut dec_settings.iter().map(String::as_str).collect()); dec_cmd.append(&mut config.processing.clone().settings.unwrap());
debug!( debug!(
"Decoder CMD: <bright-blue>\"ffmpeg {}\"</>", "Decoder CMD: <bright-blue>\"ffmpeg {}\"</>",

View File

@ -7,6 +7,7 @@ use simplelog::*;
use crate::filter::v_drawtext; use crate::filter::v_drawtext;
use crate::utils::{GlobalConfig, Media}; use crate::utils::{GlobalConfig, Media};
use crate::vec_strings;
/// Streaming Output /// Streaming Output
/// ///
@ -14,18 +15,18 @@ use crate::utils::{GlobalConfig, Media};
pub fn output(log_format: &str) -> process::Child { pub fn output(log_format: &str) -> process::Child {
let config = GlobalConfig::global(); let config = GlobalConfig::global();
let mut enc_filter: Vec<String> = vec![]; let mut enc_filter: Vec<String> = vec![];
let mut preview: Vec<&str> = vec![]; let mut preview: Vec<String> = vec_strings![];
let preview_cmd = config.out.preview_cmd.as_ref().unwrap().clone(); let mut preview_cmd = config.out.preview_cmd.as_ref().unwrap().clone();
let output_cmd = config.out.output_cmd.as_ref().unwrap().clone(); let mut output_cmd = config.out.output_cmd.as_ref().unwrap().clone();
let mut enc_cmd = vec![ let mut enc_cmd = vec_strings![
"-hide_banner", "-hide_banner",
"-nostats", "-nostats",
"-v", "-v",
log_format, log_format,
"-re", "-re",
"-i", "-i",
"pipe:0", "pipe:0"
]; ];
if config.text.add_text && !config.text.over_pre { if config.text.add_text && !config.text.over_pre {
@ -34,25 +35,25 @@ pub fn output(log_format: &str) -> process::Child {
config.text.bind_address config.text.bind_address
); );
let mut filter: String = "[0:v]null,".to_string(); let mut filter = "[0:v]null,".to_string();
filter.push_str(v_drawtext::filter_node(&mut Media::new(0, String::new(), false)).as_str()); filter.push_str(v_drawtext::filter_node(&mut Media::new(0, String::new(), false)).as_str());
if config.out.preview { if config.out.preview {
filter.push_str(",split=2[v_out1][v_out2]"); filter.push_str(",split=2[v_out1][v_out2]");
preview = vec!["-map", "[v_out1]", "-map", "0:a"]; preview = vec_strings!["-map", "[v_out1]", "-map", "0:a"];
preview.append(&mut preview_cmd.iter().map(String::as_str).collect()); preview.append(&mut preview_cmd);
preview.append(&mut vec!["-map", "[v_out2]", "-map", "0:a"]); preview.append(&mut vec_strings!["-map", "[v_out2]", "-map", "0:a"]);
} }
enc_filter = vec!["-filter_complex".to_string(), filter]; enc_filter = vec!["-filter_complex".to_string(), filter];
} else if config.out.preview { } else if config.out.preview {
preview = preview_cmd.iter().map(String::as_str).collect() preview = preview_cmd
} }
enc_cmd.append(&mut enc_filter.iter().map(String::as_str).collect()); enc_cmd.append(&mut enc_filter);
enc_cmd.append(&mut preview); enc_cmd.append(&mut preview);
enc_cmd.append(&mut output_cmd.iter().map(String::as_str).collect()); enc_cmd.append(&mut output_cmd);
debug!( debug!(
"Encoder CMD: <bright-blue>\"ffmpeg {}\"</>", "Encoder CMD: <bright-blue>\"ffmpeg {}\"</>",

View File

@ -11,6 +11,7 @@ use serde_yaml::{self};
use shlex::split; use shlex::split;
use crate::utils::{get_args, time_to_sec}; use crate::utils::{get_args, time_to_sec};
use crate::vec_strings;
/// Global Config /// Global Config
/// ///
@ -167,8 +168,15 @@ impl GlobalConfig {
.join("ffplayout_status.json") .join("ffplayout_status.json")
.display() .display()
.to_string(); .to_string();
let fps = config.processing.fps.to_string(); let bitrate = format!(
let bitrate = config.processing.width * config.processing.height / 10; "{}k",
config.processing.width * config.processing.height / 10
);
let buf_size = format!(
"{}k",
(config.processing.width * config.processing.height / 10) / 2
);
config.playlist.start_sec = Some(time_to_sec(&config.playlist.day_start)); config.playlist.start_sec = Some(time_to_sec(&config.playlist.day_start));
if config.playlist.length.contains(':') { if config.playlist.length.contains(':') {
@ -178,35 +186,29 @@ impl GlobalConfig {
} }
// We set the decoder settings here, so we only define them ones. // We set the decoder settings here, so we only define them ones.
let mut settings: Vec<String> = vec![ let mut settings = vec_strings![
"-pix_fmt", "-pix_fmt",
"yuv420p", "yuv420p",
"-r", "-r",
&fps, &config.processing.fps.to_string(),
"-c:v", "-c:v",
"mpeg2video", "mpeg2video",
"-g", "-g",
"1", "1",
"-b:v", "-b:v",
format!("{bitrate}k").as_str(), &bitrate,
"-minrate", "-minrate",
format!("{bitrate}k").as_str(), &bitrate,
"-maxrate", "-maxrate",
format!("{bitrate}k").as_str(), &bitrate,
"-bufsize", "-bufsize",
format!("{}k", bitrate / 2).as_str(), &buf_size
] ];
.iter()
.map(|&s| s.into())
.collect();
settings.append(&mut pre_audio_codec(config.processing.add_loudnorm)); settings.append(&mut pre_audio_codec(config.processing.add_loudnorm));
settings.append( settings.append(&mut vec_strings![
&mut vec!["-ar", "48000", "-ac", "2", "-f", "mpegts", "-"] "-ar", "48000", "-ac", "2", "-f", "mpegts", "-"
.iter() ]);
.map(|&s| s.into())
.collect(),
);
config.processing.settings = Some(settings); config.processing.settings = Some(settings);
@ -277,13 +279,13 @@ static INSTANCE: OnceCell<GlobalConfig> = OnceCell::new();
/// s302m has higher quality, but is experimental /// s302m has higher quality, but is experimental
/// and works not well together with the loudnorm filter. /// and works not well together with the loudnorm filter.
fn pre_audio_codec(add_loudnorm: bool) -> Vec<String> { fn pre_audio_codec(add_loudnorm: bool) -> Vec<String> {
let mut codec = vec!["-c:a", "s302m", "-strict", "-2"]; let mut codec = vec_strings!["-c:a", "s302m", "-strict", "-2"];
if add_loudnorm { if add_loudnorm {
codec = vec!["-c:a", "mp2", "-b:a", "384k"]; codec = vec_strings!["-c:a", "mp2", "-b:a", "384k"];
} }
codec.iter().map(|&s| s.into()).collect() codec
} }
pub fn init_config() { pub fn init_config() {

View File

@ -131,7 +131,7 @@ impl SharedLogger for LogMailer {
/// ///
/// ToDo: maybe in next version from simplelog this is not necessary anymore. /// ToDo: maybe in next version from simplelog this is not necessary anymore.
fn clean_string(text: &str) -> String { fn clean_string(text: &str) -> String {
let regex: Regex = Regex::new(r"\x1b\[[0-9;]*[mGKF]").unwrap(); let regex = Regex::new(r"\x1b\[[0-9;]*[mGKF]").unwrap();
regex.replace_all(text, "").to_string() regex.replace_all(text, "").to_string()
} }
@ -169,7 +169,7 @@ pub fn init_logging() -> Vec<Box<dyn SharedLogger>> {
let file_config = log_config let file_config = log_config
.clone() .clone()
.set_time_format_custom(format_description!( .set_time_format_custom(format_description!(
"[[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]]" "[[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:5]]"
)) ))
.build(); .build();
let mut log_path = "logs/ffplayout.log".to_string(); let mut log_path = "logs/ffplayout.log".to_string();
@ -207,7 +207,7 @@ pub fn init_logging() -> Vec<Box<dyn SharedLogger>> {
.set_level_color(Level::Warn, Some(Color::Ansi256(208))) .set_level_color(Level::Warn, Some(Color::Ansi256(208)))
.set_level_color(Level::Error, Some(Color::Ansi256(9))) .set_level_color(Level::Error, Some(Color::Ansi256(9)))
.set_time_format_custom(format_description!( .set_time_format_custom(format_description!(
"\x1b[[30;1m[[[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:4]]\x1b[[0m" "\x1b[[30;1m[[[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:5]]\x1b[[0m"
)) ))
.build(); .build();

View File

@ -35,6 +35,13 @@ pub use logging::init_logging;
use crate::filter::filter_chains; use crate::filter::filter_chains;
#[macro_export]
macro_rules! vec_strings {
($($str:expr),*) => ({
vec![$(String::from($str),)*] as Vec<String>
});
}
/// Video clip struct to hold some important states and comments for current media. /// Video clip struct to hold some important states and comments for current media.
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Media { pub struct Media {