diff --git a/src/input/playlist.rs b/src/input/playlist.rs index 489ea345..e7ba909c 100644 --- a/src/input/playlist.rs +++ b/src/input/playlist.rs @@ -12,8 +12,7 @@ use simplelog::*; use crate::utils::{ check_sync, gen_dummy, get_delta, get_sec, is_close, is_remote, json_serializer::read_json, - json_serializer::read_remote_json, modified_time, seek_and_length, valid_source, GlobalConfig, - Media, PlayoutStatus, DUMMY_LEN, + modified_time, seek_and_length, valid_source, GlobalConfig, Media, PlayoutStatus, DUMMY_LEN, }; /// Struct for current playlist. @@ -41,11 +40,7 @@ impl CurrentProgram { current_list: Arc>>, global_index: Arc, ) -> Self { - let json = if is_remote(&config.playlist.path.clone()) { - read_remote_json(config, None, is_terminated.clone(), true, 0.0) - } else { - read_json(config, None, is_terminated.clone(), true, 0.0) - }; + let json = read_json(config, None, is_terminated.clone(), true, 0.0); *current_list.lock().unwrap() = json.program; *playout_stat.current_date.lock().unwrap() = json.date.clone(); @@ -82,75 +77,87 @@ impl CurrentProgram { self.json_path = json.current_file; self.json_mod = json.modified; *self.nodes.lock().unwrap() = json.program; - } else if Path::new(&self.json_path.clone().unwrap()).is_file() { - let mod_time = modified_time(&self.json_path.clone().unwrap()); + } else if Path::new(&self.json_path.clone().unwrap()).is_file() + || is_remote(&self.json_path.clone().unwrap()) + { + let mut is_playlist_changed = false; - if let Some(m) = mod_time { - if !m.to_string().eq(&self.json_mod.clone().unwrap()) { - // when playlist has changed, reload it - info!( - "Reload playlist {}", - self.json_path.clone().unwrap() - ); + if is_remote(&self.json_path.clone().unwrap()) { + let resp = reqwest::blocking::Client::new() + .head(self.json_path.clone().unwrap()) + .send(); + match resp { + Ok(resp) => { + if resp.status().is_success() { + match resp.headers().get(reqwest::header::LAST_MODIFIED) { + Some(last_modified) => { + if !last_modified + .to_str() + .unwrap() + .eq(&self.json_mod.clone().unwrap()) + { + is_playlist_changed = true + } + } + None => {} + } + } + } + Err(_) => self.on_check_update_error(), + }; + } else { + let mod_time = modified_time(&self.json_path.clone().unwrap()); - let json = read_json( - &self.config, - self.json_path.clone(), - self.is_terminated.clone(), - false, - 0.0, - ); - - self.json_mod = json.modified; - *self.nodes.lock().unwrap() = json.program; - - self.get_current_clip(); - self.index.fetch_add(1, Ordering::SeqCst); + if let Some(m) = mod_time { + if !m.to_string().eq(&self.json_mod.clone().unwrap()) { + is_playlist_changed = true; + } } } - } else if is_remote(&self.json_path.clone().unwrap()) { - let resp = reqwest::blocking::Client::new() - .head(self.json_path.clone().unwrap()) - .send() - .unwrap(); - if resp.status().is_success() { - let headers = resp.headers().clone(); - let last_modified = headers.get(reqwest::header::LAST_MODIFIED).unwrap(); + if is_playlist_changed { + // when playlist has changed, reload it + info!( + "Reload playlist {}", + self.json_path.clone().unwrap() + ); - if !last_modified.eq(&self.json_mod.clone().unwrap()) { - let json = read_remote_json( - &self.config, - self.json_path.clone(), - self.is_terminated.clone(), - false, - 0.0, - ); - self.json_mod = json.modified; - *self.nodes.lock().unwrap() = json.program; + let json = read_json( + &self.config, + self.json_path.clone(), + self.is_terminated.clone(), + false, + 0.0, + ); - self.get_current_clip(); - self.index.fetch_add(1, Ordering::SeqCst); - } + self.json_mod = json.modified; + *self.nodes.lock().unwrap() = json.program; + + self.get_current_clip(); + self.index.fetch_add(1, Ordering::SeqCst); } } else { - error!( - "Playlist {} not exists!", - self.json_path.clone().unwrap() - ); - let mut media = Media::new(0, String::new(), false); - media.begin = Some(get_sec()); - media.duration = DUMMY_LEN; - media.out = DUMMY_LEN; - - self.json_path = None; - *self.nodes.lock().unwrap() = vec![media.clone()]; - self.current_node = media; - self.playout_stat.list_init.store(true, Ordering::SeqCst); - self.index.store(0, Ordering::SeqCst); + self.on_check_update_error(); } } + fn on_check_update_error(&mut self) { + error!( + "Playlist {} not exists!", + self.json_path.clone().unwrap() + ); + let mut media = Media::new(0, String::new(), false); + media.begin = Some(get_sec()); + media.duration = DUMMY_LEN; + media.out = DUMMY_LEN; + + self.json_path = None; + *self.nodes.lock().unwrap() = vec![media.clone()]; + self.current_node = media; + self.playout_stat.list_init.store(true, Ordering::SeqCst); + self.index.store(0, Ordering::SeqCst); + } + // Check if day is past and it is time for a new playlist. fn check_for_next_playlist(&mut self) { let current_time = get_sec(); @@ -173,23 +180,13 @@ impl CurrentProgram { || is_close(total_delta, 0.0, 2.0) || is_close(total_delta, target_length, 2.0) { - let json = if is_remote(&self.config.playlist.path.clone()) { - read_remote_json( - &self.config, - None, - self.is_terminated.clone(), - false, - next_start, - ) - } else { - read_json( - &self.config, - None, - self.is_terminated.clone(), - false, - next_start, - ) - }; + let json = read_json( + &self.config, + None, + self.is_terminated.clone(), + false, + next_start, + ); let data = json!({ "time_shift": 0.0, diff --git a/src/utils/json_serializer.rs b/src/utils/json_serializer.rs index 9369eb4c..02524f47 100644 --- a/src/utils/json_serializer.rs +++ b/src/utils/json_serializer.rs @@ -8,7 +8,7 @@ use std::{ use simplelog::*; -use crate::utils::{get_date, modified_time, validate_playlist, GlobalConfig, Media}; +use crate::utils::{get_date, is_remote, modified_time, validate_playlist, GlobalConfig, Media}; pub const DUMMY_LEN: f64 = 60.0; @@ -75,29 +75,68 @@ pub fn read_json( current_file = p } - if !playlist_path.is_file() { - error!("Playlist {current_file} not exists!"); + let mut playlist: Playlist; - return Playlist::new(date, start_sec); + if is_remote(¤t_file.clone()) { + let resp = reqwest::blocking::Client::new().get(¤t_file).send(); + + match resp { + Ok(resp) => { + if resp.status().is_success() { + info!("Read Remote Playlist: {current_file}"); + + let headers = resp.headers().clone(); + let body = resp.text().unwrap(); + + playlist = + serde_json::from_str(&body).expect("Could not read json playlist str."); + + match headers.get(reqwest::header::LAST_MODIFIED) { + Some(t) => { + playlist.modified = Some(t.to_str().unwrap().to_string()); + } + None => {} + } + } else { + error!( + "Get Remote Playlist {current_file} not success!: {}", + resp.text().unwrap() + ); + + return Playlist::new(date, start_sec); + } + } + Err(e) => { + error!("Remote Playlist {current_file}: {}", e); + + return Playlist::new(date, start_sec); + } + }; + } else { + if !playlist_path.is_file() { + error!("Playlist {current_file} not exists!"); + + return Playlist::new(date, start_sec); + } + + info!("Read Playlist: {current_file}"); + + let f = File::options() + .read(true) + .write(false) + .open(¤t_file) + .expect("Could not open json playlist file."); + playlist = serde_json::from_reader(f).expect("Could not read json playlist file."); + + let modify = modified_time(¤t_file); + + if let Some(modi) = modify { + playlist.modified = Some(modi.to_string()); + } } - info!("Read Playlist: {current_file}"); - - let f = File::options() - .read(true) - .write(false) - .open(¤t_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.clone()); playlist.start_sec = Some(start_sec); - let modify = modified_time(¤t_file); - - if let Some(modi) = modify { - playlist.modified = Some(modi.to_string()); - } // Add extra values to every media clip for (i, item) in playlist.program.iter_mut().enumerate() { @@ -117,61 +156,3 @@ pub fn read_json( playlist } - -pub fn read_remote_json( - config: &GlobalConfig, - path: Option, - is_terminated: Arc, - seek: bool, - next_start: f64, -) -> Playlist { - let config_clone = config.clone(); - let playlist_path = Path::new(&config.playlist.path).to_owned(); - let mut start_sec = config.playlist.start_sec.unwrap(); - let date = get_date(seek, start_sec, next_start); - - let mut current_file: String = playlist_path.as_path().display().to_string(); - - if let Some(p) = path { - current_file = p - } - - let resp = reqwest::blocking::Client::new() - .get(¤t_file) - .send() - .unwrap(); - if !resp.status().is_success() { - error!("Remote Playlist {current_file} not found!"); - - return Playlist::new(date, start_sec); - } - - let headers = resp.headers().clone(); - let body = resp.text().unwrap(); - let last_modified = headers.get(reqwest::header::LAST_MODIFIED).unwrap(); - - let mut playlist: Playlist = - serde_json::from_str(&body).expect("Could not read json playlist str."); - - playlist.current_file = Some(current_file); - playlist.start_sec = Some(start_sec); - - playlist.modified = Some(last_modified.to_str().unwrap().to_string()); - - for (i, item) in playlist.program.iter_mut().enumerate() { - item.begin = Some(start_sec); - item.index = Some(i); - item.last_ad = Some(false); - item.next_ad = Some(false); - item.process = Some(true); - item.filter = Some(vec![]); - - start_sec += item.out - item.seek; - } - - let list_clone = playlist.clone(); - - thread::spawn(move || validate_playlist(list_clone, is_terminated, config_clone)); - - playlist -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 7a37255a..c7a2b8a1 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -437,9 +437,7 @@ pub fn is_remote(path: &str) -> bool { /// /// Check if input is a remote source, or from storage and see if it exists. pub fn valid_source(source: &str) -> bool { - let re = Regex::new(r"^https?://.*").unwrap(); - - if re.is_match(source) && MediaProbe::new(source).video_streams.is_some() { + if is_remote(source) && MediaProbe::new(source).video_streams.is_some() { return true; }