move config to global config.

This commit is contained in:
jb-alvarado 2022-03-13 22:18:53 +01:00
parent 8c55d20ed2
commit 37dd5a695c
13 changed files with 202 additions and 174 deletions

1
Cargo.lock generated
View File

@ -158,6 +158,7 @@ dependencies = [
"lettre",
"log",
"notify",
"once_cell",
"rand",
"regex",
"serde",

View File

@ -15,6 +15,7 @@ log = "0.4.14"
notify = "4.0.17"
rand = "0.8.5"
regex = "1"
once_cell = "1.10"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.8"

View File

@ -2,7 +2,7 @@ use std::path::Path;
use simplelog::*;
use crate::utils::{is_close, Config, Media};
use crate::utils::{is_close, GlobalConfig, Media};
#[derive(Debug, Clone)]
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 aspect < config.processing.aspect {
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 {
chain.add_filter(
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 {
chain.add_filter(
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
&& Path::new(&config.processing.logo).is_file()
&& 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 {
chain.add_filter(
format!("volume={}", config.processing.volume),
@ -248,7 +248,9 @@ fn fps_calc(r_frame_rate: String) -> f64 {
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 audio_map = "1:a".to_string();
filters.audio_map = Some(audio_map);

View File

@ -8,13 +8,12 @@ mod utils;
use simplelog::*;
use crate::output::play;
use crate::utils::{get_config, init_logging};
use crate::utils::{init_config, init_logging};
fn main() {
let config = get_config();
let logging = init_logging(&config);
init_config();
let logging = init_logging();
CombinedLogger::init(logging).unwrap();
play(config);
play();
}

View File

@ -5,9 +5,11 @@ use std::{
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_cmd = vec![

View File

@ -17,10 +17,12 @@ mod desktop;
mod stream;
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 mut thread_count = 2;
@ -34,7 +36,7 @@ pub fn play(config: Config) {
.build()
.unwrap();
let get_source = match config.processing.mode.clone().as_str() {
let get_source = match config.processing.clone().mode.as_str() {
"folder" => {
let path = config.storage.path.clone();
if !Path::new(&path).exists() {
@ -44,7 +46,7 @@ pub fn play(config: Config) {
info!("Playout in folder mode.");
let folder_source = Source::new(config.clone());
let folder_source = Source::new();
let (sender, receiver) = channel();
let mut watcher = watcher(sender, Duration::from_secs(2)).unwrap();
@ -60,7 +62,7 @@ pub fn play(config: Config) {
}
"playlist" => {
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!");
@ -68,13 +70,12 @@ pub fn play(config: Config) {
}
};
let config_clone = config.clone();
let dec_settings = config.processing.settings.unwrap();
let dec_settings = config.processing.clone().settings.unwrap();
let ff_log_format = format!("level+{}", config.logging.ffmpeg_level);
let mut enc_proc = match config.out.mode.as_str() {
"desktop" => desktop::output(config_clone, ff_log_format.clone()),
"stream" => stream::output(config_clone, ff_log_format.clone()),
"desktop" => desktop::output(ff_log_format.clone()),
"stream" => stream::output(ff_log_format.clone()),
_ => panic!("Output mode doesn't exists!"),
};

View File

@ -5,9 +5,10 @@ use std::{
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_cmd = vec![

View File

@ -1,12 +1,12 @@
use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};
use serde_yaml::{self};
use std::{fs::File, path::Path, process};
// use regex::Regex;
use crate::utils::{get_args, time_to_sec};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Config {
pub struct GlobalConfig {
pub general: General,
pub mail: Mail,
pub logging: Logging,
@ -108,115 +108,128 @@ pub struct Out {
pub stream_param: Vec<String>,
}
pub fn get_config() -> Config {
let args = get_args();
let mut config_path: String = "ffplayout.yml".to_string();
static INSTANCE: OnceCell<GlobalConfig> = OnceCell::new();
if args.config.is_some() {
config_path = args.config.unwrap();
} else if Path::new("/etc/ffplayout/ffplayout.yml").is_file() {
config_path = "/etc/ffplayout/ffplayout.yml".to_string();
}
impl GlobalConfig {
fn new() -> Self {
let args = get_args();
let mut config_path: String = "ffplayout.yml".to_string();
let f = match File::open(&config_path) {
Ok(file) => file,
Err(err) => {
println!(
"'{config_path}' doesn't exists!\n{}\n\nSystem error: {err}",
"Put 'ffplayout.yml' in '/etc/playout/' or beside the executable!"
);
process::exit(0x0100);
if args.config.is_some() {
config_path = args.config.unwrap();
} else if Path::new("/etc/ffplayout/ffplayout.yml").is_file() {
config_path = "/etc/ffplayout/ffplayout.yml".to_string();
}
};
let mut config: Config = serde_yaml::from_reader(f).expect("Could not read config file.");
let fps = config.processing.fps.to_string();
let bitrate = config.processing.width * config.processing.height / 10;
config.playlist.start_sec = Some(time_to_sec(&config.playlist.day_start));
let f = match File::open(&config_path) {
Ok(file) => file,
Err(err) => {
println!(
"'{config_path}' doesn't exists!\n{}\n\nSystem error: {err}",
"Put 'ffplayout.yml' in '/etc/playout/' or beside the executable!"
);
process::exit(0x0100);
}
};
if config.playlist.length.contains(":") {
config.playlist.length_sec = Some(time_to_sec(&config.playlist.length));
} else {
config.playlist.length_sec = Some(86400.0);
}
let settings = vec![
"-pix_fmt",
"yuv420p",
"-r",
&fps,
"-c:v",
"mpeg2video",
"-g",
"1",
"-b:v",
format!("{}k", bitrate).as_str(),
"-minrate",
format!("{}k", bitrate).as_str(),
"-maxrate",
format!("{}k", bitrate).as_str(),
"-bufsize",
format!("{}k", bitrate / 2).as_str(),
"-c:a",
"s302m",
"-strict",
"-2",
"-ar",
"48000",
"-ac",
"2",
"-f",
"mpegts",
"-",
]
.iter()
.map(|&s| s.into())
.collect();
config.processing.settings = Some(settings);
if args.log.is_some() {
config.logging.log_path = args.log.unwrap();
}
if args.playlist.is_some() {
config.playlist.path = args.playlist.unwrap();
}
if args.play_mode.is_some() {
config.processing.mode = args.play_mode.unwrap();
}
if args.folder.is_some() {
config.storage.path = args.folder.unwrap();
}
if args.start.is_some() {
config.playlist.day_start = args.start.clone().unwrap();
config.playlist.start_sec = Some(time_to_sec(&args.start.unwrap()));
}
if args.length.is_some() {
config.playlist.length = args.length.clone().unwrap();
let mut config: GlobalConfig = serde_yaml::from_reader(f).expect("Could not read config file.");
let fps = config.processing.fps.to_string();
let bitrate = config.processing.width * config.processing.height / 10;
config.playlist.start_sec = Some(time_to_sec(&config.playlist.day_start));
if config.playlist.length.contains(":") {
config.playlist.length_sec = Some(time_to_sec(&config.playlist.length));
} else {
config.playlist.length_sec = Some(86400.0);
}
let settings = vec![
"-pix_fmt",
"yuv420p",
"-r",
&fps,
"-c:v",
"mpeg2video",
"-g",
"1",
"-b:v",
format!("{}k", bitrate).as_str(),
"-minrate",
format!("{}k", bitrate).as_str(),
"-maxrate",
format!("{}k", bitrate).as_str(),
"-bufsize",
format!("{}k", bitrate / 2).as_str(),
"-c:a",
"s302m",
"-strict",
"-2",
"-ar",
"48000",
"-ac",
"2",
"-f",
"mpegts",
"-",
]
.iter()
.map(|&s| s.into())
.collect();
config.processing.settings = Some(settings);
if args.log.is_some() {
config.logging.log_path = args.log.unwrap();
}
if args.playlist.is_some() {
config.playlist.path = args.playlist.unwrap();
}
if args.play_mode.is_some() {
config.processing.mode = args.play_mode.unwrap();
}
if args.folder.is_some() {
config.storage.path = args.folder.unwrap();
}
if args.start.is_some() {
config.playlist.day_start = args.start.clone().unwrap();
config.playlist.start_sec = Some(time_to_sec(&args.start.unwrap()));
}
if args.length.is_some() {
config.playlist.length = args.length.clone().unwrap();
if config.playlist.length.contains(":") {
config.playlist.length_sec = Some(time_to_sec(&config.playlist.length));
} else {
config.playlist.length_sec = Some(86400.0);
}
}
if args.infinit {
config.playlist.infinit = args.infinit;
}
if args.output.is_some() {
config.out.mode = args.output.unwrap();
}
if args.volume.is_some() {
config.processing.volume = args.volume.unwrap();
}
config
}
if args.infinit {
config.playlist.infinit = args.infinit;
pub fn global() -> &'static GlobalConfig {
INSTANCE.get().expect("Config is not initialized")
}
if args.output.is_some() {
config.out.mode = args.output.unwrap();
}
if args.volume.is_some() {
config.processing.volume = args.volume.unwrap();
}
return config;
}
pub fn init_config() {
let config = GlobalConfig::new();
INSTANCE.set(config).unwrap();
}

View File

@ -12,17 +12,18 @@ use std::{
use walkdir::WalkDir;
use crate::utils::{Config, Media};
use crate::utils::{GlobalConfig, Media};
#[derive(Debug, Clone)]
pub struct Source {
config: Config,
config: GlobalConfig,
pub nodes: Arc<Mutex<Vec<String>>>,
index: usize,
}
impl Source {
pub fn new(config: Config) -> Self {
pub fn new() -> Self {
let config = GlobalConfig::global();
let mut file_list = vec![];
for entry in WalkDir::new(config.storage.path.clone())
@ -53,7 +54,7 @@ impl Source {
}
Self {
config: config,
config: config.clone(),
nodes: Arc::new(Mutex::new(file_list)),
index: 0,
}
@ -77,7 +78,7 @@ impl Iterator for Source {
let current_file = self.nodes.lock().unwrap()[self.index].clone();
let mut media = Media::new(self.index, current_file);
media.add_probe();
media.add_filter(&self.config);
media.add_filter();
self.index += 1;
Some(media)
@ -93,7 +94,7 @@ impl Iterator for Source {
let current_file = self.nodes.lock().unwrap()[0].clone();
let mut media = Media::new(self.index, current_file);
media.add_probe();
media.add_filter(&self.config);
media.add_filter();
self.index = 1;
Some(media)

View File

@ -3,7 +3,7 @@ use std::{fs::File, path::Path};
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;
@ -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 start = &config.playlist.day_start;
let mut start_sec = time_to_sec(start);

View File

@ -10,24 +10,21 @@ use simplelog::*;
use lettre::{transport::smtp::authentication::Credentials, Message, SmtpTransport, Transport};
use crate::utils;
use crate::utils::GlobalConfig;
pub struct LogMailer {
level: LevelFilter,
config: Config,
playout_config: utils::Config,
}
impl LogMailer {
pub fn new(
log_level: LevelFilter,
config: Config,
playout_config: &utils::Config,
) -> Box<LogMailer> {
Box::new(LogMailer {
level: log_level,
config,
playout_config: playout_config.clone(),
})
}
}
@ -40,8 +37,8 @@ impl Log for LogMailer {
fn log(&self, record: &Record<'_>) {
if self.enabled(record.metadata()) {
match record.level() {
Level::Error => send_mail(record.args().to_string(), &self.playout_config),
Level::Warn => 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()),
_ => (),
}
}
@ -72,7 +69,9 @@ fn clean_string(text: String) -> 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()
.from(config.mail.sender_addr.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 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
}
app_logger.push(LogMailer::new(filter, mail_config, config));
app_logger.push(LogMailer::new(filter, mail_config));
}
app_logger

View File

@ -21,7 +21,7 @@ mod logging;
mod playlist;
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 json_reader::{read_json, DUMMY_LEN};
pub use logging::init_logging;
@ -82,9 +82,9 @@ impl Media {
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();
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
}
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 start = config.playlist.start_sec.unwrap();
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)
}
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 {
error!("Start time out of sync for <yellow>{}</> seconds", delta);
return false;
@ -258,7 +261,8 @@ pub fn check_sync(delta: f64, config: &Config) -> bool {
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 source = format!(
"color=c={color}:s={}x{}:d={duration}",

View File

@ -4,12 +4,12 @@ use simplelog::*;
use crate::utils::{
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)]
pub struct CurrentProgram {
config: Config,
config: GlobalConfig,
start_sec: f64,
json_mod: Option<String>,
json_path: Option<String>,
@ -20,11 +20,12 @@ pub struct CurrentProgram {
}
impl CurrentProgram {
pub fn new(config: Config) -> Self {
let json = read_json(&config, true, 0.0);
pub fn new() -> Self {
let config = GlobalConfig::global();
let json = read_json(true, 0.0);
Self {
config,
config: config.clone(),
start_sec: json.start_sec.unwrap(),
json_mod: json.modified,
json_path: json.current_file,
@ -37,7 +38,7 @@ impl CurrentProgram {
fn check_update(&mut self, seek: bool) {
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_mod = json.modified;
@ -51,7 +52,7 @@ impl CurrentProgram {
.eq(&self.json_mod.clone().unwrap())
{
// 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.nodes = json.program;
@ -78,7 +79,7 @@ impl CurrentProgram {
let current_time = get_sec();
let start_sec = self.config.playlist.start_sec.unwrap();
let target_length = self.config.playlist.length_sec.unwrap();
let (delta, total_delta) = get_delta(&current_time, &self.config);
let (delta, total_delta) = get_delta(&current_time);
let mut duration = self.current_node.out.clone();
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, 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_mod = json.modified;
@ -139,7 +140,7 @@ impl CurrentProgram {
self.index = i + 1;
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;
}
start_sec += item.out - item.seek;
@ -176,7 +177,7 @@ impl Iterator for CurrentProgram {
self.get_init_clip();
} else {
let mut current_time = get_sec();
let (_, total_delta) = get_delta(&current_time, &self.config);
let (_, total_delta) = get_delta(&current_time);
let mut duration = DUMMY_LEN;
if DUMMY_LEN > total_delta {
@ -192,7 +193,7 @@ impl Iterator for CurrentProgram {
media.duration = 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.index = self.nodes.len();
}
@ -222,7 +223,7 @@ impl Iterator for CurrentProgram {
let last_playlist = self.json_path.clone();
self.check_for_next_playlist();
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);
if last_playlist == self.json_path
@ -240,17 +241,17 @@ impl Iterator for CurrentProgram {
}
self.current_node.duration = 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());
last_ad = self.is_ad(self.index, false);
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());
}
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.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
// check begin and length from clip
// 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();
new_node.process = Some(false);
if config.playlist.length.contains(":") {
debug!("Delta: <yellow>{delta}</>");
debug!("Total delta: <yellow>{total_delta}</>");
let sync = check_sync(delta, &config);
let sync = check_sync(delta);
if !sync {
new_node.cmd = None;
@ -287,7 +288,7 @@ fn timed_source(node: Media, config: &Config, last: bool) -> Media {
|| !config.playlist.length.contains(":")
{
// 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);
} else if total_delta <= 0.0 {
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
}
fn gen_source(mut node: Media, config: &Config) -> Media {
fn gen_source(mut node: Media) -> Media {
if Path::new(&node.source).is_file() {
node.add_probe();
node.cmd = Some(seek_and_length(
@ -307,7 +308,7 @@ fn gen_source(mut node: Media, config: &Config) -> Media {
node.out,
node.duration,
));
node.add_filter(&config);
node.add_filter();
} else {
if node.source.chars().count() == 0 {
warn!(
@ -317,20 +318,20 @@ fn gen_source(mut node: Media, config: &Config) -> Media {
} else {
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.cmd = Some(cmd);
node.add_filter(&config);
node.add_filter();
}
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,
// 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;
if node.out - node.seek > total_delta {
@ -339,7 +340,7 @@ fn handle_list_init(mut node: Media, config: &Config) -> Media {
node.out = out;
let new_node = gen_source(node, &config);
let new_node = gen_source(node);
new_node
}