check if file exists, check sync
This commit is contained in:
parent
30348f6b66
commit
c7aec5b594
@ -1,8 +1,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fs::File, path::Path};
|
||||
|
||||
use crate::utils::Config;
|
||||
use crate::utils::{get_date, get_sec, modified_time, MediaProbe};
|
||||
use crate::utils::{get_date, get_sec, modified_time, time_to_sec, Config, MediaProbe};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Playlist {
|
||||
@ -34,11 +33,7 @@ pub fn read_json(config: &Config, seek: bool) -> Playlist {
|
||||
let mut playlist_path = Path::new(&config.playlist.path).to_owned();
|
||||
let start = &config.playlist.day_start;
|
||||
let length = &config.playlist.length;
|
||||
let t: Vec<&str> = start.split(':').collect();
|
||||
let h: f64 = t[0].parse().unwrap();
|
||||
let m: f64 = t[1].parse().unwrap();
|
||||
let s: f64 = t[2].parse().unwrap();
|
||||
let mut start_sec = h * 3600.0 + m * 60.0 + s;
|
||||
let mut start_sec = time_to_sec(start);
|
||||
let mut length_sec: f64 = 86400.0;
|
||||
let mut seek_first = seek;
|
||||
|
||||
@ -55,11 +50,7 @@ pub fn read_json(config: &Config, seek: bool) -> Playlist {
|
||||
let current_file: String = playlist_path.as_path().display().to_string();
|
||||
|
||||
if length.contains(":") {
|
||||
let t: Vec<&str> = length.split(':').collect();
|
||||
let h: f64 = t[0].parse().unwrap();
|
||||
let m: f64 = t[1].parse().unwrap();
|
||||
let s: f64 = t[2].parse().unwrap();
|
||||
length_sec = h * 3600.0 + m * 60.0 + s;
|
||||
length_sec = time_to_sec(length);
|
||||
}
|
||||
|
||||
println!("Read Playlist: {}", ¤t_file);
|
||||
@ -86,10 +77,18 @@ pub fn read_json(config: &Config, seek: bool) -> Playlist {
|
||||
item.index = Some(i);
|
||||
let mut source_cmd: Vec<String> = vec![];
|
||||
|
||||
if seek_first && start_sec + item.out - item.seek > time_sec {
|
||||
seek_first = false;
|
||||
playlist.start_index = Some(i);
|
||||
item.seek = time_sec - start_sec;
|
||||
if seek_first {
|
||||
let tmp_length = item.out - item.seek;
|
||||
|
||||
if start_sec + item.out - item.seek > time_sec {
|
||||
seek_first = false;
|
||||
playlist.start_index = Some(i);
|
||||
|
||||
item.seek = time_sec - start_sec;
|
||||
}
|
||||
start_sec += tmp_length;
|
||||
} else {
|
||||
start_sec += item.out - item.seek;
|
||||
}
|
||||
|
||||
if item.seek > 0.0 {
|
||||
@ -111,7 +110,6 @@ pub fn read_json(config: &Config, seek: bool) -> Playlist {
|
||||
}
|
||||
|
||||
item.cmd = Some(source_cmd);
|
||||
start_sec += item.out - item.seek;
|
||||
}
|
||||
|
||||
// println!("{:#?}", playlist);
|
||||
|
@ -2,9 +2,7 @@ use chrono::prelude::*;
|
||||
use chrono::Duration;
|
||||
use ffprobe::{ffprobe, Format, Stream};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::metadata;
|
||||
use std::time::{UNIX_EPOCH};
|
||||
use std::time;
|
||||
use std::{fs::metadata, process, time, time::UNIX_EPOCH};
|
||||
|
||||
mod arg_parse;
|
||||
mod config;
|
||||
@ -20,9 +18,9 @@ pub use playlist::program;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct MediaProbe {
|
||||
pub format: Option<Format>,
|
||||
pub audio_streams: Option<Vec<Stream>>,
|
||||
pub video_streams: Option<Vec<Stream>>,
|
||||
pub format: Option<Format>,
|
||||
pub audio_streams: Option<Vec<Stream>>,
|
||||
pub video_streams: Option<Vec<Stream>>,
|
||||
}
|
||||
|
||||
impl MediaProbe {
|
||||
@ -52,8 +50,16 @@ impl MediaProbe {
|
||||
|
||||
MediaProbe {
|
||||
format: Some(obj.format),
|
||||
audio_streams: if a_stream.len() > 0 {Some(a_stream)} else {None},
|
||||
video_streams: if v_stream.len() > 0 {Some(v_stream)} else {None},
|
||||
audio_streams: if a_stream.len() > 0 {
|
||||
Some(a_stream)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
video_streams: if v_stream.len() > 0 {
|
||||
Some(v_stream)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
@ -111,6 +117,19 @@ pub fn modified_time(path: String) -> Option<DateTime<Local>> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn time_to_sec(time_str: &String) -> f64 {
|
||||
if ["now", "", "none"].contains(&time_str.as_str()) || !time_str.contains(":") {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
let t: Vec<&str> = time_str.split(':').collect();
|
||||
let h: f64 = t[0].parse().unwrap();
|
||||
let m: f64 = t[1].parse().unwrap();
|
||||
let s: f64 = t[2].parse().unwrap();
|
||||
|
||||
h * 3600.0 + m * 60.0 + s
|
||||
}
|
||||
|
||||
pub fn sec_to_time(sec: f64) -> String {
|
||||
let d = UNIX_EPOCH + time::Duration::from_secs(sec as u64);
|
||||
// Create DateTime from SystemTime
|
||||
@ -120,9 +139,64 @@ pub fn sec_to_time(sec: f64) -> String {
|
||||
}
|
||||
|
||||
pub fn is_close(a: f64, b: f64, to: f64) -> bool {
|
||||
if (a - b).abs() > to {
|
||||
return true
|
||||
if (a - b).abs() < to {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub fn get_delta(begin: &f64, config: &Config) -> f64 {
|
||||
let mut current_time = get_sec();
|
||||
let start = time_to_sec(&config.playlist.day_start);
|
||||
let length = time_to_sec(&config.playlist.length);
|
||||
let mut target_length = 86400.0;
|
||||
|
||||
if length > 0.0 && length != target_length {
|
||||
target_length = length
|
||||
}
|
||||
|
||||
if begin == &start && start == 0.0 && 86400.0 - current_time < 4.0 {
|
||||
current_time -= target_length
|
||||
} else if start >= current_time && begin != &start {
|
||||
current_time += target_length
|
||||
}
|
||||
|
||||
let mut current_delta = begin - current_time;
|
||||
|
||||
if is_close(current_delta, 86400.0, config.general.stop_threshold) {
|
||||
current_delta -= 86400.0
|
||||
}
|
||||
|
||||
current_delta
|
||||
}
|
||||
|
||||
pub fn check_sync(delta: f64, config: &Config) {
|
||||
if delta.abs() > config.general.stop_threshold && config.general.stop_threshold > 0.0 {
|
||||
println!("Start time out of sync for '{}' seconds", delta);
|
||||
process::exit(0x0100);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gen_dummy(duration: f64, config: &Config) -> (String, Vec<String>) {
|
||||
let color = "#121212";
|
||||
let source = format!(
|
||||
"color=c={color}:s={}x{}:d={duration}",
|
||||
config.processing.width, config.processing.height
|
||||
);
|
||||
let cmd: Vec<String> = vec![
|
||||
"-f".to_string(),
|
||||
"lavfi".to_string(),
|
||||
"-i".to_string(),
|
||||
format!(
|
||||
"{source}:r={},format=pix_fmts=yuv420p",
|
||||
config.processing.fps
|
||||
),
|
||||
"-f".to_string(),
|
||||
"lavfi".to_string(),
|
||||
"-i".to_string(),
|
||||
format!("anoisesrc=d={duration}:c=pink:r=48000:a=0.05"),
|
||||
];
|
||||
|
||||
(source, cmd)
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
use std::path::Path;
|
||||
|
||||
use crate::utils::{
|
||||
check_sync, gen_dummy, get_delta,
|
||||
json_reader::{read_json, Program},
|
||||
modified_time, Config, MediaProbe,
|
||||
};
|
||||
@ -10,6 +13,7 @@ pub struct CurrentProgram {
|
||||
json_mod: String,
|
||||
json_path: String,
|
||||
nodes: Vec<Program>,
|
||||
init: bool,
|
||||
idx: usize,
|
||||
}
|
||||
|
||||
@ -22,6 +26,7 @@ impl CurrentProgram {
|
||||
json_mod: json.modified.unwrap(),
|
||||
json_path: json.current_file.unwrap(),
|
||||
nodes: json.program.into(),
|
||||
init: true,
|
||||
idx: json.start_index.unwrap(),
|
||||
}
|
||||
}
|
||||
@ -31,7 +36,7 @@ impl CurrentProgram {
|
||||
|
||||
if !mod_time.unwrap().to_string().eq(&self.json_mod) {
|
||||
// when playlist has changed, reload it
|
||||
let json = read_json(&self.config, true);
|
||||
let json = read_json(&self.config, false);
|
||||
|
||||
self.json_mod = json.modified.unwrap();
|
||||
self.nodes = json.program.into();
|
||||
@ -61,15 +66,34 @@ impl Iterator for CurrentProgram {
|
||||
last = true
|
||||
}
|
||||
|
||||
println!("Last: {}", self.nodes[self.idx - 1].source);
|
||||
println!("Next: {}", self.nodes[self.idx + 1].source);
|
||||
|
||||
self.idx += 1;
|
||||
|
||||
if self.idx <= self.nodes.len() - 1 && self.nodes[self.idx].category == "advertisement" {
|
||||
if self.idx <= self.nodes.len() - 1 && self.nodes[self.idx].category == "advertisement"
|
||||
{
|
||||
next = true
|
||||
}
|
||||
|
||||
self.append_probe(&mut current);
|
||||
self.add_filter(&mut current, last, next);
|
||||
if !self.init {
|
||||
let delta = get_delta(¤t.begin.unwrap(), &self.config);
|
||||
println!("Delta: {delta}");
|
||||
check_sync(delta, &self.config);
|
||||
}
|
||||
|
||||
if Path::new(¤t.source).is_file() {
|
||||
self.append_probe(&mut current);
|
||||
self.add_filter(&mut current, last, next);
|
||||
} else {
|
||||
println!("File not found: {}", current.source);
|
||||
let dummy = gen_dummy(current.out - current.seek, &self.config);
|
||||
current.source = dummy.0;
|
||||
current.cmd = Some(dummy.1);
|
||||
current.filter = Some(vec![]);
|
||||
}
|
||||
|
||||
self.init = false;
|
||||
Some(current)
|
||||
} else {
|
||||
let mut last = false;
|
||||
@ -91,8 +115,22 @@ impl Iterator for CurrentProgram {
|
||||
next = true
|
||||
}
|
||||
|
||||
self.append_probe(&mut current);
|
||||
self.add_filter(&mut current, last, next);
|
||||
if !self.init {
|
||||
let delta = get_delta(¤t.begin.unwrap(), &self.config);
|
||||
println!("Delta: {delta}");
|
||||
check_sync(delta, &self.config);
|
||||
}
|
||||
|
||||
if Path::new(¤t.source).is_file() {
|
||||
self.append_probe(&mut current);
|
||||
self.add_filter(&mut current, last, next);
|
||||
} else {
|
||||
println!("File not found: {}", current.source);
|
||||
let dummy = gen_dummy(current.out - current.seek, &self.config);
|
||||
current.source = dummy.0;
|
||||
current.cmd = Some(dummy.1);
|
||||
current.filter = Some(vec![]);
|
||||
}
|
||||
|
||||
Some(current)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user