remove str/string conversions in vectors, log ingest url with match
This commit is contained in:
parent
83a8684d8e
commit
4cd6b885ff
@ -10,6 +10,7 @@ use simplelog::*;
|
||||
|
||||
use crate::filter::ingest_filter::filter_cmd;
|
||||
use crate::utils::{stderr_reader, GlobalConfig, Ingest, ProcessControl};
|
||||
use crate::vec_strings;
|
||||
|
||||
/// ffmpeg Ingest Server
|
||||
///
|
||||
@ -21,22 +22,18 @@ pub fn ingest_server(
|
||||
) -> Result<(), Error> {
|
||||
let config = GlobalConfig::global();
|
||||
let mut buffer: [u8; 65088] = [0; 65088];
|
||||
let filter_list = filter_cmd();
|
||||
|
||||
let mut server_cmd = vec!["-hide_banner", "-nostats", "-v", log_format.as_str()];
|
||||
let mut server_cmd = vec_strings!["-hide_banner", "-nostats", "-v", log_format];
|
||||
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 filter_list.iter().map(String::as_str).collect());
|
||||
server_cmd.append(&mut stream_settings.iter().map(String::as_str).collect());
|
||||
server_cmd.append(&mut stream_input.clone());
|
||||
server_cmd.append(&mut filter_cmd());
|
||||
server_cmd.append(&mut config.processing.settings.clone().unwrap());
|
||||
|
||||
let mut is_running;
|
||||
|
||||
info!(
|
||||
"Start ingest server, listening on: <b><magenta>{}</></b>",
|
||||
stream_input.last().unwrap()
|
||||
);
|
||||
if let Some(url) = stream_input.iter().find(|s| s.contains("://")) {
|
||||
info!("Start ingest server, listening on: <b><magenta>{url}</></b>",);
|
||||
};
|
||||
|
||||
debug!(
|
||||
"Server CMD: <bright-blue>\"ffmpeg {}\"</>",
|
||||
|
@ -243,7 +243,6 @@ impl Iterator for CurrentProgram {
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.playout_stat.list_init.load(Ordering::SeqCst) {
|
||||
debug!("Playlist init");
|
||||
self.check_update(true);
|
||||
|
||||
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,
|
||||
/// this we have to figure out and calculate the right length.
|
||||
fn handle_list_init(mut node: Media) -> Media {
|
||||
debug!("Playlist init");
|
||||
let (_, total_delta) = get_delta(&node.begin.unwrap());
|
||||
let mut out = node.out;
|
||||
|
||||
|
@ -4,6 +4,7 @@ use simplelog::*;
|
||||
|
||||
use crate::filter::v_drawtext;
|
||||
use crate::utils::{GlobalConfig, Media};
|
||||
use crate::vec_strings;
|
||||
|
||||
/// Desktop Output
|
||||
///
|
||||
@ -13,7 +14,7 @@ pub fn output(log_format: &str) -> process::Child {
|
||||
|
||||
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 {
|
||||
info!(
|
||||
@ -26,7 +27,7 @@ pub fn output(log_format: &str) -> process::Child {
|
||||
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!(
|
||||
"Encoder CMD: <bright-blue>\"ffplay {}\"</>",
|
||||
|
@ -33,6 +33,7 @@ use crate::utils::{
|
||||
sec_to_time, stderr_reader, Decoder, GlobalConfig, Ingest, PlayerControl, PlayoutStatus,
|
||||
ProcessControl,
|
||||
};
|
||||
use crate::vec_strings;
|
||||
|
||||
fn format_line(line: String, level: &str) -> String {
|
||||
line.replace(&format!("[{level: >5}] "), "")
|
||||
@ -44,23 +45,20 @@ fn ingest_to_hls_server(
|
||||
mut proc_control: ProcessControl,
|
||||
) -> Result<(), Error> {
|
||||
let config = GlobalConfig::global();
|
||||
let dec_settings = config.out.clone().output_cmd.unwrap();
|
||||
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();
|
||||
|
||||
server_cmd.append(&mut stream_input.iter().map(String::as_str).collect());
|
||||
server_cmd.append(&mut filter_list.iter().map(String::as_str).collect());
|
||||
server_cmd.append(&mut dec_settings.iter().map(String::as_str).collect());
|
||||
server_cmd.append(&mut stream_input.clone());
|
||||
server_cmd.append(&mut filter_cmd());
|
||||
server_cmd.append(&mut config.out.clone().output_cmd.unwrap());
|
||||
|
||||
let mut is_running;
|
||||
|
||||
info!(
|
||||
"Start ingest server, listening on: <b><magenta>{}</></b>",
|
||||
stream_input.last().unwrap()
|
||||
);
|
||||
if let Some(url) = stream_input.iter().find(|s| s.contains("://")) {
|
||||
info!("Start ingest server, listening on: <b><magenta>{url}</></b>",);
|
||||
};
|
||||
|
||||
debug!(
|
||||
"Server CMD: <bright-blue>\"ffmpeg {}\"</>",
|
||||
@ -137,7 +135,6 @@ pub fn write_hls(
|
||||
mut proc_control: ProcessControl,
|
||||
) {
|
||||
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 play_stat = playout_stat.clone();
|
||||
let proc_control_c = proc_control.clone();
|
||||
@ -158,7 +155,7 @@ pub fn write_hls(
|
||||
for node in get_source {
|
||||
*play_control.current_media.lock().unwrap() = Some(node.clone());
|
||||
|
||||
let cmd = match node.cmd {
|
||||
let mut cmd = match node.cmd {
|
||||
Some(cmd) => cmd,
|
||||
None => break,
|
||||
};
|
||||
@ -173,15 +170,15 @@ pub fn write_hls(
|
||||
node.source
|
||||
);
|
||||
|
||||
let filter = node.filter.unwrap();
|
||||
let mut dec_cmd = vec!["-hide_banner", "-nostats", "-v", ff_log_format.as_str()];
|
||||
dec_cmd.append(&mut cmd.iter().map(String::as_str).collect());
|
||||
let mut filter = node.filter.unwrap();
|
||||
let mut dec_cmd = vec_strings!["-hide_banner", "-nostats", "-v", &ff_log_format];
|
||||
dec_cmd.append(&mut cmd);
|
||||
|
||||
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!(
|
||||
"HLS writer CMD: <bright-blue>\"ffmpeg {}\"</>",
|
||||
|
@ -20,6 +20,7 @@ use crate::utils::{
|
||||
sec_to_time, stderr_reader, Decoder, Encoder, GlobalConfig, PlayerControl, PlayoutStatus,
|
||||
ProcessControl,
|
||||
};
|
||||
use crate::vec_strings;
|
||||
|
||||
/// Player
|
||||
///
|
||||
@ -36,7 +37,6 @@ pub fn player(
|
||||
mut proc_control: ProcessControl,
|
||||
) {
|
||||
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 mut buffer = [0; 65088];
|
||||
let mut live_on = false;
|
||||
@ -80,7 +80,7 @@ pub fn player(
|
||||
'source_iter: for node in get_source {
|
||||
*play_control.current_media.lock().unwrap() = Some(node.clone());
|
||||
|
||||
let cmd = match node.cmd {
|
||||
let mut cmd = match node.cmd {
|
||||
Some(cmd) => cmd,
|
||||
None => break,
|
||||
};
|
||||
@ -95,15 +95,15 @@ pub fn player(
|
||||
node.source
|
||||
);
|
||||
|
||||
let filter = node.filter.unwrap();
|
||||
let mut dec_cmd = vec!["-hide_banner", "-nostats", "-v", ff_log_format.as_str()];
|
||||
dec_cmd.append(&mut cmd.iter().map(String::as_str).collect());
|
||||
let mut filter = node.filter.unwrap();
|
||||
let mut dec_cmd = vec_strings!["-hide_banner", "-nostats", "-v", &ff_log_format];
|
||||
dec_cmd.append(&mut cmd);
|
||||
|
||||
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!(
|
||||
"Decoder CMD: <bright-blue>\"ffmpeg {}\"</>",
|
||||
|
@ -7,6 +7,7 @@ use simplelog::*;
|
||||
|
||||
use crate::filter::v_drawtext;
|
||||
use crate::utils::{GlobalConfig, Media};
|
||||
use crate::vec_strings;
|
||||
|
||||
/// Streaming Output
|
||||
///
|
||||
@ -14,18 +15,18 @@ use crate::utils::{GlobalConfig, Media};
|
||||
pub fn output(log_format: &str) -> process::Child {
|
||||
let config = GlobalConfig::global();
|
||||
let mut enc_filter: Vec<String> = vec![];
|
||||
let mut preview: Vec<&str> = vec![];
|
||||
let preview_cmd = config.out.preview_cmd.as_ref().unwrap().clone();
|
||||
let output_cmd = config.out.output_cmd.as_ref().unwrap().clone();
|
||||
let mut preview: Vec<String> = vec_strings![];
|
||||
let mut preview_cmd = config.out.preview_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",
|
||||
"-nostats",
|
||||
"-v",
|
||||
log_format,
|
||||
"-re",
|
||||
"-i",
|
||||
"pipe:0",
|
||||
"pipe:0"
|
||||
];
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
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());
|
||||
|
||||
if config.out.preview {
|
||||
filter.push_str(",split=2[v_out1][v_out2]");
|
||||
|
||||
preview = vec!["-map", "[v_out1]", "-map", "0:a"];
|
||||
preview.append(&mut preview_cmd.iter().map(String::as_str).collect());
|
||||
preview.append(&mut vec!["-map", "[v_out2]", "-map", "0:a"]);
|
||||
preview = vec_strings!["-map", "[v_out1]", "-map", "0:a"];
|
||||
preview.append(&mut preview_cmd);
|
||||
preview.append(&mut vec_strings!["-map", "[v_out2]", "-map", "0:a"]);
|
||||
}
|
||||
|
||||
enc_filter = vec!["-filter_complex".to_string(), filter];
|
||||
} 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 output_cmd.iter().map(String::as_str).collect());
|
||||
enc_cmd.append(&mut output_cmd);
|
||||
|
||||
debug!(
|
||||
"Encoder CMD: <bright-blue>\"ffmpeg {}\"</>",
|
||||
|
@ -11,6 +11,7 @@ use serde_yaml::{self};
|
||||
use shlex::split;
|
||||
|
||||
use crate::utils::{get_args, time_to_sec};
|
||||
use crate::vec_strings;
|
||||
|
||||
/// Global Config
|
||||
///
|
||||
@ -167,8 +168,15 @@ impl GlobalConfig {
|
||||
.join("ffplayout_status.json")
|
||||
.display()
|
||||
.to_string();
|
||||
let fps = config.processing.fps.to_string();
|
||||
let bitrate = config.processing.width * config.processing.height / 10;
|
||||
let bitrate = format!(
|
||||
"{}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));
|
||||
|
||||
if config.playlist.length.contains(':') {
|
||||
@ -178,35 +186,29 @@ impl GlobalConfig {
|
||||
}
|
||||
|
||||
// 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",
|
||||
"yuv420p",
|
||||
"-r",
|
||||
&fps,
|
||||
&config.processing.fps.to_string(),
|
||||
"-c:v",
|
||||
"mpeg2video",
|
||||
"-g",
|
||||
"1",
|
||||
"-b:v",
|
||||
format!("{bitrate}k").as_str(),
|
||||
&bitrate,
|
||||
"-minrate",
|
||||
format!("{bitrate}k").as_str(),
|
||||
&bitrate,
|
||||
"-maxrate",
|
||||
format!("{bitrate}k").as_str(),
|
||||
&bitrate,
|
||||
"-bufsize",
|
||||
format!("{}k", bitrate / 2).as_str(),
|
||||
]
|
||||
.iter()
|
||||
.map(|&s| s.into())
|
||||
.collect();
|
||||
&buf_size
|
||||
];
|
||||
|
||||
settings.append(&mut pre_audio_codec(config.processing.add_loudnorm));
|
||||
settings.append(
|
||||
&mut vec!["-ar", "48000", "-ac", "2", "-f", "mpegts", "-"]
|
||||
.iter()
|
||||
.map(|&s| s.into())
|
||||
.collect(),
|
||||
);
|
||||
settings.append(&mut vec_strings![
|
||||
"-ar", "48000", "-ac", "2", "-f", "mpegts", "-"
|
||||
]);
|
||||
|
||||
config.processing.settings = Some(settings);
|
||||
|
||||
@ -277,13 +279,13 @@ static INSTANCE: OnceCell<GlobalConfig> = OnceCell::new();
|
||||
/// s302m has higher quality, but is experimental
|
||||
/// and works not well together with the loudnorm filter.
|
||||
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 {
|
||||
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() {
|
||||
|
@ -131,7 +131,7 @@ impl SharedLogger for LogMailer {
|
||||
///
|
||||
/// ToDo: maybe in next version from simplelog this is not necessary anymore.
|
||||
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()
|
||||
}
|
||||
@ -169,7 +169,7 @@ pub fn init_logging() -> Vec<Box<dyn SharedLogger>> {
|
||||
let file_config = log_config
|
||||
.clone()
|
||||
.set_time_format_custom(format_description!(
|
||||
"[[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]]"
|
||||
"[[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:5]]"
|
||||
))
|
||||
.build();
|
||||
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::Error, Some(Color::Ansi256(9)))
|
||||
.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();
|
||||
|
||||
|
@ -35,6 +35,13 @@ pub use logging::init_logging;
|
||||
|
||||
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.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Media {
|
||||
|
Loading…
x
Reference in New Issue
Block a user