Fixed a bug that causes the player to crash

This commit is contained in:
MrDulfin 2025-01-01 03:13:53 -05:00
parent 64e41af96f
commit 3a8826bb5d
4 changed files with 104 additions and 74 deletions

2
.gitignore vendored
View file

@ -31,4 +31,4 @@ Cargo.lock
.cargo .cargo
test-config test-config
.txt *.txt

View file

@ -1,5 +1,5 @@
#![allow(while_true)] #![allow(while_true)]
use std::{sync::Arc, thread::sleep, time::{Duration, SystemTime, UNIX_EPOCH}}; use std::{sync::{atomic::{AtomicBool, Ordering}, Arc}, thread::sleep, time::{Duration, SystemTime, UNIX_EPOCH}};
use chrono::TimeDelta; use chrono::TimeDelta;
use crossbeam::{scope, select}; use crossbeam::{scope, select};
@ -34,6 +34,10 @@ pub(super) struct ControllerConnections {
pub inner: ConnectionsInput pub inner: ConnectionsInput
} }
static DC_ACTIVE: AtomicBool = AtomicBool::new(false);
static LB_ACTIVE: AtomicBool = AtomicBool::new(false);
impl Controller { impl Controller {
pub(super) fn handle_connections( pub(super) fn handle_connections(
config: Arc<RwLock<Config>>, config: Arc<RwLock<Config>>,
@ -48,6 +52,7 @@ impl Controller {
let (dc_song_rx, dc_song_tx) = bounded::<Song>(1); let (dc_song_rx, dc_song_tx) = bounded::<Song>(1);
let (lb_song_rx, lb_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 (lb_eos_rx, lb_eos_tx) = bounded::<()>(1);
scope(|s| { scope(|s| {
s.builder().name("Notifications Sorter".to_string()).spawn(|_| { s.builder().name("Notifications Sorter".to_string()).spawn(|_| {
use ConnectionsNotification::*; use ConnectionsNotification::*;
@ -55,14 +60,14 @@ impl Controller {
match notifications_tx.recv().unwrap() { match notifications_tx.recv().unwrap() {
Playback { position, duration } => {} Playback { position, duration } => {}
StateChange(state) => { StateChange(state) => {
dc_state_rx.send(state.clone()).unwrap(); if DC_ACTIVE.load(Ordering::Relaxed) { dc_state_rx.send(state.clone()).unwrap(); }
} }
SongChange(song) => { SongChange(song) => {
dc_song_rx.send(song.clone()).unwrap(); if DC_ACTIVE.load(Ordering::Relaxed) { dc_song_rx.send(song.clone()).unwrap(); }
lb_song_rx.send(song).unwrap(); if LB_ACTIVE.load(Ordering::Relaxed) { lb_song_rx.send(song).unwrap(); }
} }
EOS => { EOS => {
lb_eos_rx.send(()).unwrap(); if LB_ACTIVE.load(Ordering::Relaxed) { lb_eos_rx.send(()).unwrap(); }
} }
} }
} }
@ -84,7 +89,6 @@ impl Controller {
fn discord_rpc(client_id: u64, song_tx: Receiver<Song>, state_tx: Receiver<PrismState>) { fn discord_rpc(client_id: u64, song_tx: Receiver<Song>, state_tx: Receiver<PrismState>) {
// TODO: Handle seeking position change and pause // TODO: Handle seeking position change and pause
std::thread::spawn(move || {
let mut client = discord_presence::Client::with_error_config(client_id, Duration::from_secs(5), None); let mut client = discord_presence::Client::with_error_config(client_id, Duration::from_secs(5), None);
client.start(); client.start();
while !Client::is_ready() { sleep(Duration::from_millis(100)); } while !Client::is_ready() { sleep(Duration::from_millis(100)); }
@ -93,6 +97,7 @@ impl Controller {
let mut state = "Started".to_string(); let mut state = "Started".to_string();
let mut song: Option<Song> = None; let mut song: Option<Song> = None;
let mut now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs(); let mut now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs();
DC_ACTIVE.store(true, Ordering::Relaxed);
while true { while true {
let state = &mut state; let state = &mut state;
@ -150,7 +155,7 @@ impl Controller {
}).instance(true) }).instance(true)
}).unwrap(); }).unwrap();
} }
}); 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>, eos_tx: Receiver<()>) {
@ -161,25 +166,48 @@ impl Controller {
} }
let mut song: Option<Song> = None; let mut song: Option<Song> = None;
LB_ACTIVE.store(true, Ordering::Relaxed);
while true { while true {
let song = &mut song; let song = &mut song;
let client = &client; let client = &client;
select! { select! {
recv(song_tx) -> res => { recv(song_tx) -> res => {
if let Ok(_song) = res { if let Ok(_song) = res {
client.playing_now(_song.get_tag(&Tag::Artist).map_or("", |tag| tag.as_str()), _song.get_tag(&Tag::Title).map_or("", |tag| tag.as_str()), None).unwrap(); let artist = if let Some(tag) = _song.get_tag(&Tag::Artist) {
tag.as_str()
} else {
continue
};
let title = if let Some(tag) = _song.get_tag(&Tag::Title) {
tag.as_str()
} else {
continue
};
client.playing_now(artist, title, None).unwrap();
*song = Some(_song); *song = Some(_song);
println!("Song Listening") println!("Song Listening")
} }
}, },
recv(eos_tx) -> _ => { recv(eos_tx) -> _ => {
if let Some(song) = song { if let Some(song) = song {
client.listen(song.get_tag(&Tag::Artist).map_or("", |tag| tag.as_str()), song.get_tag(&Tag::Title).map_or("", |tag| tag.as_str()), None).unwrap(); let artist = if let Some(tag) = song.get_tag(&Tag::Artist) {
tag.as_str()
} else {
continue
};
let title = if let Some(tag) = song.get_tag(&Tag::Title) {
tag.as_str()
} else {
continue
};
client.listen(artist, title, None).unwrap();
println!("Song Scrobbled"); println!("Song Scrobbled");
} }
} }
} }
} }
LB_ACTIVE.store(false, Ordering::Relaxed);
} }
} }

View file

@ -656,6 +656,7 @@ impl Controller {
if let Ok(song) = res { if let Ok(song) = res {
notify_next_song.send(song.clone()).unwrap(); notify_next_song.send(song.clone()).unwrap();
notify_connections.send(ConnectionsNotification::SongChange(song)).unwrap(); notify_connections.send(ConnectionsNotification::SongChange(song)).unwrap();
notify_connections.send(ConnectionsNotification::EOS).unwrap();
} }
} }
std::thread::sleep(Duration::from_millis(100)); std::thread::sleep(Duration::from_millis(100));

View file

@ -294,8 +294,8 @@ function PlayBar({ playing, setPlaying }: PlayBarProps) {
const pos_ = Array.isArray(info.position) ? info.position![0] : 0; const pos_ = Array.isArray(info.position) ? info.position![0] : 0;
const dur_ = Array.isArray(info.duration) ? info.duration![0] : 0; const dur_ = Array.isArray(info.duration) ? info.duration![0] : 0;
setPosition(dur_); setPosition(pos_);
setDuration(pos_); setDuration(dur_);
let progress = ((dur_/pos_) * 100); let progress = ((dur_/pos_) * 100);
setSeekBarSize(progress) setSeekBarSize(progress)
}) })
@ -332,10 +332,11 @@ function PlayBar({ playing, setPlaying }: PlayBarProps) {
invoke('set_volume', { volume: volume.target.value }).then(() => {}) invoke('set_volume', { volume: volume.target.value }).then(() => {})
}} /> }} />
<p id="timeDisplay"> <p id="timeDisplay">
{ Math.floor(+position / 60).toString().padStart(2, "0") }:
{ (+position % 60).toString().padStart(2, "0") }/
{ Math.floor(+duration / 60).toString().padStart(2, "0") }: { Math.floor(+duration / 60).toString().padStart(2, "0") }:
{ (+duration % 60).toString().padStart(2, "0") } { (+duration % 60).toString().padStart(2, "0") }/
{ Math.floor(+position / 60).toString().padStart(2, "0") }:
{ (+position % 60).toString().padStart(2, "0") }
</p> </p>
</div> </div>
</div> </div>