From b8f942feb1d26ca0cb261733bfe9d9730e2d42c2 Mon Sep 17 00:00:00 2001 From: MrDulfin Date: Wed, 1 Jan 2025 16:38:41 -0500 Subject: [PATCH] Updated Prismriver and fixed scrobbling timing --- dmp-core/src/music_controller/connections.rs | 73 ++++++++----------- dmp-core/src/music_controller/controller.rs | 2 + .../src/music_controller/player_monitor.rs | 27 +++++-- src-tauri/tauri.conf.json | 7 +- 4 files changed, 57 insertions(+), 52 deletions(-) diff --git a/dmp-core/src/music_controller/connections.rs b/dmp-core/src/music_controller/connections.rs index 52afdc4..82485c7 100644 --- a/dmp-core/src/music_controller/connections.rs +++ b/dmp-core/src/music_controller/connections.rs @@ -9,7 +9,7 @@ use std::{ use chrono::TimeDelta; use crossbeam::{scope, select}; -use crossbeam_channel::{bounded, Receiver}; +use crossbeam_channel::{unbounded, Receiver}; use discord_presence::Client; use listenbrainz::ListenBrainz; use parking_lot::RwLock; @@ -30,6 +30,7 @@ pub(super) enum ConnectionsNotification { }, StateChange(PrismState), SongChange(Song), + AboutToFinish, EOS, } @@ -56,10 +57,11 @@ impl Controller { }, }: ControllerConnections, ) { - let (dc_state_rx, dc_state_tx) = bounded::(1); - let (dc_song_rx, dc_song_tx) = bounded::(1); - let (lb_song_rx, lb_song_tx) = bounded::(1); - let (lb_eos_rx, lb_eos_tx) = bounded::<()>(1); + let (dc_state_rx, dc_state_tx) = unbounded::(); + let (dc_song_rx, dc_song_tx) = unbounded::(); + let (lb_song_rx, lb_song_tx) = unbounded::(); + let (lb_abt_fin_rx, lb_abt_fn_tx) = unbounded::<()>(); + let (lb_eos_rx, lb_eos_tx) = unbounded::<()>(); scope(|s| { s.builder() @@ -87,6 +89,11 @@ impl Controller { lb_eos_rx.send(()).unwrap(); } } + AboutToFinish => { + if LB_ACTIVE.load(Ordering::Relaxed) { + lb_abt_fin_rx.send(()).unwrap(); + } + } } } }) @@ -105,7 +112,7 @@ impl Controller { s.builder() .name("ListenBrainz Handler".to_string()) .spawn(move |_| { - Controller::listenbrainz_scrobble(&token, lb_song_tx, lb_eos_tx); + Controller::listenbrainz_scrobble(&token, lb_song_tx, lb_abt_fn_tx, lb_eos_tx); }) .unwrap(); } @@ -199,7 +206,7 @@ impl Controller { DC_ACTIVE.store(false, Ordering::Relaxed); } - fn listenbrainz_scrobble(token: &str, song_tx: Receiver, eos_tx: Receiver<()>) { + fn listenbrainz_scrobble(token: &str, song_tx: Receiver, abt_fn_tx: Receiver<()>, eos_tx: Receiver<()>) { let mut client = ListenBrainz::new(); client.authenticate(token).unwrap(); if !client.is_authenticated() { @@ -207,10 +214,14 @@ impl Controller { } let mut song: Option = None; + let mut last_song: Option = None; LB_ACTIVE.store(true, Ordering::Relaxed); + println!("ListenBrainz connected"); while true { let song = &mut song; + let last_song = &mut last_song; + let client = &client; select! { recv(song_tx) -> res => { @@ -225,13 +236,19 @@ impl Controller { } else { continue }; - client.playing_now(artist, title, None).unwrap(); + let release = _song.get_tag(&Tag::Key(String::from("MusicBrainzReleaseId"))).map(|id| id.as_str()); + + client.playing_now(artist, title, release).unwrap(); + println!("Song Listening = {artist} - {title}"); *song = Some(_song); - println!("Song Listening") } }, + recv(abt_fn_tx) -> _ => { + *last_song = song.take(); + println!("song = {:?}", last_song.as_ref().map(|s| s.get_tag(&Tag::Title).map_or("No Title", |t| t.as_str()))); + }, recv(eos_tx) -> _ => { - if let Some(song) = song { + if let Some(song) = last_song { let artist = if let Some(tag) = song.get_tag(&Tag::Artist) { tag.as_str() } else { @@ -242,7 +259,9 @@ impl Controller { } else { continue }; - client.listen(artist, title, None).unwrap(); + let release = song.get_tag(&Tag::Key(String::from("MusicBrainzReleaseId"))).map(|id| id.as_str()); + + client.listen(artist, title, release).unwrap(); println!("Song Scrobbled"); } } @@ -250,34 +269,4 @@ impl Controller { } LB_ACTIVE.store(false, Ordering::Relaxed); } -} - -#[cfg(test)] -mod test_super { - use std::thread::{sleep, spawn}; - - use crossbeam_channel::unbounded; - - use crate::config::tests::read_config_lib; - - use super::*; - - #[test] - fn lb_test() { - let (song_rx, song_tx) = unbounded(); - let (eos_rx, eos_tx) = unbounded(); - - let (config, lib) = read_config_lib(); - song_rx.send(lib.library[0].clone()).unwrap(); - spawn(|| { - Controller::listenbrainz_scrobble( - config.connections.listenbrainz_token.unwrap().as_str(), - song_tx, - eos_tx, - ); - }); - sleep(Duration::from_secs(10)); - eos_rx.send(()).unwrap(); - sleep(Duration::from_secs(10)); - } -} +} \ No newline at end of file diff --git a/dmp-core/src/music_controller/controller.rs b/dmp-core/src/music_controller/controller.rs index 3259787..ea63369 100644 --- a/dmp-core/src/music_controller/controller.rs +++ b/dmp-core/src/music_controller/controller.rs @@ -277,6 +277,7 @@ impl Controller { let player = Prismriver::new(); let player_state = player.state.clone(); let player_timing = player.get_timing_recv(); + let about_to_finish_tx = player.get_about_to_finish_recv(); let finished_tx = player.get_finished_recv(); let (notifications_rx, notifications_tx) = crossbeam_channel::unbounded::(); @@ -325,6 +326,7 @@ impl Controller { Controller::player_monitor_loop( player_state, player_timing, + about_to_finish_tx, finished_tx, player_mail.0, notify_next_song, diff --git a/dmp-core/src/music_controller/player_monitor.rs b/dmp-core/src/music_controller/player_monitor.rs index 4ad4b95..b80a4bf 100644 --- a/dmp-core/src/music_controller/player_monitor.rs +++ b/dmp-core/src/music_controller/player_monitor.rs @@ -20,7 +20,8 @@ impl Controller { pub(super) fn player_monitor_loop( playback_state: Arc>, playback_time_tx: Receiver<(Option, Option)>, - finished_recv: Receiver<()>, + about_to_finish_tx: Receiver<()>, + finished_tx: Receiver<()>, player_mail: async_channel::Sender, notify_next_song: Sender, notify_connections_: Sender, @@ -45,14 +46,25 @@ impl Controller { } }); + let notify_connections = notify_connections_.clone(); + s.spawn(move || { + println!("AboutToFinish monitor started"); + futures::executor::block_on(async { + while true { + _ = about_to_finish_tx.recv(); + notify_connections.send(ConnectionsNotification::AboutToFinish).unwrap(); + println!("About to Finish"); + } + }) + }); + // Thread for End of Track let notify_connections = notify_connections_.clone(); s.spawn(move || { + println!("EOS monitor started"); futures::executor::block_on(async { - println!("EOS monitor started"); while true { - let _ = finished_recv.recv(); - println!("End of song"); + _ = finished_tx.recv(); let (command, tx) = PlayerCommandInput::command(PlayerCommand::NextSong); player_mail.send(command).await.unwrap(); @@ -64,12 +76,13 @@ impl Controller { notify_connections .send(ConnectionsNotification::SongChange(song)) .unwrap(); - notify_connections + } + + notify_connections .send(ConnectionsNotification::EOS) .unwrap(); - } + println!("End of song"); } - std::thread::sleep(Duration::from_millis(100)); }); }); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index caddea4..cd689a6 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -2,7 +2,7 @@ "$schema": "https://schema.tauri.app/config/2", "productName": "Dango Music Player", "version": "0.0.1", - "identifier": "com.dango-music-player.app", + "identifier": "com.dmp.app", "build": { "beforeDevCommand": "npm run dev", "devUrl": "http://localhost:1420", @@ -14,13 +14,14 @@ { "title": "Dango Music Player", "width": 800, - "height": 600 + "height": 600, + "decorations": true } ], "security": { "assetProtocol": { "enable": true, - "scope": { "allow": ["asset://localhost*", "http://localhost*"] } + "scope": { "allow": ["asset://localhost*"] } }, "csp": { "default-src": "'self' customprotocol: asset:",