mirror of
https://github.com/Dangoware/dango-music-player.git
synced 2025-04-19 01:52:53 -05:00
Updated Prismriver and fixed scrobbling timing
This commit is contained in:
parent
2ac3acdf5a
commit
b8f942feb1
4 changed files with 57 additions and 52 deletions
|
@ -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::<PrismState>(1);
|
||||
let (dc_song_rx, dc_song_tx) = bounded::<Song>(1);
|
||||
let (lb_song_rx, lb_song_tx) = bounded::<Song>(1);
|
||||
let (lb_eos_rx, lb_eos_tx) = bounded::<()>(1);
|
||||
let (dc_state_rx, dc_state_tx) = unbounded::<PrismState>();
|
||||
let (dc_song_rx, dc_song_tx) = unbounded::<Song>();
|
||||
let (lb_song_rx, lb_song_tx) = unbounded::<Song>();
|
||||
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<Song>, eos_tx: Receiver<()>) {
|
||||
fn listenbrainz_scrobble(token: &str, song_tx: Receiver<Song>, 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<Song> = None;
|
||||
let mut last_song: Option<Song> = 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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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::<ConnectionsNotification>();
|
||||
|
@ -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,
|
||||
|
|
|
@ -20,7 +20,8 @@ impl Controller {
|
|||
pub(super) fn player_monitor_loop(
|
||||
playback_state: Arc<std::sync::RwLock<PrismState>>,
|
||||
playback_time_tx: Receiver<(Option<TimeDelta>, Option<TimeDelta>)>,
|
||||
finished_recv: Receiver<()>,
|
||||
about_to_finish_tx: Receiver<()>,
|
||||
finished_tx: Receiver<()>,
|
||||
player_mail: async_channel::Sender<PlayerCommandInput>,
|
||||
notify_next_song: Sender<Song>,
|
||||
notify_connections_: Sender<ConnectionsNotification>,
|
||||
|
@ -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));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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:",
|
||||
|
|
Loading…
Reference in a new issue