fix 3 cases:

1. when playlist is to short, fill with dummy
2. when next playlist not exists
3. when in the middle of playling the current playlist disappeare
This commit is contained in:
jb-alvarado 2022-03-04 11:45:30 +01:00
parent bffd296ddc
commit 82a9def158
4 changed files with 147 additions and 62 deletions

View File

@ -105,7 +105,6 @@ pub fn play(config: Config) {
};
for node in get_source {
// println!("Node begin: {:?}", sec_to_time(node.begin.unwrap()));
let cmd = match node.cmd {
Some(cmd) => cmd,
None => break

View File

@ -3,44 +3,66 @@ use std::{fs::File, path::Path};
use simplelog::*;
use crate::utils::{get_date, modified_time, seek_and_length, time_to_sec, Config, Media};
use crate::utils::{get_date, get_sec, modified_time, seek_and_length, time_to_sec, Config, Media};
pub const DUMMY_LEN: f64 = 20.0;
#[derive(Debug, Serialize, Deserialize)]
pub struct Playlist {
pub date: String,
pub start_sec: Option<f64>,
pub current_file: Option<String>,
pub start_index: Option<usize>,
pub modified: Option<String>,
pub program: Vec<Media>,
}
impl Playlist {
fn new(date: String, start: f64) -> Self {
let mut media = Media::new(0, "".to_string());
media.begin = Some(start);
media.duration = DUMMY_LEN;
media.out = DUMMY_LEN;
Self {
date,
start_sec: Some(start),
current_file: None,
modified: None,
program: vec![media],
}
}
}
pub fn read_json(config: &Config, seek: bool, next_start: f64) -> Playlist {
let mut playlist_path = Path::new(&config.playlist.path).to_owned();
let start = &config.playlist.day_start;
let mut start_sec = time_to_sec(start);
let date = get_date(seek, start_sec, next_start);
if playlist_path.is_dir() {
let date = get_date(seek, start_sec, next_start);
let d: Vec<&str> = date.split('-').collect();
playlist_path = playlist_path
.join(d[0])
.join(d[1])
.join(date)
.join(date.clone())
.with_extension("json");
}
let current_file: String = playlist_path.as_path().display().to_string();
if !playlist_path.is_file() {
error!("Playlist <b><magenta>{}</></b> not exists!", current_file);
return Playlist::new(date, get_sec());
}
info!("Read Playlist: <b><magenta>{}</></b>", &current_file);
let modify = modified_time(current_file.clone());
let f = File::open(&current_file).expect("Could not open json playlist file.");
let mut playlist: Playlist =
serde_json::from_reader(f).expect("Could not read json playlist file.");
playlist.current_file = Some(current_file);
playlist.current_file = Some(current_file.clone());
playlist.start_sec = Some(start_sec.clone());
let modify = modified_time(current_file);
if modify.is_some() {
playlist.modified = Some(modify.unwrap().to_string());

View File

@ -16,7 +16,7 @@ mod playlist;
pub use arg_parse::get_args;
pub use config::{get_config, Config};
pub use folder::{watch_folder, Source};
pub use json_reader::read_json;
pub use json_reader::{read_json, DUMMY_LEN};
pub use logging::init_logging;
pub use playlist::CurrentProgram;
@ -213,14 +213,14 @@ pub fn is_close(a: f64, b: f64, to: f64) -> bool {
pub fn get_delta(begin: &f64, config: &Config) -> (f64, f64) {
let mut current_time = get_sec();
let start = time_to_sec(&config.playlist.day_start);
let mut tmp_time = current_time.clone();
let start = config.playlist.start_sec.unwrap();
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 {
@ -233,8 +233,12 @@ pub fn get_delta(begin: &f64, config: &Config) -> (f64, f64) {
current_delta -= 86400.0
}
if tmp_time <= start + current_delta.abs() {
tmp_time += target_length
}
let ref_time = target_length + start;
let total_delta = ref_time - begin + current_delta;
let total_delta = ref_time - tmp_time;
(current_delta, total_delta)
}
@ -265,7 +269,7 @@ pub fn gen_dummy(duration: f64, config: &Config) -> (String, Vec<String>) {
"-f".to_string(),
"lavfi".to_string(),
"-i".to_string(),
format!("anoisesrc=d={duration}:c=pink:r=48000:a=0.05"),
format!("anoisesrc=d={duration}:c=pink:r=48000:a=0.3"),
];
(source, cmd)

View File

@ -4,7 +4,7 @@ use simplelog::*;
use crate::utils::{
check_sync, gen_dummy, get_delta, get_sec, json_reader::read_json, modified_time,
seek_and_length, time_to_sec, Config, Media,
seek_and_length, time_to_sec, Config, Media, DUMMY_LEN,
};
#[derive(Debug)]
@ -12,7 +12,7 @@ pub struct CurrentProgram {
config: Config,
start_sec: f64,
json_mod: String,
json_path: String,
json_path: Option<String>,
nodes: Vec<Media>,
current_node: Media,
init: bool,
@ -24,11 +24,11 @@ impl CurrentProgram {
let json = read_json(&config, true, 0.0);
Self {
config: config,
config,
start_sec: json.start_sec.unwrap(),
json_mod: json.modified.unwrap(),
json_path: json.current_file.unwrap(),
nodes: json.program.into(),
json_path: Some(json.current_file.unwrap()),
nodes: json.program,
current_node: Media::new(0, "".to_string()),
init: true,
index: 0,
@ -36,14 +36,35 @@ impl CurrentProgram {
}
fn check_update(&mut self) {
let mod_time = modified_time(self.json_path.clone());
match self.json_path.clone() {
Some(path) => {
if Path::new(&path).is_file() {
let mod_time = modified_time(path);
if !mod_time.unwrap().to_string().eq(&self.json_mod) {
// when playlist has changed, reload it
let json = read_json(&self.config, false, 0.0);
if !mod_time.unwrap().to_string().eq(&self.json_mod) {
// when playlist has changed, reload it
let json = read_json(&self.config, false, 0.0);
self.json_mod = json.modified.unwrap();
self.nodes = json.program.into();
self.json_mod = json.modified.unwrap();
self.nodes = json.program.into();
}
} else {
error!("Playlist <b><magenta>{}</></b> not exists!", path);
let mut media = Media::new(0, "".to_string());
media.begin = Some(get_sec());
media.duration = DUMMY_LEN;
media.out = DUMMY_LEN;
self.json_path = None;
self.nodes = vec![media.clone()];
self.current_node = media;
self.init = true;
self.index = 0;
}
}
_ => (),
}
}
@ -112,6 +133,39 @@ impl CurrentProgram {
self.current_node.cmd = None;
}
}
fn get_init_clip(&mut self) {
let mut time_sec = get_sec();
let length = self.config.playlist.length.clone();
let mut length_sec: f64 = 86400.0;
if length.contains(":") {
length_sec = time_to_sec(&length);
}
if time_sec < self.start_sec {
time_sec += length_sec
}
let mut start_sec = self.start_sec.clone();
for (i, item) in self.nodes.iter_mut().enumerate() {
if start_sec + item.out - item.seek > time_sec {
self.init = false;
self.index = i + 1;
item.seek = time_sec - start_sec;
item.cmd = Some(seek_and_length(
item.source.clone(),
item.seek,
item.out,
item.duration,
));
self.current_node = handle_list_init(item.clone(), &self.config);
break
}
start_sec += item.out - item.seek;
}
}
}
impl Iterator for CurrentProgram {
@ -119,42 +173,34 @@ impl Iterator for CurrentProgram {
fn next(&mut self) -> Option<Self::Item> {
if self.init {
let mut time_sec = get_sec();
let length = self.config.playlist.length.clone();
let mut length_sec: f64 = 86400.0;
debug!("Playlist init");
if length.contains(":") {
length_sec = time_to_sec(&length);
if self.json_path.is_some() {
self.get_init_clip();
}
if time_sec < self.start_sec {
time_sec += length_sec
}
if self.init {
let json = read_json(&self.config, false, get_sec() + DUMMY_LEN);
let mut start_sec = self.start_sec.clone();
if json.current_file.is_some() {
self.json_mod = json.modified.unwrap();
self.json_path = Some(json.current_file.unwrap());
self.nodes = json.program;
self.get_init_clip();
} else {
let mut media = Media::new(0, "".to_string());
media.begin = Some(get_sec());
media.duration = DUMMY_LEN;
media.out = DUMMY_LEN;
for (i, item) in self.nodes.iter_mut().enumerate() {
if start_sec + item.out - item.seek > time_sec {
self.init = false;
self.index = i + 1;
item.seek = time_sec - start_sec;
item.cmd = Some(seek_and_length(
item.source.clone(),
item.seek,
item.out,
item.duration,
));
self.current_node = handle_list_init(item.clone(), &self.config);
self.current_node.last_ad = self.is_ad(i, false);
self.current_node.next_ad = self.is_ad(i, false);
break;
self.current_node = gen_source(media, &self.config);
}
start_sec += item.out - item.seek;
}
if !self.init {
return Some(self.current_node.clone());
}
self.current_node.last_ad = self.is_ad(self.index, false);
self.current_node.next_ad = self.is_ad(self.index, false);
return Some(self.current_node.clone());
}
if self.index < self.nodes.len() {
self.check_update();
@ -168,16 +214,20 @@ impl Iterator for CurrentProgram {
self.check_for_next_playlist(false);
Some(self.current_node.clone())
} else {
let (_, time_diff) = get_delta(&get_sec(), &self.config);
let (_, time_diff) = get_delta(&self.config.playlist.start_sec.unwrap(), &self.config);
let mut last_ad = self.is_ad(self.index, false);
// println!("delta: {:?} | time_diff: {:?}", delta, time_diff);
if time_diff.abs() > self.config.general.stop_threshold {
// Test if playlist is to early finish,
// and if we have to fill it with a placeholder.
self.current_node = Media::new(self.index + 1, "".to_string());
self.current_node.begin = Some(get_sec());
let mut duration = time_diff.abs();
if duration > 60.0 {
duration = 60.0;
if duration > DUMMY_LEN {
duration = DUMMY_LEN;
}
self.current_node.duration = duration;
self.current_node.out = duration;
@ -191,12 +241,23 @@ impl Iterator for CurrentProgram {
return Some(self.current_node.clone());
}
let json = read_json(&self.config, false, 0.0);
self.json_mod = json.modified.unwrap();
self.json_path = json.current_file.unwrap();
self.nodes = json.program.into();
let next_begin =
self.current_node.begin.unwrap() + self.current_node.out - self.current_node.seek;
self.get_current_node(0);
// Here we should end up, when we need a new playlist
let json = read_json(&self.config, false, next_begin);
if json.current_file.is_none() {
self.init = true;
self.json_path = None;
self.nodes = json.program;
} else {
self.json_mod = json.modified.unwrap();
self.json_path = Some(json.current_file.unwrap());
self.nodes = json.program;
}
self.current_node = gen_source(self.nodes[0].clone(), &self.config);
self.current_node.last_ad = last_ad;
self.current_node.next_ad = self.is_ad(0, false);
@ -218,6 +279,7 @@ fn timed_source(node: Media, config: &Config, last: bool) -> Media {
if config.playlist.length.contains(":") {
debug!("Delta: <yellow>{delta}</>");
debug!("Total delta: <yellow>{total_delta}</>");
check_sync(delta, &config);
}
@ -243,7 +305,7 @@ fn gen_source(mut node: Media, config: &Config) -> Media {
} else {
if node.source.chars().count() == 0 {
warn!(
"Generate filler with <yellow>{}</> seconds length!",
"Generate filler with <yellow>{:.2}</> seconds length!",
node.out - node.seek
);
} else {
@ -262,8 +324,6 @@ fn handle_list_init(mut node: Media, config: &Config) -> 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
debug!("Playlist init");
let (_, total_delta) = get_delta(&node.begin.unwrap(), config);
let mut out = node.out;