clean code with clippy
This commit is contained in:
parent
b48c553ced
commit
2534059ae5
@ -28,7 +28,7 @@ impl Filters {
|
|||||||
match codec_type {
|
match codec_type {
|
||||||
"audio" => match &self.audio_chain {
|
"audio" => match &self.audio_chain {
|
||||||
Some(ac) => {
|
Some(ac) => {
|
||||||
if filter.starts_with(";") || filter.starts_with("[") {
|
if filter.starts_with(';') || filter.starts_with('[') {
|
||||||
self.audio_chain = Some(format!("{ac}{filter}"))
|
self.audio_chain = Some(format!("{ac}{filter}"))
|
||||||
} else {
|
} else {
|
||||||
self.audio_chain = Some(format!("{ac},{filter}"))
|
self.audio_chain = Some(format!("{ac},{filter}"))
|
||||||
@ -46,7 +46,7 @@ impl Filters {
|
|||||||
},
|
},
|
||||||
"video" => match &self.video_chain {
|
"video" => match &self.video_chain {
|
||||||
Some(vc) => {
|
Some(vc) => {
|
||||||
if filter.starts_with(";") || filter.starts_with("[") {
|
if filter.starts_with(';') || filter.starts_with('[') {
|
||||||
self.video_chain = Some(format!("{vc}{filter}"))
|
self.video_chain = Some(format!("{vc}{filter}"))
|
||||||
} else {
|
} else {
|
||||||
self.video_chain = Some(format!("{vc},{filter}"))
|
self.video_chain = Some(format!("{vc},{filter}"))
|
||||||
@ -142,7 +142,7 @@ fn fade(node: &mut Media, chain: &mut Filters, codec_type: &str) {
|
|||||||
fn overlay(node: &mut Media, chain: &mut Filters, config: &GlobalConfig) {
|
fn overlay(node: &mut Media, chain: &mut Filters, config: &GlobalConfig) {
|
||||||
if config.processing.add_logo
|
if config.processing.add_logo
|
||||||
&& Path::new(&config.processing.logo).is_file()
|
&& Path::new(&config.processing.logo).is_file()
|
||||||
&& &node.category.clone().unwrap_or(String::new()) != "advertisement"
|
&& &node.category.clone().unwrap_or_default() != "advertisement"
|
||||||
{
|
{
|
||||||
let opacity = format!(
|
let opacity = format!(
|
||||||
"format=rgba,colorchannelmixer=aa={}",
|
"format=rgba,colorchannelmixer=aa={}",
|
||||||
@ -173,7 +173,7 @@ fn overlay(node: &mut Media, chain: &mut Filters, config: &GlobalConfig) {
|
|||||||
|
|
||||||
fn extend_video(node: &mut Media, chain: &mut Filters) {
|
fn extend_video(node: &mut Media, chain: &mut Filters) {
|
||||||
let video_streams = node.probe.clone().unwrap().video_streams.unwrap();
|
let video_streams = node.probe.clone().unwrap().video_streams.unwrap();
|
||||||
if video_streams.len() > 0 {
|
if !video_streams.is_empty() {
|
||||||
if let Some(duration) = &video_streams[0].duration {
|
if let Some(duration) = &video_streams[0].duration {
|
||||||
let duration_float = duration.clone().parse::<f64>().unwrap();
|
let duration_float = duration.clone().parse::<f64>().unwrap();
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ fn add_text(node: &mut Media, chain: &mut Filters, config: &GlobalConfig) {
|
|||||||
chain.add_filter(&filter, "video");
|
chain.add_filter(&filter, "video");
|
||||||
|
|
||||||
if let Some(filters) = &chain.video_chain {
|
if let Some(filters) = &chain.video_chain {
|
||||||
for (i, f) in filters.split(",").enumerate() {
|
for (i, f) in filters.split(',').enumerate() {
|
||||||
if f.contains("drawtext") && !config.text.text_from_filename {
|
if f.contains("drawtext") && !config.text.text_from_filename {
|
||||||
debug!("drawtext node is on index: <yellow>{i}</>");
|
debug!("drawtext node is on index: <yellow>{i}</>");
|
||||||
break;
|
break;
|
||||||
@ -211,7 +211,7 @@ fn add_text(node: &mut Media, chain: &mut Filters, config: &GlobalConfig) {
|
|||||||
|
|
||||||
fn add_audio(node: &mut Media, chain: &mut Filters) {
|
fn add_audio(node: &mut Media, chain: &mut Filters) {
|
||||||
let audio_streams = node.probe.clone().unwrap().audio_streams.unwrap();
|
let audio_streams = node.probe.clone().unwrap().audio_streams.unwrap();
|
||||||
if audio_streams.len() == 0 {
|
if audio_streams.is_empty() {
|
||||||
warn!("Clip: '{}' has no audio!", node.source);
|
warn!("Clip: '{}' has no audio!", node.source);
|
||||||
let audio = format!(
|
let audio = format!(
|
||||||
"aevalsrc=0:channel_layout=stereo:duration={}:sample_rate=48000",
|
"aevalsrc=0:channel_layout=stereo:duration={}:sample_rate=48000",
|
||||||
@ -223,7 +223,7 @@ fn add_audio(node: &mut Media, chain: &mut Filters) {
|
|||||||
|
|
||||||
fn extend_audio(node: &mut Media, chain: &mut Filters) {
|
fn extend_audio(node: &mut Media, chain: &mut Filters) {
|
||||||
let audio_streams = node.probe.clone().unwrap().audio_streams.unwrap();
|
let audio_streams = node.probe.clone().unwrap().audio_streams.unwrap();
|
||||||
if audio_streams.len() > 0 {
|
if !audio_streams.is_empty() {
|
||||||
if let Some(duration) = &audio_streams[0].duration {
|
if let Some(duration) = &audio_streams[0].duration {
|
||||||
let duration_float = duration.clone().parse::<f64>().unwrap();
|
let duration_float = duration.clone().parse::<f64>().unwrap();
|
||||||
|
|
||||||
@ -241,7 +241,7 @@ fn add_loudnorm(node: &mut Media, chain: &mut Filters, config: &GlobalConfig) {
|
|||||||
// add single pass loudnorm filter to audio line
|
// add single pass loudnorm filter to audio line
|
||||||
|
|
||||||
if node.probe.is_some()
|
if node.probe.is_some()
|
||||||
&& node.probe.clone().unwrap().audio_streams.unwrap().len() > 0
|
&& !node.probe.clone().unwrap().audio_streams.unwrap().is_empty()
|
||||||
&& config.processing.add_loudnorm
|
&& config.processing.add_loudnorm
|
||||||
{
|
{
|
||||||
let loud_filter = format!(
|
let loud_filter = format!(
|
||||||
@ -329,14 +329,14 @@ pub fn filter_chains(node: &mut Media) -> Vec<String> {
|
|||||||
let frame_per_sec = fps_calc(v_stream.r_frame_rate.clone());
|
let frame_per_sec = fps_calc(v_stream.r_frame_rate.clone());
|
||||||
|
|
||||||
deinterlace(v_stream.field_order.clone(), &mut filters);
|
deinterlace(v_stream.field_order.clone(), &mut filters);
|
||||||
pad(aspect, &mut filters, &config);
|
pad(aspect, &mut filters, config);
|
||||||
fps(frame_per_sec, &mut filters, &config);
|
fps(frame_per_sec, &mut filters, config);
|
||||||
scale(
|
scale(
|
||||||
v_stream.width.unwrap(),
|
v_stream.width.unwrap(),
|
||||||
v_stream.height.unwrap(),
|
v_stream.height.unwrap(),
|
||||||
aspect,
|
aspect,
|
||||||
&mut filters,
|
&mut filters,
|
||||||
&config,
|
config,
|
||||||
);
|
);
|
||||||
extend_video(node, &mut filters);
|
extend_video(node, &mut filters);
|
||||||
|
|
||||||
@ -344,15 +344,15 @@ pub fn filter_chains(node: &mut Media) -> Vec<String> {
|
|||||||
extend_audio(node, &mut filters);
|
extend_audio(node, &mut filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_text(node, &mut filters, &config);
|
add_text(node, &mut filters, config);
|
||||||
fade(node, &mut filters, "video".into());
|
fade(node, &mut filters, "video");
|
||||||
overlay(node, &mut filters, &config);
|
overlay(node, &mut filters, config);
|
||||||
realtime_filter(node, &mut filters, &config, "video".into());
|
realtime_filter(node, &mut filters, config, "video");
|
||||||
|
|
||||||
add_loudnorm(node, &mut filters, &config);
|
add_loudnorm(node, &mut filters, config);
|
||||||
fade(node, &mut filters, "audio".into());
|
fade(node, &mut filters, "audio");
|
||||||
audio_volume(&mut filters, &config);
|
audio_volume(&mut filters, config);
|
||||||
realtime_filter(node, &mut filters, &config, "audio".into());
|
realtime_filter(node, &mut filters, config, "audio");
|
||||||
|
|
||||||
let mut filter_cmd = vec![];
|
let mut filter_cmd = vec![];
|
||||||
let mut filter_str: String = String::new();
|
let mut filter_str: String = String::new();
|
||||||
@ -368,7 +368,7 @@ pub fn filter_chains(node: &mut Media) -> Vec<String> {
|
|||||||
|
|
||||||
if let Some(a_filters) = filters.audio_chain {
|
if let Some(a_filters) = filters.audio_chain {
|
||||||
if filter_str.len() > 10 {
|
if filter_str.len() > 10 {
|
||||||
filter_str.push_str(";")
|
filter_str.push(';')
|
||||||
}
|
}
|
||||||
filter_str.push_str(a_filters.as_str());
|
filter_str.push_str(a_filters.as_str());
|
||||||
filter_str.push_str(filters.audio_map.clone().unwrap().as_str());
|
filter_str.push_str(filters.audio_map.clone().unwrap().as_str());
|
||||||
|
@ -24,14 +24,14 @@ pub fn filter_node(node: &mut Media) -> String {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let escape = text
|
let escape = text
|
||||||
.replace("'", "'\\\\\\''")
|
.replace('\'', "'\\\\\\''")
|
||||||
.replace("%", "\\\\\\%")
|
.replace('%', "\\\\\\%")
|
||||||
.replace(":", "\\:");
|
.replace(':', "\\:");
|
||||||
filter = format!("drawtext=text='{escape}':{}{font}", config.text.style)
|
filter = format!("drawtext=text='{escape}':{}{font}", config.text.style)
|
||||||
} else {
|
} else {
|
||||||
filter = format!(
|
filter = format!(
|
||||||
"zmq=b=tcp\\\\://'{}',drawtext=text=''{font}",
|
"zmq=b=tcp\\\\://'{}',drawtext=text=''{font}",
|
||||||
config.text.bind_address.replace(":", "\\:")
|
config.text.bind_address.replace(':', "\\:")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,12 +93,9 @@ impl FolderSource {
|
|||||||
fn shuffle(&mut self) {
|
fn shuffle(&mut self) {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
self.nodes.lock().unwrap().shuffle(&mut rng);
|
self.nodes.lock().unwrap().shuffle(&mut rng);
|
||||||
let mut index: usize = 0;
|
|
||||||
|
|
||||||
for item in self.nodes.lock().unwrap().iter_mut() {
|
for (index, item) in self.nodes.lock().unwrap().iter_mut().enumerate() {
|
||||||
item.index = Some(index);
|
item.index = Some(index);
|
||||||
|
|
||||||
index += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,12 +104,9 @@ impl FolderSource {
|
|||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.sort_by(|d1, d2| d1.source.cmp(&d2.source));
|
.sort_by(|d1, d2| d1.source.cmp(&d2.source));
|
||||||
let mut index: usize = 0;
|
|
||||||
|
|
||||||
for item in self.nodes.lock().unwrap().iter_mut() {
|
for (index, item) in self.nodes.lock().unwrap().iter_mut().enumerate() {
|
||||||
item.index = Some(index);
|
item.index = Some(index);
|
||||||
|
|
||||||
index += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,9 +75,9 @@ pub fn ingest_server(
|
|||||||
config.processing.aspect
|
config.processing.aspect
|
||||||
);
|
);
|
||||||
|
|
||||||
filter.push_str(&overlay(&config));
|
filter.push_str(&overlay(config));
|
||||||
filter.push_str("[vout1]");
|
filter.push_str("[vout1]");
|
||||||
filter.push_str(audio_filter(&config).as_str());
|
filter.push_str(audio_filter(config).as_str());
|
||||||
let mut filter_list = vec![
|
let mut filter_list = vec![
|
||||||
"-filter_complex",
|
"-filter_complex",
|
||||||
&filter,
|
&filter,
|
||||||
|
@ -24,7 +24,7 @@ pub fn source_generator(
|
|||||||
playout_stat: PlayoutStatus,
|
playout_stat: PlayoutStatus,
|
||||||
is_terminated: Arc<AtomicBool>,
|
is_terminated: Arc<AtomicBool>,
|
||||||
) -> Box<dyn Iterator<Item = Media>> {
|
) -> Box<dyn Iterator<Item = Media>> {
|
||||||
let get_source = match config.processing.clone().mode.as_str() {
|
let get_source = match config.processing.mode.as_str() {
|
||||||
"folder" => {
|
"folder" => {
|
||||||
info!("Playout in folder mode");
|
info!("Playout in folder mode");
|
||||||
debug!("Monitor folder: <b><magenta>{}</></b>", &config.storage.path);
|
debug!("Monitor folder: <b><magenta>{}</></b>", &config.storage.path);
|
||||||
@ -41,7 +41,7 @@ pub fn source_generator(
|
|||||||
info!("Playout in playlist mode");
|
info!("Playout in playlist mode");
|
||||||
let program = CurrentProgram::new(
|
let program = CurrentProgram::new(
|
||||||
playout_stat,
|
playout_stat,
|
||||||
is_terminated.clone(),
|
is_terminated,
|
||||||
current_list,
|
current_list,
|
||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
|
@ -128,10 +128,10 @@ impl CurrentProgram {
|
|||||||
let start_sec = self.config.playlist.start_sec.unwrap();
|
let start_sec = self.config.playlist.start_sec.unwrap();
|
||||||
let target_length = self.config.playlist.length_sec.unwrap();
|
let target_length = self.config.playlist.length_sec.unwrap();
|
||||||
let (delta, total_delta) = get_delta(¤t_time);
|
let (delta, total_delta) = get_delta(¤t_time);
|
||||||
let mut duration = self.current_node.out.clone();
|
let mut duration = self.current_node.out;
|
||||||
|
|
||||||
if self.current_node.duration > self.current_node.out {
|
if self.current_node.duration > self.current_node.out {
|
||||||
duration = self.current_node.duration.clone()
|
duration = self.current_node.duration
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_start = self.current_node.begin.unwrap() - start_sec + duration + delta;
|
let next_start = self.current_node.begin.unwrap() - start_sec + duration + delta;
|
||||||
@ -172,22 +172,14 @@ impl CurrentProgram {
|
|||||||
let current_list = self.nodes.lock().unwrap();
|
let current_list = self.nodes.lock().unwrap();
|
||||||
|
|
||||||
if index + 1 < current_list.len()
|
if index + 1 < current_list.len()
|
||||||
&& ¤t_list[index + 1]
|
&& ¤t_list[index + 1].category.clone().unwrap_or_default() == "advertisement"
|
||||||
.category
|
|
||||||
.clone()
|
|
||||||
.unwrap_or(String::new())
|
|
||||||
== "advertisement"
|
|
||||||
{
|
{
|
||||||
self.current_node.next_ad = Some(true);
|
self.current_node.next_ad = Some(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if index > 0
|
if index > 0
|
||||||
&& index < current_list.len()
|
&& index < current_list.len()
|
||||||
&& ¤t_list[index - 1]
|
&& ¤t_list[index - 1].category.clone().unwrap_or_default() == "advertisement"
|
||||||
.category
|
|
||||||
.clone()
|
|
||||||
.unwrap_or(String::new())
|
|
||||||
== "advertisement"
|
|
||||||
{
|
{
|
||||||
self.current_node.last_ad = Some(true);
|
self.current_node.last_ad = Some(true);
|
||||||
}
|
}
|
||||||
@ -295,7 +287,8 @@ impl Iterator for CurrentProgram {
|
|||||||
|
|
||||||
self.current_node = gen_source(media);
|
self.current_node = gen_source(media);
|
||||||
self.nodes.lock().unwrap().push(self.current_node.clone());
|
self.nodes.lock().unwrap().push(self.current_node.clone());
|
||||||
self.index.store(self.nodes.lock().unwrap().len(), Ordering::SeqCst);
|
self.index
|
||||||
|
.store(self.nodes.lock().unwrap().len(), Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,7 +321,7 @@ impl Iterator for CurrentProgram {
|
|||||||
Some(self.current_node.clone())
|
Some(self.current_node.clone())
|
||||||
} else {
|
} else {
|
||||||
let last_playlist = self.json_path.clone();
|
let last_playlist = self.json_path.clone();
|
||||||
let last_ad = self.current_node.last_ad.clone();
|
let last_ad = self.current_node.last_ad;
|
||||||
self.check_for_next_playlist();
|
self.check_for_next_playlist();
|
||||||
let (_, total_delta) = get_delta(&self.config.playlist.start_sec.unwrap());
|
let (_, total_delta) = get_delta(&self.config.playlist.start_sec.unwrap());
|
||||||
|
|
||||||
@ -386,7 +379,7 @@ fn timed_source(
|
|||||||
let mut new_node = node.clone();
|
let mut new_node = node.clone();
|
||||||
new_node.process = Some(false);
|
new_node.process = Some(false);
|
||||||
|
|
||||||
if config.playlist.length.contains(":") {
|
if config.playlist.length.contains(':') {
|
||||||
let time_shift = playout_stat.time_shift.lock().unwrap();
|
let time_shift = playout_stat.time_shift.lock().unwrap();
|
||||||
|
|
||||||
if *playout_stat.current_date.lock().unwrap() == *playout_stat.date.lock().unwrap()
|
if *playout_stat.current_date.lock().unwrap() == *playout_stat.date.lock().unwrap()
|
||||||
@ -412,7 +405,7 @@ fn timed_source(
|
|||||||
|
|
||||||
if (total_delta > node.out - node.seek && !last)
|
if (total_delta > node.out - node.seek && !last)
|
||||||
|| node.index.unwrap() < 2
|
|| node.index.unwrap() < 2
|
||||||
|| !config.playlist.length.contains(":")
|
|| !config.playlist.length.contains(':')
|
||||||
{
|
{
|
||||||
// when we are in the 24 hour range, get the clip
|
// when we are in the 24 hour range, get the clip
|
||||||
new_node = gen_source(node);
|
new_node = gen_source(node);
|
||||||
@ -466,9 +459,7 @@ fn handle_list_init(mut node: Media) -> Media {
|
|||||||
}
|
}
|
||||||
|
|
||||||
node.out = out;
|
node.out = out;
|
||||||
|
gen_source(node)
|
||||||
let new_node = gen_source(node);
|
|
||||||
new_node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// when we come to last clip in playlist,
|
/// when we come to last clip in playlist,
|
||||||
|
@ -62,7 +62,6 @@ pub fn json_rpc_server(
|
|||||||
) {
|
) {
|
||||||
let config = GlobalConfig::global();
|
let config = GlobalConfig::global();
|
||||||
let mut io = IoHandler::default();
|
let mut io = IoHandler::default();
|
||||||
let play = play_control.clone();
|
|
||||||
let proc = proc_control.clone();
|
let proc = proc_control.clone();
|
||||||
|
|
||||||
io.add_sync_method("player", move |params: Params| {
|
io.add_sync_method("player", move |params: Params| {
|
||||||
@ -73,9 +72,9 @@ pub fn json_rpc_server(
|
|||||||
|
|
||||||
// get next clip
|
// get next clip
|
||||||
if map.contains_key("control") && &map["control"] == "next" {
|
if map.contains_key("control") && &map["control"] == "next" {
|
||||||
let index = play.index.load(Ordering::SeqCst);
|
let index = play_control.index.load(Ordering::SeqCst);
|
||||||
|
|
||||||
if index < play.current_list.lock().unwrap().len() {
|
if index < play_control.current_list.lock().unwrap().len() {
|
||||||
if let Some(proc) = proc.decoder_term.lock().unwrap().as_mut() {
|
if let Some(proc) = proc.decoder_term.lock().unwrap().as_mut() {
|
||||||
if let Err(e) = proc.kill() {
|
if let Err(e) = proc.kill() {
|
||||||
error!("Decoder {e:?}")
|
error!("Decoder {e:?}")
|
||||||
@ -88,7 +87,7 @@ pub fn json_rpc_server(
|
|||||||
info!("Move to next clip");
|
info!("Move to next clip");
|
||||||
|
|
||||||
let mut data_map = Map::new();
|
let mut data_map = Map::new();
|
||||||
let mut media = play.current_list.lock().unwrap()[index].clone();
|
let mut media = play_control.current_list.lock().unwrap()[index].clone();
|
||||||
media.add_probe();
|
media.add_probe();
|
||||||
|
|
||||||
let (delta, _) = get_delta(&media.begin.unwrap_or(0.0));
|
let (delta, _) = get_delta(&media.begin.unwrap_or(0.0));
|
||||||
@ -111,9 +110,9 @@ pub fn json_rpc_server(
|
|||||||
|
|
||||||
// get last clip
|
// get last clip
|
||||||
if map.contains_key("control") && &map["control"] == "back" {
|
if map.contains_key("control") && &map["control"] == "back" {
|
||||||
let index = play.index.load(Ordering::SeqCst);
|
let index = play_control.index.load(Ordering::SeqCst);
|
||||||
|
|
||||||
if index > 1 && play.current_list.lock().unwrap().len() > 1 {
|
if index > 1 && play_control.current_list.lock().unwrap().len() > 1 {
|
||||||
if let Some(proc) = proc.decoder_term.lock().unwrap().as_mut() {
|
if let Some(proc) = proc.decoder_term.lock().unwrap().as_mut() {
|
||||||
if let Err(e) = proc.kill() {
|
if let Err(e) = proc.kill() {
|
||||||
error!("Decoder {e:?}")
|
error!("Decoder {e:?}")
|
||||||
@ -125,8 +124,8 @@ pub fn json_rpc_server(
|
|||||||
|
|
||||||
info!("Move to last clip");
|
info!("Move to last clip");
|
||||||
let mut data_map = Map::new();
|
let mut data_map = Map::new();
|
||||||
let mut media = play.current_list.lock().unwrap()[index - 2].clone();
|
let mut media = play_control.current_list.lock().unwrap()[index - 2].clone();
|
||||||
play.index.fetch_sub(2, Ordering::SeqCst);
|
play_control.index.fetch_sub(2, Ordering::SeqCst);
|
||||||
media.add_probe();
|
media.add_probe();
|
||||||
|
|
||||||
let (delta, _) = get_delta(&media.begin.unwrap_or(0.0));
|
let (delta, _) = get_delta(&media.begin.unwrap_or(0.0));
|
||||||
@ -176,7 +175,7 @@ pub fn json_rpc_server(
|
|||||||
|
|
||||||
// get infos about current clip
|
// get infos about current clip
|
||||||
if map.contains_key("media") && &map["media"] == "current" {
|
if map.contains_key("media") && &map["media"] == "current" {
|
||||||
if let Some(media) = play.current_media.lock().unwrap().clone() {
|
if let Some(media) = play_control.current_media.lock().unwrap().clone() {
|
||||||
let data_map = get_data_map(config, media);
|
let data_map = get_data_map(config, media);
|
||||||
|
|
||||||
return Ok(Value::Object(data_map));
|
return Ok(Value::Object(data_map));
|
||||||
@ -185,10 +184,10 @@ pub fn json_rpc_server(
|
|||||||
|
|
||||||
// get infos about next clip
|
// get infos about next clip
|
||||||
if map.contains_key("media") && &map["media"] == "next" {
|
if map.contains_key("media") && &map["media"] == "next" {
|
||||||
let index = play.index.load(Ordering::SeqCst);
|
let index = play_control.index.load(Ordering::SeqCst);
|
||||||
|
|
||||||
if index < play.current_list.lock().unwrap().len() {
|
if index < play_control.current_list.lock().unwrap().len() {
|
||||||
let media = play.current_list.lock().unwrap()[index].clone();
|
let media = play_control.current_list.lock().unwrap()[index].clone();
|
||||||
|
|
||||||
let data_map = get_data_map(config, media);
|
let data_map = get_data_map(config, media);
|
||||||
|
|
||||||
@ -200,10 +199,10 @@ pub fn json_rpc_server(
|
|||||||
|
|
||||||
// get infos about last clip
|
// get infos about last clip
|
||||||
if map.contains_key("media") && &map["media"] == "last" {
|
if map.contains_key("media") && &map["media"] == "last" {
|
||||||
let index = play.index.load(Ordering::SeqCst);
|
let index = play_control.index.load(Ordering::SeqCst);
|
||||||
|
|
||||||
if index > 1 && index - 2 < play.current_list.lock().unwrap().len() {
|
if index > 1 && index - 2 < play_control.current_list.lock().unwrap().len() {
|
||||||
let media = play.current_list.lock().unwrap()[index - 2].clone();
|
let media = play_control.current_list.lock().unwrap()[index - 2].clone();
|
||||||
|
|
||||||
let data_map = get_data_map(config, media);
|
let data_map = get_data_map(config, media);
|
||||||
|
|
||||||
@ -241,7 +240,7 @@ pub fn json_rpc_server(
|
|||||||
.start_http(&config.rpc_server.address.parse().unwrap())
|
.start_http(&config.rpc_server.address.parse().unwrap())
|
||||||
.expect("Unable to start RPC server");
|
.expect("Unable to start RPC server");
|
||||||
|
|
||||||
*proc_control.rpc_handle.lock().unwrap() = Some(server.close_handle().clone());
|
*proc_control.rpc_handle.lock().unwrap() = Some(server.close_handle());
|
||||||
|
|
||||||
server.wait();
|
server.wait();
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,5 @@ pub struct Args {
|
|||||||
|
|
||||||
/// Get arguments from command line, and return them.
|
/// Get arguments from command line, and return them.
|
||||||
pub fn get_args() -> Args {
|
pub fn get_args() -> Args {
|
||||||
let args = Args::parse();
|
Args::parse()
|
||||||
|
|
||||||
args
|
|
||||||
}
|
}
|
||||||
|
@ -153,8 +153,7 @@ impl GlobalConfig {
|
|||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!(
|
println!(
|
||||||
"{config_path:?} doesn't exists!\n{}\n\nSystem error: {err}",
|
"{config_path:?} doesn't exists!\nPut \"ffplayout.yml\" in \"/etc/playout/\" or beside the executable!\n\nSystem error: {err}"
|
||||||
"Put \"ffplayout.yml\" in \"/etc/playout/\" or beside the executable!"
|
|
||||||
);
|
);
|
||||||
process::exit(0x0100);
|
process::exit(0x0100);
|
||||||
}
|
}
|
||||||
@ -171,7 +170,7 @@ impl GlobalConfig {
|
|||||||
let bitrate = config.processing.width * config.processing.height / 10;
|
let bitrate = config.processing.width * config.processing.height / 10;
|
||||||
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(':') {
|
||||||
config.playlist.length_sec = Some(time_to_sec(&config.playlist.length));
|
config.playlist.length_sec = Some(time_to_sec(&config.playlist.length));
|
||||||
} else {
|
} else {
|
||||||
config.playlist.length_sec = Some(86400.0);
|
config.playlist.length_sec = Some(86400.0);
|
||||||
@ -244,7 +243,7 @@ impl GlobalConfig {
|
|||||||
if let Some(length) = args.length {
|
if let Some(length) = args.length {
|
||||||
config.playlist.length = length.clone();
|
config.playlist.length = length.clone();
|
||||||
|
|
||||||
if length.contains(":") {
|
if length.contains(':') {
|
||||||
config.playlist.length_sec = Some(time_to_sec(&length));
|
config.playlist.length_sec = Some(time_to_sec(&length));
|
||||||
} else {
|
} else {
|
||||||
config.playlist.length_sec = Some(86400.0);
|
config.playlist.length_sec = Some(86400.0);
|
||||||
|
@ -22,30 +22,24 @@ use crate::utils::{json_serializer::Playlist, GlobalConfig, Media};
|
|||||||
|
|
||||||
|
|
||||||
/// Generate a vector with dates, from given range.
|
/// Generate a vector with dates, from given range.
|
||||||
fn get_date_range(date_range: &Vec<String>) -> Vec<String> {
|
fn get_date_range(date_range: &[String]) -> Vec<String> {
|
||||||
let mut range = vec![];
|
let mut range = vec![];
|
||||||
let start;
|
|
||||||
let end;
|
|
||||||
|
|
||||||
match NaiveDate::parse_from_str(&date_range[0], "%Y-%m-%d") {
|
let start = match NaiveDate::parse_from_str(&date_range[0], "%Y-%m-%d") {
|
||||||
Ok(s) => {
|
Ok(s) => s,
|
||||||
start = s;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
error!("date format error in: <yellow>{:?}</>", date_range[0]);
|
error!("date format error in: <yellow>{:?}</>", date_range[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
match NaiveDate::parse_from_str(&date_range[2], "%Y-%m-%d") {
|
let end = match NaiveDate::parse_from_str(&date_range[2], "%Y-%m-%d") {
|
||||||
Ok(e) => {
|
Ok(e) => e,
|
||||||
end = e;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
error!("date format error in: <yellow>{:?}</>", date_range[2]);
|
error!("date format error in: <yellow>{:?}</>", date_range[2]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
let duration = end.signed_duration_since(start);
|
let duration = end.signed_duration_since(start);
|
||||||
let days = duration.num_days() + 1;
|
let days = duration.num_days() + 1;
|
||||||
@ -60,7 +54,7 @@ fn get_date_range(date_range: &Vec<String>) -> Vec<String> {
|
|||||||
/// Generate playlists
|
/// Generate playlists
|
||||||
pub fn generate_playlist(mut date_range: Vec<String>) {
|
pub fn generate_playlist(mut date_range: Vec<String>) {
|
||||||
let config = GlobalConfig::global();
|
let config = GlobalConfig::global();
|
||||||
let total_length = config.playlist.length_sec.unwrap().clone();
|
let total_length = config.playlist.length_sec.unwrap();
|
||||||
let current_list = Arc::new(Mutex::new(vec![Media::new(0, "".to_string(), false)]));
|
let current_list = Arc::new(Mutex::new(vec![Media::new(0, "".to_string(), false)]));
|
||||||
let index = Arc::new(AtomicUsize::new(0));
|
let index = Arc::new(AtomicUsize::new(0));
|
||||||
let playlist_root = Path::new(&config.playlist.path);
|
let playlist_root = Path::new(&config.playlist.path);
|
||||||
@ -108,7 +102,7 @@ pub fn generate_playlist(mut date_range: Vec<String>) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut filler = Media::new(0, config.storage.filler_clip.clone(), true);
|
let mut filler = Media::new(0, config.storage.filler_clip.clone(), true);
|
||||||
let filler_length = filler.duration.clone();
|
let filler_length = filler.duration;
|
||||||
let mut length = 0.0;
|
let mut length = 0.0;
|
||||||
let mut round = 0;
|
let mut round = 0;
|
||||||
|
|
||||||
@ -121,7 +115,7 @@ pub fn generate_playlist(mut date_range: Vec<String>) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for item in media_list.clone() {
|
for item in media_list.clone() {
|
||||||
let duration = item.duration.clone();
|
let duration = item.duration;
|
||||||
|
|
||||||
if total_length > length + duration {
|
if total_length > length + duration {
|
||||||
playlist.program.push(item);
|
playlist.program.push(item);
|
||||||
|
@ -92,7 +92,7 @@ pub fn read_json(
|
|||||||
serde_json::from_reader(f).expect("Could not read json playlist file.");
|
serde_json::from_reader(f).expect("Could not read json playlist file.");
|
||||||
|
|
||||||
playlist.current_file = Some(current_file.clone());
|
playlist.current_file = Some(current_file.clone());
|
||||||
playlist.start_sec = Some(start_sec.clone());
|
playlist.start_sec = Some(start_sec);
|
||||||
let modify = modified_time(¤t_file);
|
let modify = modified_time(¤t_file);
|
||||||
|
|
||||||
if let Some(modi) = modify {
|
if let Some(modi) = modify {
|
||||||
|
@ -152,7 +152,7 @@ pub fn init_logging() -> Vec<Box<dyn SharedLogger>> {
|
|||||||
time_level = LevelFilter::Error;
|
time_level = LevelFilter::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
let log_config = simplelog::ConfigBuilder::new()
|
let mut log_config = simplelog::ConfigBuilder::new()
|
||||||
.set_thread_level(LevelFilter::Off)
|
.set_thread_level(LevelFilter::Off)
|
||||||
.set_target_level(LevelFilter::Off)
|
.set_target_level(LevelFilter::Off)
|
||||||
.set_level_padding(LevelPadding::Left)
|
.set_level_padding(LevelPadding::Left)
|
||||||
@ -210,14 +210,14 @@ pub fn init_logging() -> Vec<Box<dyn SharedLogger>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set mail logger only the recipient is set in config
|
// set mail logger only the recipient is set in config
|
||||||
if config.mail.recipient.contains("@") && config.mail.recipient.contains(".") {
|
if config.mail.recipient.contains('@') && config.mail.recipient.contains('.') {
|
||||||
let messages: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
|
let messages: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
|
||||||
let messages_clone = messages.clone();
|
let messages_clone = messages.clone();
|
||||||
let interval = config.mail.interval.clone();
|
let interval = config.mail.interval;
|
||||||
|
|
||||||
thread::spawn(move || mail_queue(messages_clone, interval));
|
thread::spawn(move || mail_queue(messages_clone, interval));
|
||||||
|
|
||||||
let mail_config = log_config.clone().build();
|
let mail_config = log_config.build();
|
||||||
|
|
||||||
let filter = match config.mail.mail_level.to_lowercase().as_str() {
|
let filter = match config.mail.mail_level.to_lowercase().as_str() {
|
||||||
"info" => LevelFilter::Info,
|
"info" => LevelFilter::Info,
|
||||||
|
@ -90,12 +90,12 @@ impl Media {
|
|||||||
index: Some(index),
|
index: Some(index),
|
||||||
seek: 0.0,
|
seek: 0.0,
|
||||||
out: duration,
|
out: duration,
|
||||||
duration: duration,
|
duration,
|
||||||
category: None,
|
category: None,
|
||||||
source: src.clone(),
|
source: src.clone(),
|
||||||
cmd: Some(vec!["-i".to_string(), src]),
|
cmd: Some(vec!["-i".to_string(), src]),
|
||||||
filter: Some(vec![]),
|
filter: Some(vec![]),
|
||||||
probe: probe,
|
probe,
|
||||||
last_ad: Some(false),
|
last_ad: Some(false),
|
||||||
next_ad: Some(false),
|
next_ad: Some(false),
|
||||||
process: Some(true),
|
process: Some(true),
|
||||||
@ -125,7 +125,6 @@ impl Media {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// We use the ffprobe crate, but we map the metadata to our needs.
|
/// We use the ffprobe crate, but we map the metadata to our needs.
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct MediaProbe {
|
pub struct MediaProbe {
|
||||||
@ -161,12 +160,12 @@ impl MediaProbe {
|
|||||||
|
|
||||||
MediaProbe {
|
MediaProbe {
|
||||||
format: Some(obj.format),
|
format: Some(obj.format),
|
||||||
audio_streams: if a_stream.len() > 0 {
|
audio_streams: if !a_stream.is_empty() {
|
||||||
Some(a_stream)
|
Some(a_stream)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
video_streams: if v_stream.len() > 0 {
|
video_streams: if !v_stream.is_empty() {
|
||||||
Some(v_stream)
|
Some(v_stream)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -252,7 +251,7 @@ pub fn modified_time(path: &str) -> Option<DateTime<Local>> {
|
|||||||
|
|
||||||
/// Convert a formatted time string to seconds.
|
/// Convert a formatted time string to seconds.
|
||||||
pub fn time_to_sec(time_str: &str) -> f64 {
|
pub fn time_to_sec(time_str: &str) -> f64 {
|
||||||
if ["now", "", "none"].contains(&time_str) || !time_str.contains(":") {
|
if ["now", "", "none"].contains(&time_str) || !time_str.contains(':') {
|
||||||
return get_sec();
|
return get_sec();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +292,6 @@ pub fn get_delta(begin: &f64) -> (f64, f64) {
|
|||||||
let start = config.playlist.start_sec.unwrap();
|
let start = config.playlist.start_sec.unwrap();
|
||||||
let length = time_to_sec(&config.playlist.length);
|
let length = time_to_sec(&config.playlist.length);
|
||||||
let mut target_length = 86400.0;
|
let mut target_length = 86400.0;
|
||||||
let total_delta;
|
|
||||||
|
|
||||||
if length > 0.0 && length != target_length {
|
if length > 0.0 && length != target_length {
|
||||||
target_length = length
|
target_length = length
|
||||||
@ -310,11 +308,11 @@ pub fn get_delta(begin: &f64) -> (f64, f64) {
|
|||||||
current_delta -= 86400.0
|
current_delta -= 86400.0
|
||||||
}
|
}
|
||||||
|
|
||||||
if current_time < start {
|
let total_delta = if current_time < start {
|
||||||
total_delta = start - current_time;
|
start - current_time
|
||||||
} else {
|
} else {
|
||||||
total_delta = target_length + start - current_time;
|
target_length + start - current_time
|
||||||
}
|
};
|
||||||
|
|
||||||
(current_delta, total_delta)
|
(current_delta, total_delta)
|
||||||
}
|
}
|
||||||
@ -369,7 +367,7 @@ pub fn seek_and_length(src: String, seek: f64, out: f64, duration: f64) -> Vec<S
|
|||||||
if duration > out {
|
if duration > out {
|
||||||
source_cmd.append(&mut vec![
|
source_cmd.append(&mut vec![
|
||||||
"-t".to_string(),
|
"-t".to_string(),
|
||||||
format!("{}", out - seek).to_string(),
|
format!("{}", out - seek),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,16 +391,14 @@ pub fn stderr_reader(buffer: BufReader<ChildStderr>, suffix: &str) -> Result<(),
|
|||||||
"<bright black>[{suffix}]</> {}",
|
"<bright black>[{suffix}]</> {}",
|
||||||
format_line(line, "warning")
|
format_line(line, "warning")
|
||||||
)
|
)
|
||||||
} else {
|
} else if suffix != "server"
|
||||||
if suffix != "server"
|
&& !line.contains("Input/output error")
|
||||||
&& !line.contains("Input/output error")
|
&& !line.contains("Broken pipe")
|
||||||
&& !line.contains("Broken pipe")
|
{
|
||||||
{
|
error!(
|
||||||
error!(
|
"<bright black>[{suffix}]</> {}",
|
||||||
"<bright black>[{suffix}]</> {}",
|
format_line(line.clone(), "error")
|
||||||
format_line(line.clone(), "error")
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,15 +446,13 @@ fn ffmpeg_libs_and_filter() -> (Vec<String>, Vec<String>) {
|
|||||||
|
|
||||||
// stderr shows only the ffmpeg configuration
|
// stderr shows only the ffmpeg configuration
|
||||||
// get codec library's
|
// get codec library's
|
||||||
for line in err_buffer.lines() {
|
for line in err_buffer.lines().flatten() {
|
||||||
if let Ok(line) = line {
|
if line.contains("configuration:") {
|
||||||
if line.contains("configuration:") {
|
let configs = line.split_whitespace();
|
||||||
let configs = line.split_whitespace();
|
|
||||||
|
|
||||||
for config in configs {
|
for config in configs {
|
||||||
if config.contains("--enable-lib") {
|
if config.contains("--enable-lib") {
|
||||||
libs.push(config.replace("--enable-", ""));
|
libs.push(config.replace("--enable-", ""));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,13 +460,11 @@ fn ffmpeg_libs_and_filter() -> (Vec<String>, Vec<String>) {
|
|||||||
|
|
||||||
// stdout shows filter help text
|
// stdout shows filter help text
|
||||||
// get filters
|
// get filters
|
||||||
for line in out_buffer.lines() {
|
for line in out_buffer.lines().flatten() {
|
||||||
if let Ok(line) = line {
|
if re.captures(line.as_str()).is_some() {
|
||||||
if let Some(_) = re.captures(line.as_str()) {
|
let filter_line = line.split_whitespace();
|
||||||
let filter_line = line.split_whitespace();
|
|
||||||
|
|
||||||
filters.push(filter_line.collect::<Vec<&str>>()[1].to_string());
|
filters.push(filter_line.collect::<Vec<&str>>()[1].to_string());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user