mirror of
https://github.com/Dangoware/dango-music-player.git
synced 2025-04-18 09:32:53 -05:00
Fixed a bug that causes the player to crash
This commit is contained in:
parent
64e41af96f
commit
3a8826bb5d
4 changed files with 104 additions and 74 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -31,4 +31,4 @@ Cargo.lock
|
|||
.cargo
|
||||
|
||||
test-config
|
||||
.txt
|
||||
*.txt
|
|
@ -1,5 +1,5 @@
|
|||
#![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 crossbeam::{scope, select};
|
||||
|
@ -34,6 +34,10 @@ pub(super) struct ControllerConnections {
|
|||
pub inner: ConnectionsInput
|
||||
}
|
||||
|
||||
|
||||
static DC_ACTIVE: AtomicBool = AtomicBool::new(false);
|
||||
static LB_ACTIVE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
impl Controller {
|
||||
pub(super) fn handle_connections(
|
||||
config: Arc<RwLock<Config>>,
|
||||
|
@ -48,6 +52,7 @@ impl Controller {
|
|||
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);
|
||||
|
||||
scope(|s| {
|
||||
s.builder().name("Notifications Sorter".to_string()).spawn(|_| {
|
||||
use ConnectionsNotification::*;
|
||||
|
@ -55,14 +60,14 @@ impl Controller {
|
|||
match notifications_tx.recv().unwrap() {
|
||||
Playback { position, duration } => {}
|
||||
StateChange(state) => {
|
||||
dc_state_rx.send(state.clone()).unwrap();
|
||||
if DC_ACTIVE.load(Ordering::Relaxed) { dc_state_rx.send(state.clone()).unwrap(); }
|
||||
}
|
||||
SongChange(song) => {
|
||||
dc_song_rx.send(song.clone()).unwrap();
|
||||
lb_song_rx.send(song).unwrap();
|
||||
if DC_ACTIVE.load(Ordering::Relaxed) { dc_song_rx.send(song.clone()).unwrap(); }
|
||||
if LB_ACTIVE.load(Ordering::Relaxed) { lb_song_rx.send(song).unwrap(); }
|
||||
}
|
||||
EOS => {
|
||||
lb_eos_rx.send(()).unwrap();
|
||||
if LB_ACTIVE.load(Ordering::Relaxed) { lb_eos_rx.send(()).unwrap(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,73 +89,73 @@ impl Controller {
|
|||
|
||||
fn discord_rpc(client_id: u64, song_tx: Receiver<Song>, state_tx: Receiver<PrismState>) {
|
||||
// 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);
|
||||
client.start();
|
||||
while !Client::is_ready() { sleep(Duration::from_millis(100)); }
|
||||
println!("discord connected");
|
||||
let mut client = discord_presence::Client::with_error_config(client_id, Duration::from_secs(5), None);
|
||||
client.start();
|
||||
while !Client::is_ready() { sleep(Duration::from_millis(100)); }
|
||||
println!("discord connected");
|
||||
|
||||
let mut state = "Started".to_string();
|
||||
let mut song: Option<Song> = None;
|
||||
let mut now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs();
|
||||
let mut state = "Started".to_string();
|
||||
let mut song: Option<Song> = None;
|
||||
let mut now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs();
|
||||
DC_ACTIVE.store(true, Ordering::Relaxed);
|
||||
|
||||
while true {
|
||||
let state = &mut state;
|
||||
let song = &mut song;
|
||||
select! {
|
||||
recv(state_tx) -> res => {
|
||||
if let Ok(state_) = res {
|
||||
*state = match state_ {
|
||||
PrismState::Playing => "Playing",
|
||||
PrismState::Paused => "Paused",
|
||||
PrismState::Stopped => "Stopped",
|
||||
_ => "I'm Scared, Boss"
|
||||
}.to_string();
|
||||
}
|
||||
},
|
||||
recv(song_tx) -> res => {
|
||||
if let Ok(song_) = res {
|
||||
*song = Some(song_);
|
||||
now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs();
|
||||
}
|
||||
},
|
||||
default(Duration::from_millis(99)) => ()
|
||||
}
|
||||
while true {
|
||||
let state = &mut state;
|
||||
let song = &mut song;
|
||||
select! {
|
||||
recv(state_tx) -> res => {
|
||||
if let Ok(state_) = res {
|
||||
*state = match state_ {
|
||||
PrismState::Playing => "Playing",
|
||||
PrismState::Paused => "Paused",
|
||||
PrismState::Stopped => "Stopped",
|
||||
_ => "I'm Scared, Boss"
|
||||
}.to_string();
|
||||
}
|
||||
},
|
||||
recv(song_tx) -> res => {
|
||||
if let Ok(song_) = res {
|
||||
*song = Some(song_);
|
||||
now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs();
|
||||
}
|
||||
},
|
||||
default(Duration::from_millis(99)) => ()
|
||||
}
|
||||
|
||||
client.set_activity(|activity| {
|
||||
let a = activity.state(
|
||||
song.as_ref().map_or(String::new(), |s| format!(
|
||||
"{}{}{}",
|
||||
s.get_tag(&Tag::Artist).map_or(String::new(), |album| album.clone()),
|
||||
if s.get_tag(&Tag::Album).is_some() && s.get_tag(&Tag::Artist).is_some() { " - " } else { "" },
|
||||
s.get_tag(&Tag::Album).map_or(String::new(), |album| album.clone())
|
||||
)
|
||||
client.set_activity(|activity| {
|
||||
let a = activity.state(
|
||||
song.as_ref().map_or(String::new(), |s| format!(
|
||||
"{}{}{}",
|
||||
s.get_tag(&Tag::Artist).map_or(String::new(), |album| album.clone()),
|
||||
if s.get_tag(&Tag::Album).is_some() && s.get_tag(&Tag::Artist).is_some() { " - " } else { "" },
|
||||
s.get_tag(&Tag::Album).map_or(String::new(), |album| album.clone())
|
||||
)
|
||||
)._type(discord_presence::models::ActivityType::Listening)
|
||||
.details(
|
||||
if let Some(song) = song {
|
||||
song.get_tag(&Tag::Title).map_or(String::from("Unknown Title"), |title| title.clone())
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
);
|
||||
if let Some(s) = song {
|
||||
if state.as_str() == "Playing" {
|
||||
a.timestamps(|timestamps| {
|
||||
timestamps.start(now)
|
||||
.end(now + s.duration.as_secs())
|
||||
})
|
||||
} else {
|
||||
a
|
||||
}
|
||||
)
|
||||
)._type(discord_presence::models::ActivityType::Listening)
|
||||
.details(
|
||||
if let Some(song) = song {
|
||||
song.get_tag(&Tag::Title).map_or(String::from("Unknown Title"), |title| title.clone())
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
);
|
||||
if let Some(s) = song {
|
||||
if state.as_str() == "Playing" {
|
||||
a.timestamps(|timestamps| {
|
||||
timestamps.start(now)
|
||||
.end(now + s.duration.as_secs())
|
||||
})
|
||||
} else {
|
||||
a
|
||||
}.assets(|a| {
|
||||
a.large_text(state.clone())
|
||||
}).instance(true)
|
||||
}).unwrap();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
a
|
||||
}.assets(|a| {
|
||||
a.large_text(state.clone())
|
||||
}).instance(true)
|
||||
}).unwrap();
|
||||
}
|
||||
DC_ACTIVE.store(false, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
fn listenbrainz_scrobble(token: &str, song_tx: Receiver<Song>, eos_tx: Receiver<()>) {
|
||||
|
@ -161,25 +166,48 @@ impl Controller {
|
|||
}
|
||||
|
||||
let mut song: Option<Song> = None;
|
||||
LB_ACTIVE.store(true, Ordering::Relaxed);
|
||||
|
||||
while true {
|
||||
let song = &mut song;
|
||||
let client = &client;
|
||||
select! {
|
||||
recv(song_tx) -> 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);
|
||||
println!("Song Listening")
|
||||
}
|
||||
},
|
||||
recv(eos_tx) -> _ => {
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LB_ACTIVE.store(false, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -656,6 +656,7 @@ impl Controller {
|
|||
if let Ok(song) = res {
|
||||
notify_next_song.send(song.clone()).unwrap();
|
||||
notify_connections.send(ConnectionsNotification::SongChange(song)).unwrap();
|
||||
notify_connections.send(ConnectionsNotification::EOS).unwrap();
|
||||
}
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
|
|
11
src/App.tsx
11
src/App.tsx
|
@ -294,8 +294,8 @@ function PlayBar({ playing, setPlaying }: PlayBarProps) {
|
|||
const pos_ = Array.isArray(info.position) ? info.position![0] : 0;
|
||||
const dur_ = Array.isArray(info.duration) ? info.duration![0] : 0;
|
||||
|
||||
setPosition(dur_);
|
||||
setDuration(pos_);
|
||||
setPosition(pos_);
|
||||
setDuration(dur_);
|
||||
let progress = ((dur_/pos_) * 100);
|
||||
setSeekBarSize(progress)
|
||||
})
|
||||
|
@ -332,10 +332,11 @@ function PlayBar({ playing, setPlaying }: PlayBarProps) {
|
|||
invoke('set_volume', { volume: volume.target.value }).then(() => {})
|
||||
}} />
|
||||
<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") }:
|
||||
{ (+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>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue