add simple playlist generator

This commit is contained in:
jb-alvarado 2022-04-14 11:50:29 +02:00
parent 614aa7851c
commit 11c577aff5
6 changed files with 72 additions and 32 deletions

2
Cargo.lock generated
View File

@ -167,7 +167,7 @@ dependencies = [
[[package]]
name = "ffplayout-rs"
version = "0.9.2"
version = "0.9.3"
dependencies = [
"chrono",
"clap",

View File

@ -4,7 +4,7 @@ description = "24/7 playout based on rust and ffmpeg"
license = "GPL-3.0"
authors = ["Jonathan Baecker jonbae77@gmail.com"]
readme = "README.md"
version = "0.9.2"
version = "0.9.3"
edition = "2021"
[dependencies]
@ -47,7 +47,6 @@ section = "net"
license-file = ["LICENSE", "0"]
depends = ""
suggests = "ffmpeg"
maintainer-scripts = "package/debian/"
copyright = "Copyright (c) 2022, Jonathan Baecker. All rights reserved."
assets = [
["target/x86_64-unknown-linux-musl/release/ffplayout", "/usr/bin/ffplayout", "755"],

View File

@ -68,9 +68,8 @@ fn main() {
validate_ffmpeg();
if config.general.generate.is_some() {
// generate playlist from given dates
generate_playlist();
if let Some(range) = config.general.generate.clone() {
generate_playlist(range);
exit(0);
}

View File

@ -2,7 +2,7 @@ use clap::Parser;
#[derive(Parser, Debug)]
#[clap(version,
about = "ffplayout, Rust based 24/7 playout solution",
about = "ffplayout, Rust based 24/7 playout solution.\n\nRun without any command to use config file only, or with commands to override parameters.",
long_about = None)]
pub struct Args {
#[clap(short, long, help = "File path to ffplayout.conf")]
@ -14,7 +14,8 @@ pub struct Args {
#[clap(
short,
long,
help = "Generate playlist for given date. Date needs format: YYYY-MM-DD. Date-range is possible to, like: 2022-01-01 - 2022-01-10.",
help = "Generate playlist for date. Date-range is possible, like: 2022-01-01 - 2022-01-10.",
name = "YYYY-MM-DD",
multiple_values=true
)]
pub generate: Option<Vec<String>>,

View File

@ -1,4 +1,6 @@
use std::{
fs::{create_dir_all, write},
path::Path,
process::exit,
sync::{Arc, Mutex},
};
@ -44,25 +46,59 @@ fn get_date_range(date_range: &Vec<String>) -> Vec<String> {
range
}
pub fn generate_playlist() {
pub fn generate_playlist(mut date_range: Vec<String>) {
let config = GlobalConfig::global();
let mut date_range = config.general.generate.clone().unwrap();
let total_length = config.playlist.length_sec.unwrap().clone();
let current_list = Arc::new(Mutex::new(vec![Media::new(0, "".to_string(), false)]));
let index = Arc::new(Mutex::new(0));
let playlist_root = Path::new(&config.playlist.path);
if !playlist_root.is_dir() {
error!(
"Playlist folder <b><magenta>{}</></b> not exists!",
&config.playlist.path
);
exit(1);
}
if date_range.contains(&"-".to_string()) && date_range.len() == 3 {
date_range = get_date_range(&date_range)
}
let media_list = Source::new(current_list, index);
let list_length = media_list.nodes.lock().unwrap().len();
for date in date_range {
info!("Generate playlist for {date}");
let d: Vec<&str> = date.split('-').collect();
let year = d[0];
let month = d[1];
let playlist_path = playlist_root.join(year).join(month);
let playlist_file = &playlist_path.join(format!("{date}.json"));
if let Err(e) = create_dir_all(playlist_path) {
error!("Create folder failed: {e:?}");
exit(1);
}
if playlist_file.is_file() {
warn!(
"Playlist exists, skip: <b><magenta>{}</></b>",
playlist_file.display()
);
continue;
}
info!(
"Generate playlist: <b><magenta>{}</></b>",
playlist_file.display()
);
let mut filler = Media::new(0, config.storage.filler_clip.clone(), true);
let filler_length = filler.duration.clone();
let mut length = 0.0;
let mut round = 0;
let mut playlist = Playlist {
date,
@ -72,33 +108,36 @@ pub fn generate_playlist() {
program: vec![],
};
let mut round = 0;
for item in media_list.clone() {
let duration = item.duration.clone();
if total_length > length + filler_length {
if total_length > length + duration {
playlist.program.push(item);
length += duration;
} else if filler_length > 0.0 && filler_length > total_length - length {
println!("{filler_length}");
filler.out = filler_length - (total_length - length);
println!("{}", total_length - length);
playlist.program.push(filler);
break;
} else if round == 3 {
println!("break");
println!("length {length}");
println!("total_length {total_length}");
} else if round == list_length - 1 {
break;
} else {
round += 1;
}
}
println!("{length:?}");
println!("{:?}", playlist.program[playlist.program.len() - 1]);
let json: String = match serde_json::to_string_pretty(&playlist) {
Ok(j) => j,
Err(e) => {
error!("Unable to serialize data: {e:?}");
exit(0);
}
};
if let Err(e) = write(playlist_file, &json) {
error!("Unable to write playlist: {e:?}");
exit(1)
};
}
}

View File

@ -47,7 +47,7 @@ pub struct Media {
pub out: f64,
pub duration: f64,
#[serde(skip_deserializing)]
#[serde(skip_serializing)]
pub category: Option<String>,
pub source: String,
@ -102,17 +102,19 @@ impl Media {
}
pub fn add_probe(&mut self) {
let probe = MediaProbe::new(self.source.clone());
self.probe = Some(probe.clone());
if self.probe.is_none() {
let probe = MediaProbe::new(self.source.clone());
self.probe = Some(probe.clone());
if self.duration == 0.0 {
let duration = match probe.format.unwrap().duration {
Some(dur) => dur.parse().unwrap(),
None => 0.0,
};
if self.duration == 0.0 {
let duration = match probe.format.unwrap().duration {
Some(dur) => dur.parse().unwrap(),
None => 0.0,
};
self.out = duration;
self.duration = duration;
self.out = duration;
self.duration = duration;
}
}
}