diff --git a/Cargo.lock b/Cargo.lock index 15c8c4d4..9f220823 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -34,6 +34,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "chrono" version = "0.4.19" @@ -44,7 +56,7 @@ dependencies = [ "num-integer", "num-traits", "time", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -83,9 +95,70 @@ version = "0.1.0" dependencies = [ "chrono", "clap", + "notify", + "rand", "regex", "serde", "serde_yaml", + "walkdir", +] + +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "winapi 0.3.9", +] + +[[package]] +name = "fsevent" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +dependencies = [ + "bitflags", + "fsevent-sys", +] + +[[package]] +name = "fsevent-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" +dependencies = [ + "libc", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "getrandom" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", ] [[package]] @@ -119,12 +192,57 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inotify" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.117" @@ -137,12 +255,93 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "memchr" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio", + "slab", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "notify" +version = "4.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" +dependencies = [ + "bitflags", + "filetime", + "fsevent", + "fsevent-sys", + "inotify", + "libc", + "mio", + "mio-extras", + "walkdir", + "winapi 0.3.9", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -171,6 +370,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -213,6 +418,45 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.5.4" @@ -236,6 +480,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "serde" version = "1.0.136" @@ -268,6 +521,12 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + [[package]] name = "strsim" version = "0.10.0" @@ -302,13 +561,12 @@ checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" [[package]] name = "time" -version = "0.1.44" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "wasi", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -324,10 +582,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +name = "walkdir" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi 0.3.9", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" @@ -339,6 +614,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -351,7 +632,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -360,6 +641,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index 0f2604b5..98a2d8c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,10 @@ serde_yaml = "0.8" regex = "1" chrono = "0.4" clap = { version = "3.0.14", features = ["derive"] } +notify = "4.0.0" +walkdir = "2" +rand = "0.8.5" +# tokio = { version = "1.16.1", features = ["full"] } [[bin]] name = "ffplayout" diff --git a/ffplayout.yml b/ffplayout.yml index b29eb285..5e6e29ba 100644 --- a/ffplayout.yml +++ b/ffplayout.yml @@ -58,6 +58,7 @@ processing: loud_tp: -1.5 loud_lra: 11 output_count: 1 + volume: 1 ingest: helptext: Works not with direct hls output, it always needs full processing! Run a server @@ -73,12 +74,12 @@ playlist: script. Subdirectories needs this structure '/playlists/2018/01'. 'day_start' means at which time the playlist should start, leave day_start blank when playlist should always start at the begin. 'length' represent the target length from - playlist, when is blank real length will not consider. 'loop true' works with + playlist, when is blank real length will not consider. 'infinit true' works with single playlist file and loops it infinitely. path: "/playlists" day_start: "5:59:25" length: "24:00:00" - loop: false + infinit: false storage: helptext: Play ordered or randomly files from path. 'filler_clip' is for fill @@ -87,8 +88,8 @@ storage: path: "/mediaStorage" filler_clip: "/mediaStorage/filler/filler.mp4" extensions: - - ".mp4" - - ".mkv" + - "mp4" + - "mkv" shuffle: true text: diff --git a/src/folder.rs b/src/folder.rs new file mode 100644 index 00000000..afa0a2d6 --- /dev/null +++ b/src/folder.rs @@ -0,0 +1,109 @@ +use notify::DebouncedEvent::{Create, Remove, Rename}; +use notify::{watcher, RecursiveMode, Watcher}; +use rand::seq::SliceRandom; +use rand::thread_rng; +use std::ffi::OsStr; +use std::path::Path; +use std::process; +use std::sync::mpsc::{channel, Receiver}; +use std::time::Duration; +use std::{thread, time}; +use walkdir::WalkDir; + +#[derive(Clone)] +struct Source { + files: Vec, +} + +impl Source { + fn new(path: &String, extensions: &Vec) -> Self { + let mut file_list = vec![]; + + for entry in WalkDir::new(path).into_iter().filter_map(|e| e.ok()) { + if entry.path().is_file() { + let ext = file_extension(entry.path()).unwrap().to_lowercase(); + + if extensions.contains(&ext) { + file_list.push(entry.path().display().to_string()); + } + } + } + + Self { files: file_list } + } + + fn push(&mut self, file: String) { + self.files.push(file) + } + + fn rm(&mut self, file: String) { + self.files.retain(|x| x != &file); + } + + fn mv(&mut self, old_file: String, new_file: String) { + let i = self.files.iter().position(|x| *x == old_file).unwrap(); + self.files[i] = new_file; + } + + fn shuffle(&mut self) { + let mut rng = thread_rng(); + self.files.shuffle(&mut rng); + } +} + +fn file_extension(filename: &Path) -> Option<&str> { + filename.extension().and_then(OsStr::to_str) +} + +fn watch_folder(source: &mut Source, receiver: &Receiver) { + match receiver.try_recv() { + Ok(event) => match event { + Create(new_path) => { + println!("Create new file: {:?}", new_path); + source.push(new_path.display().to_string()); + } + Remove(old_path) => { + println!("Remove file: {:?}", old_path); + source.rm(old_path.display().to_string()); + } + Rename(old_path, new_path) => { + println!("Rename file: {:?} to {:?}", old_path, new_path); + source.mv( + old_path.display().to_string(), + new_path.display().to_string(), + ); + } + _ => (), + }, + Err(_) => (), + } +} + +pub fn walk(path: &String, shuffle: bool, extensions: &Vec) { + if !Path::new(path).exists() { + println!("Folder path not exists: '{}'", path); + process::exit(0x0100); + } + let mut source = Source::new(path, extensions); + let mut index: usize = 0; + + let (sender, receiver) = channel(); + let mut watcher = watcher(sender, Duration::from_secs(2)).unwrap(); + watcher.watch(path, RecursiveMode::Recursive).unwrap(); + + loop { + if shuffle { + println!("Shuffle files in folder"); + source.shuffle(); + } + + while index < source.files.len() { + watch_folder(&mut source, &receiver); + println!("Play file {}: {:?}", index, source.files[index]); + index += 1; + + thread::sleep(time::Duration::from_secs(1)); + } + index = 0 + } +} diff --git a/src/main.rs b/src/main.rs index 36afabe5..8e2c5eae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,19 @@ mod arg_parse; -mod config_reader; +mod config; mod utils; +mod folder; fn main() { - //println!("{:#?}", utils::Mail()); - let config = config_reader::read_yaml(); + let config = config::get_config(); + // println!("{:#?}", config); + + folder::walk(&config.storage.path, config.storage.shuffle, &config.storage.extensions); + let args = arg_parse::get_args(); - println!("{:#?}", config); + println!("{:#?}", args); println!("{:#?}", args.config.is_some()); - println!("{:#?}", args.config.unwrap()); + // println!("{:#?}", args.config.unwrap()); //println!("{:?}", config.general.stop_threshold); println!("{:#?}", utils::get_sec());