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::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 {}\"</>",
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 {}\"</>",
|
||||||
|
@ -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 {}\"</>",
|
||||||
|
@ -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 {}\"</>",
|
||||||
|
@ -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 {}\"</>",
|
||||||
|
@ -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() {
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user