Created player monitor loop

This commit is contained in:
G2-Games 2024-12-29 01:13:29 -06:00
parent eda7e6f200
commit 75393a010e
4 changed files with 131 additions and 82 deletions

View file

@ -4,12 +4,14 @@
#![allow(while_true)] #![allow(while_true)]
use chrono::TimeDelta; use chrono::TimeDelta;
use crossbeam::atomic::AtomicCell;
use kushi::{Queue, QueueItemType}; use kushi::{Queue, QueueItemType};
use kushi::{QueueError, QueueItem}; use kushi::{QueueError, QueueItem};
use prismriver::{Prismriver, Volume, Error as PrismError}; use prismriver::{Prismriver, Volume, Error as PrismError};
use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::to_string_pretty; use serde_json::to_string_pretty;
use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::Write; use std::io::Write;
@ -158,7 +160,7 @@ pub struct ControllerInput {
), ),
library: MusicLibrary, library: MusicLibrary,
config: Arc<RwLock<Config>>, config: Arc<RwLock<Config>>,
playback_info: crossbeam::channel::Sender<PlaybackInfo>, playback_info: Arc<AtomicCell<PlaybackInfo>>,
} }
pub struct ControllerHandle { pub struct ControllerHandle {
@ -168,11 +170,11 @@ pub struct ControllerHandle {
} }
impl ControllerHandle { impl ControllerHandle {
pub fn new(library: MusicLibrary, config: Arc<RwLock<Config>>) -> (Self, ControllerInput, crossbeam::channel::Receiver<PlaybackInfo>) { pub fn new(library: MusicLibrary, config: Arc<RwLock<Config>>) -> (Self, ControllerInput, Arc<AtomicCell<PlaybackInfo>>) {
let lib_mail = MailMan::double(); let lib_mail = MailMan::double();
let player_mail = MailMan::double(); let player_mail = MailMan::double();
let queue_mail = MailMan::double(); let queue_mail = MailMan::double();
let (playback_info_rx, playback_info_tx) = crossbeam::channel::bounded(1); let playback_info = Arc::new(AtomicCell::new(PlaybackInfo::default()));
( (
ControllerHandle { ControllerHandle {
lib_mail: lib_mail.0.clone(), lib_mail: lib_mail.0.clone(),
@ -185,9 +187,9 @@ impl ControllerHandle {
queue_mail, queue_mail,
library, library,
config, config,
playback_info: playback_info_rx, playback_info: Arc::clone(&playback_info),
}, },
playback_info_tx, playback_info,
) )
} }
} }
@ -253,13 +255,16 @@ impl Controller {
} }
}; };
let player = Arc::new(RwLock::new(Prismriver::new()));
std::thread::scope(|scope| { std::thread::scope(|scope| {
let queue_mail = queue_mail; let a = scope.spawn({
let a = scope.spawn(|| { let player = Arc::clone(&player);
let queue_mail = queue_mail.clone();
move || {
futures::executor::block_on(async { futures::executor::block_on(async {
moro::async_scope!(|scope| { moro::async_scope!(|scope| {
println!("async scope created"); println!("async scope created");
let player = Arc::new(RwLock::new(Prismriver::new()));
let _player = player.clone(); let _player = player.clone();
let _lib_mail = lib_mail.0.clone(); let _lib_mail = lib_mail.0.clone();
@ -276,17 +281,6 @@ impl Controller {
.await .await
.unwrap(); .unwrap();
}); });
scope
.spawn(async move {
Controller::player_monitor_loop(
player,
player_mail.0,
queue_mail.0,
playback_info,
)
.await
.unwrap();
});
scope scope
.spawn(async { .spawn(async {
Controller::library_loop( Controller::library_loop(
@ -300,6 +294,7 @@ impl Controller {
}) })
.await; .await;
}) })
}
}); });
let b = scope.spawn(|| { let b = scope.spawn(|| {
@ -307,8 +302,19 @@ impl Controller {
Controller::queue_loop(queue, queue_mail.1).await; Controller::queue_loop(queue, queue_mail.1).await;
}) })
}); });
let c = scope.spawn(|| {
Controller::player_monitor_loop(
player,
player_mail.0,
queue_mail.0,
playback_info,
).unwrap();
});
a.join().unwrap(); a.join().unwrap();
b.join().unwrap(); b.join().unwrap();
c.join().unwrap();
}); });
Ok(()) Ok(())
@ -532,20 +538,48 @@ impl Controller {
Ok(()) Ok(())
} }
async fn player_monitor_loop( fn player_monitor_loop(
player: Arc<RwLock<Prismriver>>, player: Arc<RwLock<Prismriver>>,
player_mail: MailMan<PlayerCommand, PlayerResponse>, player_mail: MailMan<PlayerCommand, PlayerResponse>,
queue_mail: MailMan<QueueCommand, QueueResponse>, queue_mail: MailMan<QueueCommand, QueueResponse>,
player_info: crossbeam_channel::Sender<PlaybackInfo> player_info: Arc<AtomicCell<PlaybackInfo>>,
) -> Result<(), ()> { ) -> Result<(), ()> {
let finished_recv = player.read().unwrap().get_finished_recv();
std::thread::scope(|s| {
// Thread for timing and metadata
s.spawn({
let player = Arc::clone(&player);
move || {
while true {
let player = player.read().unwrap();
player_info.store(PlaybackInfo {
duration: player.duration(),
position: player.position(),
metadata: player.metadata(),
});
drop(player);
std::thread::sleep(Duration::from_millis(100));
}
}
});
// Thread for End of Track
s.spawn(move || {
while true {
let _ = finished_recv.recv();
std::thread::sleep(Duration::from_millis(100));
}
});
});
// Check for duration and spit it out
// Check for end of song to get the next
Ok(()) Ok(())
// std::thread::scope(|s| {
// });
// // Check for duration and spit it out
// // Check for end of song to get the next
// Ok(())
} }
@ -590,6 +624,7 @@ impl Controller {
} }
Ok(()) Ok(())
} }
async fn queue_loop( async fn queue_loop(
mut queue: Queue<QueueSong, QueueAlbum>, mut queue: Queue<QueueSong, QueueAlbum>,
queue_mail: MailMan<QueueResponse, QueueCommand>, queue_mail: MailMan<QueueResponse, QueueCommand>,
@ -646,8 +681,9 @@ impl Controller {
} }
} }
#[derive(Debug)] #[derive(Debug, Default)]
pub struct PlaybackInfo { pub struct PlaybackInfo {
pub duration: TimeDelta, pub duration: Option<TimeDelta>,
pub position: TimeDelta pub position: Option<TimeDelta>,
pub metadata: HashMap<String, String>,
} }

View file

@ -1033,7 +1033,6 @@ impl MusicLibrary {
sort_by: &Vec<Tag>, // Tags to sort the resulting data by sort_by: &Vec<Tag>, // Tags to sort the resulting data by
) -> Option<Vec<&Song>> { ) -> Option<Vec<&Song>> {
let songs = Arc::new(Mutex::new(Vec::new())); let songs = Arc::new(Mutex::new(Vec::new()));
//let matcher = SkimMatcherV2::default();
self.library.par_iter().for_each(|track| { self.library.par_iter().for_each(|track| {
for tag in target_tags { for tag in target_tags {
@ -1048,18 +1047,6 @@ impl MusicLibrary {
}, },
}; };
/*
let match_level = match matcher.fuzzy_match(&normalize(&track_result), &normalize(query_string)) {
Some(conf) => conf,
None => continue
};
if match_level > 100 {
songs.lock().unwrap().push(track);
return;
}
*/
if normalize(&track_result.to_string()) if normalize(&track_result.to_string())
.contains(&normalize(&query_string.to_owned())) .contains(&normalize(&query_string.to_owned()))
{ {
@ -1249,13 +1236,13 @@ impl MusicLibrary {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::{ use std::{path::PathBuf, time::Instant};
path::PathBuf, use crate::music_storage::library::Tag;
sync::{Arc, RwLock},
}; use uuid::Uuid;
use crate::{ use crate::{
config::{tests::new_config_lib, Config}, config::Config,
music_storage::library::MusicLibrary, music_storage::library::MusicLibrary,
}; };
@ -1270,4 +1257,31 @@ mod test {
.unwrap(); .unwrap();
dbg!(a); dbg!(a);
} }
#[test]
fn library_search() {
let lib = MusicLibrary::init(
PathBuf::from("/media/g2/Storage4/Media-Files/Music/Albums/library.dlib"),
Uuid::new_v4(),
).unwrap();
let timer = Instant::now();
let result = lib.query_tracks(
&String::from(""),
&vec![],
&vec![
Tag::Field("location".to_string()),
Tag::Album,
Tag::Disk,
Tag::Track,
],
).unwrap();
println!("{} songs in {}ms", result.len(), timer.elapsed().as_millis());
/*
for song in result {
println!("{:?}", song.tags.get(&Tag::Title));
}
*/
}
} }

View file

@ -20,7 +20,6 @@ pub fn run() {
let (rx, tx) = unbounded::<Config>(); let (rx, tx) = unbounded::<Config>();
let (lib_rx, lib_tx) = unbounded::<Option<PathBuf>>(); let (lib_rx, lib_tx) = unbounded::<Option<PathBuf>>();
let (handle_rx, handle_tx) = unbounded::<ControllerHandle>(); let (handle_rx, handle_tx) = unbounded::<ControllerHandle>();
let (playback_handle_rx, playback_handle_tx) = unbounded::<crossbeam::channel::Receiver<PlaybackInfo>>();
let controller_thread = spawn(move || { let controller_thread = spawn(move || {
let mut config = { tx.recv().unwrap() } ; let mut config = { tx.recv().unwrap() } ;
@ -55,7 +54,7 @@ pub fn run() {
library.save(save_path).unwrap(); library.save(save_path).unwrap();
let (handle, input, playback_tx) = ControllerHandle::new( let (handle, input, playback_info) = ControllerHandle::new(
library, library,
std::sync::Arc::new(std::sync::RwLock::new(config)) std::sync::Arc::new(std::sync::RwLock::new(config))
); );