Merge pull request #347 from jb-alvarado/master

update sqlx to 0.7
This commit is contained in:
jb-alvarado 2023-07-09 14:29:01 +00:00 committed by GitHub
commit d0e83564de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 710 additions and 320 deletions

874
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9"
simplelog = { version = "^0.12", features = ["paris"] }
sqlx = { version = "0.6", features = ["runtime-tokio-rustls", "sqlite"] }
sqlx = { version = "0.7", features = ["runtime-tokio", "sqlite"] }
tokio = { version = "1.25", features = ["full"] }
[[bin]]

View File

@ -250,13 +250,19 @@ impl CurrentProgram {
if !self.playout_stat.list_init.load(Ordering::SeqCst) {
let time_sec = self.get_current_time();
let index = self.index.fetch_add(1, Ordering::SeqCst);
let nodes = self.nodes.lock().unwrap();
let last_index = nodes.len() - 1;
// de-instance node to preserve original values in list
let mut node_clone = self.nodes.lock().unwrap()[index].clone();
let mut node_clone = nodes[index].clone();
node_clone.seek = time_sec - node_clone.begin.unwrap();
self.current_node =
handle_list_init(&self.config, node_clone, &self.playout_stat.chain);
self.current_node = handle_list_init(
&self.config,
node_clone,
&self.playout_stat.chain,
last_index,
);
}
}
}
@ -269,6 +275,7 @@ impl Iterator for CurrentProgram {
self.check_update(self.playout_stat.list_init.load(Ordering::SeqCst));
if self.playout_stat.list_init.load(Ordering::SeqCst) {
trace!("Init playlist, from next iterator");
if self.json_path.is_some() {
self.init_clip();
}
@ -281,6 +288,7 @@ impl Iterator for CurrentProgram {
self.current_node = self.nodes.lock().unwrap()[last_index].clone();
let new_node = self.nodes.lock().unwrap()[last_index].clone();
let new_length = new_node.begin.unwrap() + new_node.duration;
trace!("Init playlist after playlist end");
self.check_for_next_playlist();
@ -304,13 +312,17 @@ impl Iterator for CurrentProgram {
current_time += self.config.playlist.length_sec.unwrap() + 1.0;
}
let mut media = Media::new(0, "", false);
let mut nodes = self.nodes.lock().unwrap();
let index = nodes.len();
let mut media = Media::new(index, "", false);
media.begin = Some(current_time);
media.duration = duration;
media.out = duration;
self.current_node = gen_source(&self.config, media, &self.playout_stat.chain);
let mut nodes = self.nodes.lock().unwrap();
self.current_node =
gen_source(&self.config, media, &self.playout_stat.chain, last_index);
nodes.push(self.current_node.clone());
self.index.store(nodes.len(), Ordering::SeqCst);
}
@ -326,8 +338,9 @@ impl Iterator for CurrentProgram {
let mut is_last = false;
let index = self.index.load(Ordering::SeqCst);
let nodes = self.nodes.lock().unwrap();
let last_index = nodes.len() - 1;
if index == nodes.len() - 1 {
if index == last_index {
is_last = true
}
@ -336,6 +349,7 @@ impl Iterator for CurrentProgram {
&self.config,
is_last,
&self.playout_stat,
last_index,
);
drop(nodes);
@ -370,6 +384,7 @@ impl Iterator for CurrentProgram {
&self.config,
self.current_node.clone(),
&self.playout_stat.chain,
0,
);
self.nodes.lock().unwrap().push(self.current_node.clone());
self.last_next_ad();
@ -385,10 +400,12 @@ impl Iterator for CurrentProgram {
// Get first clip from next playlist.
self.index.store(0, Ordering::SeqCst);
let last_index = self.nodes.lock().unwrap().len() - 1;
self.current_node = gen_source(
&self.config,
self.nodes.lock().unwrap()[0].clone(),
&self.playout_stat.chain,
last_index,
);
self.last_next_ad();
self.current_node.last_ad = last_ad;
@ -409,12 +426,15 @@ fn timed_source(
config: &PlayoutConfig,
last: bool,
playout_stat: &PlayoutStatus,
last_index: usize,
) -> Media {
let (delta, total_delta) = get_delta(config, &node.begin.unwrap());
let mut shifted_delta = delta;
let mut new_node = node.clone();
new_node.process = Some(false);
trace!("timed source ist last: {last}");
if config.playlist.length.contains(':') {
let time_shift = playout_stat.time_shift.lock().unwrap();
@ -443,11 +463,11 @@ fn timed_source(
{
// when we are in the 24 hour range, get the clip
new_node.process = Some(true);
new_node = gen_source(config, node, &playout_stat.chain);
new_node = gen_source(config, node, &playout_stat.chain, last_index);
} else if total_delta <= 0.0 {
info!("Begin is over play time, skip: {}", node.source);
} else if total_delta < node.duration - node.seek || last {
new_node = handle_list_end(config, node, total_delta, &playout_stat.chain);
new_node = handle_list_end(config, node, total_delta, &playout_stat.chain, last_index);
}
new_node
@ -458,6 +478,7 @@ pub fn gen_source(
config: &PlayoutConfig,
mut node: Media,
filter_chain: &Option<Arc<Mutex<Vec<String>>>>,
last_index: usize,
) -> Media {
let duration = node.out - node.seek;
@ -476,7 +497,16 @@ pub fn gen_source(
node.cmd = Some(seek_and_length(&node));
}
} else {
error!("Source not found: <b><magenta>\"{}\"</></b>", node.source);
trace!(
"clip index: {:?} | last index: {:?}",
node.index.unwrap_or_default(),
last_index
);
if node.index.unwrap_or_default() < last_index {
error!("Source not found: <b><magenta>\"{}\"</></b>", node.source);
}
warn!("Generate filler with <yellow>{duration:.2}</> seconds length!");
let probe = MediaProbe::new(&config.storage.filler_clip);
@ -532,6 +562,7 @@ fn handle_list_init(
config: &PlayoutConfig,
mut node: Media,
filter_chain: &Option<Arc<Mutex<Vec<String>>>>,
last_index: usize,
) -> Media {
debug!("Playlist init");
let (_, total_delta) = get_delta(config, &node.begin.unwrap());
@ -542,7 +573,8 @@ fn handle_list_init(
}
node.out = out;
gen_source(config, node, filter_chain)
gen_source(config, node, filter_chain, last_index)
}
/// when we come to last clip in playlist,
@ -553,6 +585,7 @@ fn handle_list_end(
mut node: Media,
total_delta: f64,
filter_chain: &Option<Arc<Mutex<Vec<String>>>>,
last_index: usize,
) -> Media {
debug!("Playlist end");
@ -580,5 +613,5 @@ fn handle_list_end(
node.process = Some(true);
gen_source(config, node, filter_chain)
gen_source(config, node, filter_chain, last_index)
}

View File

@ -2,7 +2,7 @@ use std::{
fs::{self, File},
path::{Path, PathBuf},
process::exit,
sync::{Arc, Mutex},
sync::{atomic::AtomicBool, Arc, Mutex},
thread,
};
@ -19,8 +19,9 @@ use ffplayout::{
};
use ffplayout_lib::utils::{
generate_playlist, import::import_file, init_logging, send_mail, validate_ffmpeg,
OutputMode::*, PlayerControl, PlayoutStatus, ProcessControl,
generate_playlist, get_date, import::import_file, init_logging, is_remote, send_mail,
validate_ffmpeg, validate_playlist, JsonPlaylist, OutputMode::*, PlayerControl, PlayoutStatus,
ProcessControl,
};
#[cfg(debug_assertions)]
@ -159,6 +160,39 @@ fn main() {
}
}
if args.validate {
let mut playlist_path = Path::new(&config.playlist.path).to_owned();
let start_sec = config.playlist.start_sec.unwrap();
let date = get_date(false, start_sec, 0.0);
if playlist_path.is_dir() || is_remote(&config.playlist.path) {
let d: Vec<&str> = date.split('-').collect();
playlist_path = playlist_path
.join(d[0])
.join(d[1])
.join(date.clone())
.with_extension("json");
}
let f = File::options()
.read(true)
.write(false)
.open(&playlist_path)
.expect("Could not open json playlist file.");
let playlist: JsonPlaylist = match serde_json::from_reader(f) {
Ok(p) => p,
Err(e) => {
error!("{e:?}");
exit(1)
}
};
validate_playlist(playlist, Arc::new(AtomicBool::new(false)), config);
exit(0);
}
if config.rpc_server.enable {
// If RPC server is enable we also fire up a JSON RPC server.
thread::spawn(move || run_server(config_clone, play_ctl, play_stat, proc_ctl2));

View File

@ -41,7 +41,7 @@ pub fn output(config: &PlayoutConfig, log_format: &str) -> process::Child {
}) {
enc_cmd.append(&mut cmd);
} else {
warn!("Given output parameter a skipped, they are not supported by ffplay!");
warn!("Given output parameters are skipped, they are not supported by ffplay!");
}
}

View File

@ -78,6 +78,9 @@ pub struct Args {
#[cfg(debug_assertions)]
#[clap(long, help = "fake date time, for debugging")]
pub fake_time: Option<String>,
#[clap(long, help = "validate given playlist")]
pub validate: bool,
}
/// Get arguments from command line, and return them.

View File

@ -39,6 +39,10 @@ pub fn get_config(args: Args) -> PlayoutConfig {
config.general.generate = Some(gen);
}
if args.validate {
config.general.validate = true;
}
if let Some(paths) = args.paths {
config.storage.paths = paths;
}

@ -1 +1 @@
Subproject commit 75515da508578700c82cd7ed916b9d3f2e4f1fdc
Subproject commit cf96eee7e3a233a0c58f833ff9443d869fa062b8

View File

@ -157,6 +157,9 @@ pub struct General {
#[serde(skip_serializing, skip_deserializing)]
pub ffmpeg_libs: Vec<String>,
#[serde(default, skip_serializing, skip_deserializing)]
pub validate: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone)]

View File

@ -50,7 +50,9 @@ pub fn import_file(
if !line.starts_with('#') {
let item = Media::new(0, &line, true);
playlist.program.push(item);
if item.duration > 0.0 {
playlist.program.push(item);
}
}
}

View File

@ -147,10 +147,16 @@ pub fn validate_playlist(
if valid_source(&item.source) {
if let Err(e) = check_media(item.clone(), pos, begin, &config) {
error!("{e}");
} else if config.general.validate {
debug!(
"Source at <yellow>{}</>, seems fine: <b><magenta>{}</></b>",
sec_to_time(begin),
item.source
)
};
} else {
error!(
"Source on position <yellow>{pos}</> {} not exists: <b><magenta>\"{}\"</></b>",
"Source on position <yellow>{pos}</> {} not exists: <b><magenta>{}</></b>",
sec_to_time(begin),
item.source
);

View File

@ -238,6 +238,7 @@ pub fn init_logging(
} else {
let term_config = log_config
.clone()
.set_level_color(Level::Trace, Some(Color::Ansi256(11)))
.set_level_color(Level::Debug, Some(Color::Ansi256(12)))
.set_level_color(Level::Info, Some(Color::Ansi256(10)))
.set_level_color(Level::Warn, Some(Color::Ansi256(208)))

View File

@ -113,7 +113,7 @@ impl Media {
let mut duration = 0.0;
let mut probe = None;
if do_probe && Path::new(src).is_file() {
if do_probe && (is_remote(src) || Path::new(src).is_file()) {
probe = Some(MediaProbe::new(src));
if let Some(dur) = probe

View File

@ -6,6 +6,10 @@ target=$1
echo "build frontend"
echo
if [ ! -f 'ffplayout-frontend/package.json' ]; then
git submodule update --init
fi
yes | rm -rf public
cd ffplayout-frontend

View File

@ -15,7 +15,7 @@ fn video_audio_input() {
config.processing.logo = logo_path.to_string_lossy().to_string();
let media_obj = Media::new(0, "./assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let test_filter_cmd =
vec_strings![
@ -41,7 +41,7 @@ fn video_audio_custom_filter1_input() {
config.processing.custom_filter = "[0:v]gblur=2[c_v_out];[0:a]volume=0.2[c_a_out]".to_string();
let media_obj = Media::new(0, "./assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let test_filter_cmd = vec_strings![
"-filter_complex",
@ -68,7 +68,7 @@ fn video_audio_custom_filter2_input() {
.to_string();
let media_obj = Media::new(0, "./assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let test_filter_cmd = vec_strings![
"-filter_complex",
@ -94,7 +94,7 @@ fn video_audio_custom_filter3_input() {
"[v_in];movie=logo.png[l];[v_in][l]overlay[c_v_out];[0:a]volume=0.2[c_a_out]".to_string();
let media_obj = Media::new(0, "./assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let test_filter_cmd = vec_strings![
"-filter_complex",
@ -119,7 +119,7 @@ fn dual_audio_aevalsrc_input() {
config.processing.add_logo = false;
let media_obj = Media::new(0, "./assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let test_filter_cmd =
vec_strings![
@ -145,7 +145,7 @@ fn dual_audio_input() {
config.processing.add_logo = false;
let media_obj = Media::new(0, "./assets/dual_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let test_filter_cmd = vec_strings![
"-filter_complex",
@ -171,7 +171,7 @@ fn video_separate_audio_input() {
let mut media_obj = Media::new(0, "./assets/no_audio.mp4", true);
media_obj.audio = "./assets/audio.mp3".to_string();
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let test_filter_cmd = vec_strings![
"-filter_complex",
@ -1333,7 +1333,7 @@ fn video_audio_hls() {
]);
let media_obj = Media::new(0, "./assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let enc_prefix = vec_strings![
"-hide_banner",
@ -1422,7 +1422,7 @@ fn video_audio_sub_meta_hls() {
]);
let media_obj = Media::new(0, "./assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let enc_prefix = vec_strings![
"-hide_banner",
@ -1512,7 +1512,7 @@ fn video_multi_audio_hls() {
]);
let media_obj = Media::new(0, "./assets/dual_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let enc_prefix = vec_strings![
"-hide_banner",
@ -1617,7 +1617,7 @@ fn multi_video_audio_hls() {
]);
let media_obj = Media::new(0, "./assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let enc_prefix = vec_strings![
"-hide_banner",
@ -1733,7 +1733,7 @@ fn multi_video_multi_audio_hls() {
]);
let media_obj = Media::new(0, "./assets/dual_audio.mp4", true);
let media = gen_source(&config, media_obj, &None);
let media = gen_source(&config, media_obj, &None, 1);
let enc_prefix = vec_strings![
"-hide_banner",