ffplayout/examples/watch.rs

142 lines
3.6 KiB
Rust
Raw Normal View History

2022-02-28 18:01:45 +01:00
use notify::DebouncedEvent::{Create, Remove, Rename};
use notify::{watcher, RecursiveMode, Watcher};
2022-02-27 22:15:10 +01:00
use std::{
2022-02-28 18:01:45 +01:00
ffi::OsStr,
2022-02-27 22:15:10 +01:00
path::Path,
2022-02-28 18:01:45 +01:00
sync::{
mpsc::{channel, Receiver},
{Arc, Mutex},
},
2022-02-27 22:15:10 +01:00
thread::sleep,
time::Duration,
};
2022-02-28 18:01:45 +01:00
use walkdir::WalkDir;
2022-02-27 22:15:10 +01:00
use tokio::runtime::Builder;
2022-02-28 18:01:45 +01:00
#[derive(Debug, Clone)]
pub struct Source {
nodes: Arc<Mutex<Vec<String>>>,
index: usize,
}
impl Source {
pub fn new(path: String) -> Self {
let mut file_list = vec![];
for entry in WalkDir::new(path.clone())
.into_iter()
.filter_map(|e| e.ok())
{
if entry.path().is_file() {
let ext = file_extension(entry.path());
if ext.is_some()
&& ["mp4".to_string(), "mkv".to_string()]
.clone()
.contains(&ext.unwrap().to_lowercase())
{
file_list.push(entry.path().display().to_string());
}
}
}
Self {
nodes: Arc::new(Mutex::new(file_list)),
index: 0,
}
}
}
impl Iterator for Source {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.nodes.lock().unwrap().len() {
let current_file = self.nodes.lock().unwrap()[self.index].clone();
self.index += 1;
Some(current_file)
} else {
let current_file = self.nodes.lock().unwrap()[0].clone();
self.index = 1;
Some(current_file)
2022-02-27 22:15:10 +01:00
}
}
}
2022-03-01 21:06:42 +01:00
async fn watch(receiver: Receiver<notify::DebouncedEvent>, sources: Arc<Mutex<Vec<String>>>) {
while let Ok(res) = receiver.recv() {
match res {
Create(new_path) => {
sources.lock().unwrap().push(new_path.display().to_string());
println!("Create new file: {:?}", new_path);
}
Remove(old_path) => {
sources
.lock()
.unwrap()
.retain(|x| x != &old_path.display().to_string());
println!("Remove file: {:?}", old_path);
}
Rename(old_path, new_path) => {
let i = sources
.lock()
.unwrap()
.iter()
.position(|x| *x == old_path.display().to_string())
.unwrap();
sources.lock().unwrap()[i] = new_path.display().to_string();
println!("Rename file: {:?} to {:?}", old_path, new_path);
2022-02-28 18:01:45 +01:00
}
2022-03-01 21:06:42 +01:00
_ => (),
2022-02-28 18:01:45 +01:00
}
}
}
fn file_extension(filename: &Path) -> Option<&str> {
filename.extension().and_then(OsStr::to_str)
}
fn main() {
2022-03-01 21:06:42 +01:00
let path = "/home/jb/Videos/tv-media/ADtv/01 - Intro".to_string();
2022-02-28 18:01:45 +01:00
let sources = Source::new(path.clone());
let (sender, receiver) = channel();
2022-02-27 22:15:10 +01:00
let runtime = Builder::new_multi_thread()
.worker_threads(1)
.thread_name("file_watcher")
.enable_all()
.build()
.expect("Creating Tokio runtime");
2022-02-28 18:01:45 +01:00
let mut watcher = watcher(sender, Duration::from_secs(2)).unwrap();
2022-03-01 21:06:42 +01:00
2022-02-28 18:01:45 +01:00
watcher
.watch(path.clone(), RecursiveMode::Recursive)
.unwrap();
2022-02-27 22:15:10 +01:00
2022-02-28 18:01:45 +01:00
runtime.spawn(watch(
receiver,
Arc::clone(&sources.nodes),
));
2022-02-27 22:15:10 +01:00
let mut count = 0;
2022-02-28 18:01:45 +01:00
2022-03-01 21:06:42 +01:00
for node in sources {
2022-02-28 18:01:45 +01:00
println!("task: {:?}", node);
2022-02-27 22:15:10 +01:00
sleep(Duration::from_secs(1));
count += 1;
2022-02-28 18:01:45 +01:00
if count == 5 {
2022-02-27 22:15:10 +01:00
break;
}
2022-03-01 21:06:42 +01:00
}
2022-02-27 22:15:10 +01:00
println!("after loop");
}