move config to global config.
This commit is contained in:
parent
8c55d20ed2
commit
37dd5a695c
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -158,6 +158,7 @@ dependencies = [
|
|||||||
"lettre",
|
"lettre",
|
||||||
"log",
|
"log",
|
||||||
"notify",
|
"notify",
|
||||||
|
"once_cell",
|
||||||
"rand",
|
"rand",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -15,6 +15,7 @@ log = "0.4.14"
|
|||||||
notify = "4.0.17"
|
notify = "4.0.17"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
|
once_cell = "1.10"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_yaml = "0.8"
|
serde_yaml = "0.8"
|
||||||
|
@ -2,7 +2,7 @@ use std::path::Path;
|
|||||||
|
|
||||||
use simplelog::*;
|
use simplelog::*;
|
||||||
|
|
||||||
use crate::utils::{is_close, Config, Media};
|
use crate::utils::{is_close, GlobalConfig, Media};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Filters {
|
struct Filters {
|
||||||
@ -66,7 +66,7 @@ fn deinterlace(field_order: Option<String>, chain: &mut Filters) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pad(aspect: f64, chain: &mut Filters, config: &Config) {
|
fn pad(aspect: f64, chain: &mut Filters, config: &GlobalConfig) {
|
||||||
if !is_close(aspect, config.processing.aspect, 0.03) {
|
if !is_close(aspect, config.processing.aspect, 0.03) {
|
||||||
if aspect < config.processing.aspect {
|
if aspect < config.processing.aspect {
|
||||||
chain.add_filter(
|
chain.add_filter(
|
||||||
@ -90,7 +90,7 @@ fn pad(aspect: f64, chain: &mut Filters, config: &Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fps(fps: f64, chain: &mut Filters, config: &Config) {
|
fn fps(fps: f64, chain: &mut Filters, config: &GlobalConfig) {
|
||||||
if fps != config.processing.fps {
|
if fps != config.processing.fps {
|
||||||
chain.add_filter(
|
chain.add_filter(
|
||||||
format!("fps={}", config.processing.fps).into(),
|
format!("fps={}", config.processing.fps).into(),
|
||||||
@ -99,7 +99,7 @@ fn fps(fps: f64, chain: &mut Filters, config: &Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scale(width: i64, height: i64, aspect: f64, chain: &mut Filters, config: &Config) {
|
fn scale(width: i64, height: i64, aspect: f64, chain: &mut Filters, config: &GlobalConfig) {
|
||||||
if width != config.processing.width || height != config.processing.height {
|
if width != config.processing.width || height != config.processing.height {
|
||||||
chain.add_filter(
|
chain.add_filter(
|
||||||
format!(
|
format!(
|
||||||
@ -138,7 +138,7 @@ fn fade(node: &mut Media, chain: &mut Filters, codec_type: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn overlay(node: &mut Media, chain: &mut Filters, config: &Config) {
|
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 != "advertisement".to_string()
|
&& node.category != "advertisement".to_string()
|
||||||
@ -221,7 +221,7 @@ fn extend_audio(node: &mut Media, chain: &mut Filters) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn audio_volume(chain: &mut Filters, config: &Config) {
|
fn audio_volume(chain: &mut Filters, config: &GlobalConfig) {
|
||||||
if config.processing.volume != 1.0 {
|
if config.processing.volume != 1.0 {
|
||||||
chain.add_filter(
|
chain.add_filter(
|
||||||
format!("volume={}", config.processing.volume),
|
format!("volume={}", config.processing.volume),
|
||||||
@ -248,7 +248,9 @@ fn fps_calc(r_frame_rate: String) -> f64 {
|
|||||||
fps
|
fps
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filter_chains(node: &mut Media, config: &Config) -> Vec<String> {
|
pub fn filter_chains(node: &mut Media) -> Vec<String> {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
|
|
||||||
let mut filters = Filters::new();
|
let mut filters = Filters::new();
|
||||||
let mut audio_map = "1:a".to_string();
|
let mut audio_map = "1:a".to_string();
|
||||||
filters.audio_map = Some(audio_map);
|
filters.audio_map = Some(audio_map);
|
||||||
|
@ -8,13 +8,12 @@ mod utils;
|
|||||||
use simplelog::*;
|
use simplelog::*;
|
||||||
|
|
||||||
use crate::output::play;
|
use crate::output::play;
|
||||||
use crate::utils::{get_config, init_logging};
|
use crate::utils::{init_config, init_logging};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let config = get_config();
|
init_config();
|
||||||
let logging = init_logging(&config);
|
let logging = init_logging();
|
||||||
|
|
||||||
CombinedLogger::init(logging).unwrap();
|
CombinedLogger::init(logging).unwrap();
|
||||||
|
|
||||||
play(config);
|
play();
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,11 @@ use std::{
|
|||||||
|
|
||||||
use simplelog::*;
|
use simplelog::*;
|
||||||
|
|
||||||
use crate::utils::Config;
|
use crate::utils::GlobalConfig;
|
||||||
|
|
||||||
|
pub fn output(log_format: String) -> process::Child {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
|
|
||||||
pub fn output(config: Config, log_format: String) -> process::Child {
|
|
||||||
let mut enc_filter: Vec<String> = vec![];
|
let mut enc_filter: Vec<String> = vec![];
|
||||||
|
|
||||||
let mut enc_cmd = vec![
|
let mut enc_cmd = vec![
|
||||||
|
@ -17,10 +17,12 @@ mod desktop;
|
|||||||
mod stream;
|
mod stream;
|
||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
sec_to_time, stderr_reader, watch_folder, Config, CurrentProgram, Media, Source,
|
sec_to_time, stderr_reader, watch_folder, GlobalConfig, CurrentProgram, Media, Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn play(config: Config) {
|
pub fn play() {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
|
|
||||||
let dec_pid: Arc<Mutex<u32>> = Arc::new(Mutex::new(0));
|
let dec_pid: Arc<Mutex<u32>> = Arc::new(Mutex::new(0));
|
||||||
let mut thread_count = 2;
|
let mut thread_count = 2;
|
||||||
|
|
||||||
@ -34,7 +36,7 @@ pub fn play(config: Config) {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let get_source = match config.processing.mode.clone().as_str() {
|
let get_source = match config.processing.clone().mode.as_str() {
|
||||||
"folder" => {
|
"folder" => {
|
||||||
let path = config.storage.path.clone();
|
let path = config.storage.path.clone();
|
||||||
if !Path::new(&path).exists() {
|
if !Path::new(&path).exists() {
|
||||||
@ -44,7 +46,7 @@ pub fn play(config: Config) {
|
|||||||
|
|
||||||
info!("Playout in folder mode.");
|
info!("Playout in folder mode.");
|
||||||
|
|
||||||
let folder_source = Source::new(config.clone());
|
let folder_source = Source::new();
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = channel();
|
||||||
let mut watcher = watcher(sender, Duration::from_secs(2)).unwrap();
|
let mut watcher = watcher(sender, Duration::from_secs(2)).unwrap();
|
||||||
|
|
||||||
@ -60,7 +62,7 @@ pub fn play(config: Config) {
|
|||||||
}
|
}
|
||||||
"playlist" => {
|
"playlist" => {
|
||||||
info!("Playout in playlist mode.");
|
info!("Playout in playlist mode.");
|
||||||
Box::new(CurrentProgram::new(config.clone())) as Box<dyn Iterator<Item = Media>>
|
Box::new(CurrentProgram::new()) as Box<dyn Iterator<Item = Media>>
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("Process Mode not exists!");
|
error!("Process Mode not exists!");
|
||||||
@ -68,13 +70,12 @@ pub fn play(config: Config) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let config_clone = config.clone();
|
let dec_settings = config.processing.clone().settings.unwrap();
|
||||||
let dec_settings = config.processing.settings.unwrap();
|
|
||||||
let ff_log_format = format!("level+{}", config.logging.ffmpeg_level);
|
let ff_log_format = format!("level+{}", config.logging.ffmpeg_level);
|
||||||
|
|
||||||
let mut enc_proc = match config.out.mode.as_str() {
|
let mut enc_proc = match config.out.mode.as_str() {
|
||||||
"desktop" => desktop::output(config_clone, ff_log_format.clone()),
|
"desktop" => desktop::output(ff_log_format.clone()),
|
||||||
"stream" => stream::output(config_clone, ff_log_format.clone()),
|
"stream" => stream::output(ff_log_format.clone()),
|
||||||
_ => panic!("Output mode doesn't exists!"),
|
_ => panic!("Output mode doesn't exists!"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,9 +5,10 @@ use std::{
|
|||||||
|
|
||||||
use simplelog::*;
|
use simplelog::*;
|
||||||
|
|
||||||
use crate::utils::Config;
|
use crate::utils::GlobalConfig;
|
||||||
|
|
||||||
pub fn output(config: Config, log_format: String) -> process::Child {
|
pub fn output(log_format: String) -> process::Child {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
let mut enc_filter: Vec<String> = vec![];
|
let mut enc_filter: Vec<String> = vec![];
|
||||||
|
|
||||||
let mut enc_cmd = vec![
|
let mut enc_cmd = vec![
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
use once_cell::sync::OnceCell;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_yaml::{self};
|
use serde_yaml::{self};
|
||||||
use std::{fs::File, path::Path, process};
|
use std::{fs::File, path::Path, process};
|
||||||
// use regex::Regex;
|
|
||||||
|
|
||||||
use crate::utils::{get_args, time_to_sec};
|
use crate::utils::{get_args, time_to_sec};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Config {
|
pub struct GlobalConfig {
|
||||||
pub general: General,
|
pub general: General,
|
||||||
pub mail: Mail,
|
pub mail: Mail,
|
||||||
pub logging: Logging,
|
pub logging: Logging,
|
||||||
@ -108,7 +108,10 @@ pub struct Out {
|
|||||||
pub stream_param: Vec<String>,
|
pub stream_param: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_config() -> Config {
|
static INSTANCE: OnceCell<GlobalConfig> = OnceCell::new();
|
||||||
|
|
||||||
|
impl GlobalConfig {
|
||||||
|
fn new() -> Self {
|
||||||
let args = get_args();
|
let args = get_args();
|
||||||
let mut config_path: String = "ffplayout.yml".to_string();
|
let mut config_path: String = "ffplayout.yml".to_string();
|
||||||
|
|
||||||
@ -129,7 +132,7 @@ pub fn get_config() -> Config {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut config: Config = serde_yaml::from_reader(f).expect("Could not read config file.");
|
let mut config: GlobalConfig = serde_yaml::from_reader(f).expect("Could not read config file.");
|
||||||
let fps = config.processing.fps.to_string();
|
let fps = config.processing.fps.to_string();
|
||||||
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));
|
||||||
@ -218,5 +221,15 @@ pub fn get_config() -> Config {
|
|||||||
config.processing.volume = args.volume.unwrap();
|
config.processing.volume = args.volume.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
config
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn global() -> &'static GlobalConfig {
|
||||||
|
INSTANCE.get().expect("Config is not initialized")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_config() {
|
||||||
|
let config = GlobalConfig::new();
|
||||||
|
INSTANCE.set(config).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -12,17 +12,18 @@ use std::{
|
|||||||
|
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
use crate::utils::{Config, Media};
|
use crate::utils::{GlobalConfig, Media};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Source {
|
pub struct Source {
|
||||||
config: Config,
|
config: GlobalConfig,
|
||||||
pub nodes: Arc<Mutex<Vec<String>>>,
|
pub nodes: Arc<Mutex<Vec<String>>>,
|
||||||
index: usize,
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Source {
|
impl Source {
|
||||||
pub fn new(config: Config) -> Self {
|
pub fn new() -> Self {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
let mut file_list = vec![];
|
let mut file_list = vec![];
|
||||||
|
|
||||||
for entry in WalkDir::new(config.storage.path.clone())
|
for entry in WalkDir::new(config.storage.path.clone())
|
||||||
@ -53,7 +54,7 @@ impl Source {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
config: config,
|
config: config.clone(),
|
||||||
nodes: Arc::new(Mutex::new(file_list)),
|
nodes: Arc::new(Mutex::new(file_list)),
|
||||||
index: 0,
|
index: 0,
|
||||||
}
|
}
|
||||||
@ -77,7 +78,7 @@ impl Iterator for Source {
|
|||||||
let current_file = self.nodes.lock().unwrap()[self.index].clone();
|
let current_file = self.nodes.lock().unwrap()[self.index].clone();
|
||||||
let mut media = Media::new(self.index, current_file);
|
let mut media = Media::new(self.index, current_file);
|
||||||
media.add_probe();
|
media.add_probe();
|
||||||
media.add_filter(&self.config);
|
media.add_filter();
|
||||||
self.index += 1;
|
self.index += 1;
|
||||||
|
|
||||||
Some(media)
|
Some(media)
|
||||||
@ -93,7 +94,7 @@ impl Iterator for Source {
|
|||||||
let current_file = self.nodes.lock().unwrap()[0].clone();
|
let current_file = self.nodes.lock().unwrap()[0].clone();
|
||||||
let mut media = Media::new(self.index, current_file);
|
let mut media = Media::new(self.index, current_file);
|
||||||
media.add_probe();
|
media.add_probe();
|
||||||
media.add_filter(&self.config);
|
media.add_filter();
|
||||||
self.index = 1;
|
self.index = 1;
|
||||||
|
|
||||||
Some(media)
|
Some(media)
|
||||||
|
@ -3,7 +3,7 @@ use std::{fs::File, path::Path};
|
|||||||
|
|
||||||
use simplelog::*;
|
use simplelog::*;
|
||||||
|
|
||||||
use crate::utils::{get_date, modified_time, time_to_sec, Config, Media};
|
use crate::utils::{get_date, modified_time, time_to_sec, GlobalConfig, Media};
|
||||||
|
|
||||||
pub const DUMMY_LEN: f64 = 20.0;
|
pub const DUMMY_LEN: f64 = 20.0;
|
||||||
|
|
||||||
@ -32,7 +32,9 @@ impl Playlist {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_json(config: &Config, seek: bool, next_start: f64) -> Playlist {
|
pub fn read_json(seek: bool, next_start: f64) -> Playlist {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
|
|
||||||
let mut playlist_path = Path::new(&config.playlist.path).to_owned();
|
let mut playlist_path = Path::new(&config.playlist.path).to_owned();
|
||||||
let start = &config.playlist.day_start;
|
let start = &config.playlist.day_start;
|
||||||
let mut start_sec = time_to_sec(start);
|
let mut start_sec = time_to_sec(start);
|
||||||
|
@ -10,24 +10,21 @@ use simplelog::*;
|
|||||||
|
|
||||||
use lettre::{transport::smtp::authentication::Credentials, Message, SmtpTransport, Transport};
|
use lettre::{transport::smtp::authentication::Credentials, Message, SmtpTransport, Transport};
|
||||||
|
|
||||||
use crate::utils;
|
use crate::utils::GlobalConfig;
|
||||||
|
|
||||||
pub struct LogMailer {
|
pub struct LogMailer {
|
||||||
level: LevelFilter,
|
level: LevelFilter,
|
||||||
config: Config,
|
config: Config,
|
||||||
playout_config: utils::Config,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LogMailer {
|
impl LogMailer {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
log_level: LevelFilter,
|
log_level: LevelFilter,
|
||||||
config: Config,
|
config: Config,
|
||||||
playout_config: &utils::Config,
|
|
||||||
) -> Box<LogMailer> {
|
) -> Box<LogMailer> {
|
||||||
Box::new(LogMailer {
|
Box::new(LogMailer {
|
||||||
level: log_level,
|
level: log_level,
|
||||||
config,
|
config,
|
||||||
playout_config: playout_config.clone(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,8 +37,8 @@ impl Log for LogMailer {
|
|||||||
fn log(&self, record: &Record<'_>) {
|
fn log(&self, record: &Record<'_>) {
|
||||||
if self.enabled(record.metadata()) {
|
if self.enabled(record.metadata()) {
|
||||||
match record.level() {
|
match record.level() {
|
||||||
Level::Error => send_mail(record.args().to_string(), &self.playout_config),
|
Level::Error => send_mail(record.args().to_string()),
|
||||||
Level::Warn => send_mail(record.args().to_string(), &self.playout_config),
|
Level::Warn => send_mail(record.args().to_string()),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,7 +69,9 @@ fn clean_string(text: String) -> String {
|
|||||||
regex.replace_all(text.as_str(), "").to_string()
|
regex.replace_all(text.as_str(), "").to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_mail(msg: String, config: &utils::Config) {
|
fn send_mail(msg: String) {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
|
|
||||||
let email = Message::builder()
|
let email = Message::builder()
|
||||||
.from(config.mail.sender_addr.parse().unwrap())
|
.from(config.mail.sender_addr.parse().unwrap())
|
||||||
.to(config.mail.recipient.parse().unwrap())
|
.to(config.mail.recipient.parse().unwrap())
|
||||||
@ -103,7 +102,8 @@ fn send_mail(msg: String, config: &utils::Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_logging(config: &utils::Config) -> Vec<Box<dyn SharedLogger>> {
|
pub fn init_logging() -> Vec<Box<dyn SharedLogger>> {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
let app_config = config.logging.clone();
|
let app_config = config.logging.clone();
|
||||||
let mut app_logger: Vec<Box<dyn SharedLogger>> = vec![];
|
let mut app_logger: Vec<Box<dyn SharedLogger>> = vec![];
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ pub fn init_logging(config: &utils::Config) -> Vec<Box<dyn SharedLogger>> {
|
|||||||
filter = LevelFilter::Warn
|
filter = LevelFilter::Warn
|
||||||
}
|
}
|
||||||
|
|
||||||
app_logger.push(LogMailer::new(filter, mail_config, config));
|
app_logger.push(LogMailer::new(filter, mail_config));
|
||||||
}
|
}
|
||||||
|
|
||||||
app_logger
|
app_logger
|
||||||
|
@ -21,7 +21,7 @@ mod logging;
|
|||||||
mod playlist;
|
mod playlist;
|
||||||
|
|
||||||
pub use arg_parse::get_args;
|
pub use arg_parse::get_args;
|
||||||
pub use config::{get_config, Config};
|
pub use config::{init_config, GlobalConfig};
|
||||||
pub use folder::{watch_folder, Source};
|
pub use folder::{watch_folder, Source};
|
||||||
pub use json_reader::{read_json, DUMMY_LEN};
|
pub use json_reader::{read_json, DUMMY_LEN};
|
||||||
pub use logging::init_logging;
|
pub use logging::init_logging;
|
||||||
@ -82,9 +82,9 @@ impl Media {
|
|||||||
self.probe = Some(MediaProbe::new(self.source.clone()))
|
self.probe = Some(MediaProbe::new(self.source.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_filter(&mut self, config: &Config) {
|
fn add_filter(&mut self) {
|
||||||
let mut node = self.clone();
|
let mut node = self.clone();
|
||||||
self.filter = Some(filter_chains(&mut node, &config))
|
self.filter = Some(filter_chains(&mut node))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +218,8 @@ pub fn is_close(a: f64, b: f64, to: f64) -> bool {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_delta(begin: &f64, config: &Config) -> (f64, f64) {
|
pub fn get_delta(begin: &f64) -> (f64, f64) {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
let mut current_time = get_sec();
|
let mut current_time = get_sec();
|
||||||
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);
|
||||||
@ -249,7 +250,9 @@ pub fn get_delta(begin: &f64, config: &Config) -> (f64, f64) {
|
|||||||
(current_delta, total_delta)
|
(current_delta, total_delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_sync(delta: f64, config: &Config) -> bool {
|
pub fn check_sync(delta: f64) -> bool {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
|
|
||||||
if delta.abs() > config.general.stop_threshold && config.general.stop_threshold > 0.0 {
|
if delta.abs() > config.general.stop_threshold && config.general.stop_threshold > 0.0 {
|
||||||
error!("Start time out of sync for <yellow>{}</> seconds", delta);
|
error!("Start time out of sync for <yellow>{}</> seconds", delta);
|
||||||
return false;
|
return false;
|
||||||
@ -258,7 +261,8 @@ pub fn check_sync(delta: f64, config: &Config) -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_dummy(duration: f64, config: &Config) -> (String, Vec<String>) {
|
pub fn gen_dummy(duration: f64) -> (String, Vec<String>) {
|
||||||
|
let config = GlobalConfig::global();
|
||||||
let color = "#121212";
|
let color = "#121212";
|
||||||
let source = format!(
|
let source = format!(
|
||||||
"color=c={color}:s={}x{}:d={duration}",
|
"color=c={color}:s={}x{}:d={duration}",
|
||||||
|
@ -4,12 +4,12 @@ use simplelog::*;
|
|||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
check_sync, gen_dummy, get_delta, get_sec, is_close, json_reader::read_json, modified_time,
|
check_sync, gen_dummy, get_delta, get_sec, is_close, json_reader::read_json, modified_time,
|
||||||
seek_and_length, Config, Media, DUMMY_LEN,
|
seek_and_length, GlobalConfig, Media, DUMMY_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CurrentProgram {
|
pub struct CurrentProgram {
|
||||||
config: Config,
|
config: GlobalConfig,
|
||||||
start_sec: f64,
|
start_sec: f64,
|
||||||
json_mod: Option<String>,
|
json_mod: Option<String>,
|
||||||
json_path: Option<String>,
|
json_path: Option<String>,
|
||||||
@ -20,11 +20,12 @@ pub struct CurrentProgram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CurrentProgram {
|
impl CurrentProgram {
|
||||||
pub fn new(config: Config) -> Self {
|
pub fn new() -> Self {
|
||||||
let json = read_json(&config, true, 0.0);
|
let config = GlobalConfig::global();
|
||||||
|
let json = read_json(true, 0.0);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
config,
|
config: config.clone(),
|
||||||
start_sec: json.start_sec.unwrap(),
|
start_sec: json.start_sec.unwrap(),
|
||||||
json_mod: json.modified,
|
json_mod: json.modified,
|
||||||
json_path: json.current_file,
|
json_path: json.current_file,
|
||||||
@ -37,7 +38,7 @@ impl CurrentProgram {
|
|||||||
|
|
||||||
fn check_update(&mut self, seek: bool) {
|
fn check_update(&mut self, seek: bool) {
|
||||||
if self.json_path.is_none() {
|
if self.json_path.is_none() {
|
||||||
let json = read_json(&self.config, seek, 0.0);
|
let json = read_json(seek, 0.0);
|
||||||
|
|
||||||
self.json_path = json.current_file;
|
self.json_path = json.current_file;
|
||||||
self.json_mod = json.modified;
|
self.json_mod = json.modified;
|
||||||
@ -51,7 +52,7 @@ impl CurrentProgram {
|
|||||||
.eq(&self.json_mod.clone().unwrap())
|
.eq(&self.json_mod.clone().unwrap())
|
||||||
{
|
{
|
||||||
// when playlist has changed, reload it
|
// when playlist has changed, reload it
|
||||||
let json = read_json(&self.config, false, 0.0);
|
let json = read_json(false, 0.0);
|
||||||
|
|
||||||
self.json_mod = json.modified;
|
self.json_mod = json.modified;
|
||||||
self.nodes = json.program;
|
self.nodes = json.program;
|
||||||
@ -78,7 +79,7 @@ impl CurrentProgram {
|
|||||||
let current_time = get_sec();
|
let current_time = get_sec();
|
||||||
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, &self.config);
|
let (delta, total_delta) = get_delta(¤t_time);
|
||||||
let mut duration = self.current_node.out.clone();
|
let mut duration = self.current_node.out.clone();
|
||||||
|
|
||||||
if self.current_node.duration > self.current_node.out {
|
if self.current_node.duration > self.current_node.out {
|
||||||
@ -91,7 +92,7 @@ impl CurrentProgram {
|
|||||||
|| is_close(total_delta, 0.0, 2.0)
|
|| is_close(total_delta, 0.0, 2.0)
|
||||||
|| is_close(total_delta, target_length, 2.0)
|
|| is_close(total_delta, target_length, 2.0)
|
||||||
{
|
{
|
||||||
let json = read_json(&self.config, false, next_start);
|
let json = read_json(false, next_start);
|
||||||
|
|
||||||
self.json_path = json.current_file.clone();
|
self.json_path = json.current_file.clone();
|
||||||
self.json_mod = json.modified;
|
self.json_mod = json.modified;
|
||||||
@ -139,7 +140,7 @@ impl CurrentProgram {
|
|||||||
self.index = i + 1;
|
self.index = i + 1;
|
||||||
item.seek = time_sec - start_sec;
|
item.seek = time_sec - start_sec;
|
||||||
|
|
||||||
self.current_node = handle_list_init(item.clone(), &self.config);
|
self.current_node = handle_list_init(item.clone());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
start_sec += item.out - item.seek;
|
start_sec += item.out - item.seek;
|
||||||
@ -176,7 +177,7 @@ impl Iterator for CurrentProgram {
|
|||||||
self.get_init_clip();
|
self.get_init_clip();
|
||||||
} else {
|
} else {
|
||||||
let mut current_time = get_sec();
|
let mut current_time = get_sec();
|
||||||
let (_, total_delta) = get_delta(¤t_time, &self.config);
|
let (_, total_delta) = get_delta(¤t_time);
|
||||||
let mut duration = DUMMY_LEN;
|
let mut duration = DUMMY_LEN;
|
||||||
|
|
||||||
if DUMMY_LEN > total_delta {
|
if DUMMY_LEN > total_delta {
|
||||||
@ -192,7 +193,7 @@ impl Iterator for CurrentProgram {
|
|||||||
media.duration = duration;
|
media.duration = duration;
|
||||||
media.out = duration;
|
media.out = duration;
|
||||||
|
|
||||||
self.current_node = gen_source(media, &self.config);
|
self.current_node = gen_source(media);
|
||||||
self.nodes.push(self.current_node.clone());
|
self.nodes.push(self.current_node.clone());
|
||||||
self.index = self.nodes.len();
|
self.index = self.nodes.len();
|
||||||
}
|
}
|
||||||
@ -222,7 +223,7 @@ impl Iterator for CurrentProgram {
|
|||||||
let last_playlist = self.json_path.clone();
|
let last_playlist = self.json_path.clone();
|
||||||
self.check_for_next_playlist();
|
self.check_for_next_playlist();
|
||||||
let (_, total_delta) =
|
let (_, total_delta) =
|
||||||
get_delta(&self.config.playlist.start_sec.unwrap(), &self.config);
|
get_delta(&self.config.playlist.start_sec.unwrap());
|
||||||
let mut last_ad = self.is_ad(self.index, false);
|
let mut last_ad = self.is_ad(self.index, false);
|
||||||
|
|
||||||
if last_playlist == self.json_path
|
if last_playlist == self.json_path
|
||||||
@ -240,17 +241,17 @@ impl Iterator for CurrentProgram {
|
|||||||
}
|
}
|
||||||
self.current_node.duration = duration;
|
self.current_node.duration = duration;
|
||||||
self.current_node.out = duration;
|
self.current_node.out = duration;
|
||||||
self.current_node = gen_source(self.current_node.clone(), &self.config);
|
self.current_node = gen_source(self.current_node.clone());
|
||||||
self.nodes.push(self.current_node.clone());
|
self.nodes.push(self.current_node.clone());
|
||||||
|
|
||||||
last_ad = self.is_ad(self.index, false);
|
last_ad = self.is_ad(self.index, false);
|
||||||
self.current_node.last_ad = last_ad;
|
self.current_node.last_ad = last_ad;
|
||||||
self.current_node.add_filter(&self.config);
|
self.current_node.add_filter();
|
||||||
|
|
||||||
return Some(self.current_node.clone());
|
return Some(self.current_node.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_node = gen_source(self.nodes[0].clone(), &self.config);
|
self.current_node = gen_source(self.nodes[0].clone());
|
||||||
self.current_node.last_ad = last_ad;
|
self.current_node.last_ad = last_ad;
|
||||||
self.current_node.next_ad = self.is_ad(0, true);
|
self.current_node.next_ad = self.is_ad(0, true);
|
||||||
|
|
||||||
@ -261,19 +262,19 @@ impl Iterator for CurrentProgram {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn timed_source(node: Media, config: &Config, last: bool) -> Media {
|
fn timed_source(node: Media, config: &GlobalConfig, last: bool) -> Media {
|
||||||
// prepare input clip
|
// prepare input clip
|
||||||
// check begin and length from clip
|
// check begin and length from clip
|
||||||
// return clip only if we are in 24 hours time range
|
// return clip only if we are in 24 hours time range
|
||||||
|
|
||||||
let (delta, total_delta) = get_delta(&node.begin.unwrap(), &config);
|
let (delta, total_delta) = get_delta(&node.begin.unwrap());
|
||||||
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(":") {
|
||||||
debug!("Delta: <yellow>{delta}</>");
|
debug!("Delta: <yellow>{delta}</>");
|
||||||
debug!("Total delta: <yellow>{total_delta}</>");
|
debug!("Total delta: <yellow>{total_delta}</>");
|
||||||
let sync = check_sync(delta, &config);
|
let sync = check_sync(delta);
|
||||||
|
|
||||||
if !sync {
|
if !sync {
|
||||||
new_node.cmd = None;
|
new_node.cmd = None;
|
||||||
@ -287,7 +288,7 @@ fn timed_source(node: Media, config: &Config, last: bool) -> Media {
|
|||||||
|| !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, &config);
|
new_node = gen_source(node);
|
||||||
new_node.process = Some(true);
|
new_node.process = Some(true);
|
||||||
} else if total_delta <= 0.0 {
|
} else if total_delta <= 0.0 {
|
||||||
info!("Begin is over play time, skip: {}", node.source);
|
info!("Begin is over play time, skip: {}", node.source);
|
||||||
@ -298,7 +299,7 @@ fn timed_source(node: Media, config: &Config, last: bool) -> Media {
|
|||||||
new_node
|
new_node
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_source(mut node: Media, config: &Config) -> Media {
|
fn gen_source(mut node: Media) -> Media {
|
||||||
if Path::new(&node.source).is_file() {
|
if Path::new(&node.source).is_file() {
|
||||||
node.add_probe();
|
node.add_probe();
|
||||||
node.cmd = Some(seek_and_length(
|
node.cmd = Some(seek_and_length(
|
||||||
@ -307,7 +308,7 @@ fn gen_source(mut node: Media, config: &Config) -> Media {
|
|||||||
node.out,
|
node.out,
|
||||||
node.duration,
|
node.duration,
|
||||||
));
|
));
|
||||||
node.add_filter(&config);
|
node.add_filter();
|
||||||
} else {
|
} else {
|
||||||
if node.source.chars().count() == 0 {
|
if node.source.chars().count() == 0 {
|
||||||
warn!(
|
warn!(
|
||||||
@ -317,20 +318,20 @@ fn gen_source(mut node: Media, config: &Config) -> Media {
|
|||||||
} else {
|
} else {
|
||||||
error!("File not found: {}", node.source);
|
error!("File not found: {}", node.source);
|
||||||
}
|
}
|
||||||
let (source, cmd) = gen_dummy(node.out - node.seek, &config);
|
let (source, cmd) = gen_dummy(node.out - node.seek);
|
||||||
node.source = source;
|
node.source = source;
|
||||||
node.cmd = Some(cmd);
|
node.cmd = Some(cmd);
|
||||||
node.add_filter(&config);
|
node.add_filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
node
|
node
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_list_init(mut node: Media, config: &Config) -> Media {
|
fn handle_list_init(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
|
||||||
|
|
||||||
let (_, total_delta) = get_delta(&node.begin.unwrap(), config);
|
let (_, total_delta) = get_delta(&node.begin.unwrap());
|
||||||
let mut out = node.out;
|
let mut out = node.out;
|
||||||
|
|
||||||
if node.out - node.seek > total_delta {
|
if node.out - node.seek > total_delta {
|
||||||
@ -339,7 +340,7 @@ fn handle_list_init(mut node: Media, config: &Config) -> Media {
|
|||||||
|
|
||||||
node.out = out;
|
node.out = out;
|
||||||
|
|
||||||
let new_node = gen_source(node, &config);
|
let new_node = gen_source(node);
|
||||||
new_node
|
new_node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user