Skip to content

Commit

Permalink
fix: Handle librespot Seeked events
Browse files Browse the repository at this point in the history
With librespot 0.5 the `PlayerEvent` behavior for track seeking seems to have
changed slightly and there is now a dedicated event. This broke seeking in
tracks.

With this change the dedicated event is processed and track position changes
should be picked up again.
  • Loading branch information
hrkfdn committed Sep 21, 2024
1 parent 40644e1 commit f8a0a31
Showing 1 changed file with 27 additions and 7 deletions.
34 changes: 27 additions & 7 deletions src/spotify_worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,20 @@ pub(crate) enum WorkerCommand {
Shutdown,
}

enum PlayerStatus {
Playing,
Paused,
Stopped,
}

pub struct Worker {
events: EventManager,
player_events: UnboundedReceiverStream<LibrespotPlayerEvent>,
commands: UnboundedReceiverStream<WorkerCommand>,
session: Session,
player: Arc<Player>,
token_task: Pin<Box<dyn Future<Output = ()> + Send>>,
active: bool,
player_status: PlayerStatus,
mixer: Arc<dyn Mixer>,
}

Expand All @@ -59,7 +65,7 @@ impl Worker {
player,
session,
token_task: Box::pin(futures::future::pending()),
active: false,
player_status: PlayerStatus::Stopped,
mixer,
}
}
Expand Down Expand Up @@ -142,7 +148,7 @@ impl Worker {
let playback_start = SystemTime::now() - position;
self.events
.send(Event::Player(PlayerEvent::Playing(playback_start)));
self.active = true;
self.player_status = PlayerStatus::Playing;
}
Some(LibrespotPlayerEvent::Paused {
play_request_id: _,
Expand All @@ -152,11 +158,11 @@ impl Worker {
let position = Duration::from_millis(position_ms as u64);
self.events
.send(Event::Player(PlayerEvent::Paused(position)));
self.active = false;
self.player_status = PlayerStatus::Paused;
}
Some(LibrespotPlayerEvent::Stopped { .. }) => {
self.events.send(Event::Player(PlayerEvent::Stopped));
self.active = false;
self.player_status = PlayerStatus::Stopped;
}
Some(LibrespotPlayerEvent::EndOfTrack { .. }) => {
self.events.send(Event::Player(PlayerEvent::FinishedTrack));
Expand All @@ -165,15 +171,29 @@ impl Worker {
self.events
.send(Event::Queue(QueueEvent::PreloadTrackRequest));
}
Some(LibrespotPlayerEvent::Seeked { play_request_id: _, track_id: _, position_ms}) => {
let position = Duration::from_millis(position_ms as u64);
let event = match self.player_status {
PlayerStatus::Playing => {
let playback_start = SystemTime::now() - position;
PlayerEvent::Playing(playback_start)
},
PlayerStatus::Paused => PlayerEvent::Paused(position),
PlayerStatus::Stopped => PlayerEvent::Stopped,
};
self.events.send(Event::Player(event));
}
Some(event) => {
debug!("Unhandled player event: {event:?}");
}
None => {
warn!("Librespot player event channel died, terminating worker");
break
},
_ => {}
},
// Update animated parts of the UI (e.g. statusbar during playback).
_ = ui_refresh.tick() => {
if self.active {
if !matches!(self.player_status, PlayerStatus::Stopped) {
self.events.trigger();
}
},
Expand Down

0 comments on commit f8a0a31

Please sign in to comment.