Improve synchronization of playback times
Take librespot timestamps instead of approximating them in ncspot.
This commit is contained in:
@@ -30,8 +30,8 @@ struct MprisState(String, Option<Playable>);
|
||||
|
||||
fn get_playbackstatus(spotify: Spotify) -> String {
|
||||
match spotify.get_current_status() {
|
||||
PlayerEvent::Playing | PlayerEvent::FinishedTrack => "Playing",
|
||||
PlayerEvent::Paused => "Paused",
|
||||
PlayerEvent::Playing(_) | PlayerEvent::FinishedTrack => "Playing",
|
||||
PlayerEvent::Paused(_) => "Paused",
|
||||
_ => "Stopped",
|
||||
}
|
||||
.to_string()
|
||||
|
||||
@@ -273,7 +273,7 @@ impl Queue {
|
||||
|
||||
pub fn toggleplayback(&self) {
|
||||
match self.spotify.get_current_status() {
|
||||
PlayerEvent::Playing | PlayerEvent::Paused => {
|
||||
PlayerEvent::Playing(_) | PlayerEvent::Paused(_) => {
|
||||
self.spotify.toggleplayback();
|
||||
}
|
||||
PlayerEvent::Stopped => match self.next_index() {
|
||||
|
||||
@@ -60,8 +60,8 @@ pub const VOLUME_PERCENT: u16 = ((u16::max_value() as f64) * 1.0 / 100.0) as u16
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum PlayerEvent {
|
||||
Playing,
|
||||
Paused,
|
||||
Playing(SystemTime),
|
||||
Paused(Duration),
|
||||
Stopped,
|
||||
FinishedTrack,
|
||||
}
|
||||
@@ -746,12 +746,13 @@ impl Spotify {
|
||||
|
||||
pub fn update_status(&self, new_status: PlayerEvent) {
|
||||
match new_status {
|
||||
PlayerEvent::Paused => {
|
||||
self.set_elapsed(Some(self.get_current_progress()));
|
||||
PlayerEvent::Paused(position) => {
|
||||
self.set_elapsed(Some(position));
|
||||
self.set_since(None);
|
||||
}
|
||||
PlayerEvent::Playing => {
|
||||
self.set_since(Some(SystemTime::now()));
|
||||
PlayerEvent::Playing(playback_start) => {
|
||||
self.set_since(Some(playback_start));
|
||||
self.set_elapsed(None);
|
||||
}
|
||||
PlayerEvent::Stopped | PlayerEvent::FinishedTrack => {
|
||||
self.set_elapsed(None);
|
||||
@@ -778,8 +779,8 @@ impl Spotify {
|
||||
|
||||
pub fn toggleplayback(&self) {
|
||||
match self.get_current_status() {
|
||||
PlayerEvent::Playing => self.pause(),
|
||||
PlayerEvent::Paused => self.play(),
|
||||
PlayerEvent::Playing(_) => self.pause(),
|
||||
PlayerEvent::Paused(_) => self.play(),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
@@ -805,13 +806,6 @@ impl Spotify {
|
||||
}
|
||||
|
||||
pub fn seek(&self, position_ms: u32) {
|
||||
self.set_elapsed(Some(Duration::from_millis(position_ms.into())));
|
||||
self.set_since(if self.get_current_status() == PlayerEvent::Playing {
|
||||
Some(SystemTime::now())
|
||||
} else {
|
||||
None
|
||||
});
|
||||
|
||||
self.send_worker(WorkerCommand::Seek(position_ms));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ use librespot_core::session::Session;
|
||||
use librespot_core::spotify_id::{SpotifyAudioType, SpotifyId};
|
||||
use librespot_playback::mixer::Mixer;
|
||||
use librespot_playback::player::{Player, PlayerEvent as LibrespotPlayerEvent};
|
||||
use std::pin::Pin;
|
||||
use std::time::Duration;
|
||||
use std::{pin::Pin, time::SystemTime};
|
||||
|
||||
pub(crate) enum WorkerCommand {
|
||||
Load(Playable, bool, u32),
|
||||
@@ -141,13 +141,28 @@ impl futures::Future for Worker {
|
||||
| LibrespotPlayerEvent::Changed { .. } => {
|
||||
progress = true;
|
||||
}
|
||||
LibrespotPlayerEvent::Playing { .. } => {
|
||||
self.events.send(Event::Player(PlayerEvent::Playing));
|
||||
LibrespotPlayerEvent::Playing {
|
||||
play_request_id: _,
|
||||
track_id: _,
|
||||
position_ms,
|
||||
duration_ms: _,
|
||||
} => {
|
||||
let position = Duration::from_millis(position_ms as u64);
|
||||
let playback_start = SystemTime::now() - position;
|
||||
self.events
|
||||
.send(Event::Player(PlayerEvent::Playing(playback_start)));
|
||||
self.refresh_task = self.create_refresh();
|
||||
self.active = true;
|
||||
}
|
||||
LibrespotPlayerEvent::Paused { .. } => {
|
||||
self.events.send(Event::Player(PlayerEvent::Paused));
|
||||
LibrespotPlayerEvent::Paused {
|
||||
play_request_id: _,
|
||||
track_id: _,
|
||||
position_ms,
|
||||
duration_ms: _,
|
||||
} => {
|
||||
let position = Duration::from_millis(position_ms as u64);
|
||||
self.events
|
||||
.send(Event::Player(PlayerEvent::Paused(position)));
|
||||
self.active = false;
|
||||
}
|
||||
LibrespotPlayerEvent::Stopped { .. } => {
|
||||
|
||||
@@ -72,14 +72,14 @@ impl View for StatusBar {
|
||||
|
||||
let state_icon = if self.use_nerdfont {
|
||||
match self.spotify.get_current_status() {
|
||||
PlayerEvent::Playing => "\u{f909} ",
|
||||
PlayerEvent::Paused => "\u{f8e3} ",
|
||||
PlayerEvent::Playing(_) => "\u{f909} ",
|
||||
PlayerEvent::Paused(_) => "\u{f8e3} ",
|
||||
PlayerEvent::Stopped | PlayerEvent::FinishedTrack => "\u{f9da} ",
|
||||
}
|
||||
} else {
|
||||
match self.spotify.get_current_status() {
|
||||
PlayerEvent::Playing => "▶ ",
|
||||
PlayerEvent::Paused => "▮▮",
|
||||
PlayerEvent::Playing(_) => "▶ ",
|
||||
PlayerEvent::Paused(_) => "▮▮",
|
||||
PlayerEvent::Stopped | PlayerEvent::FinishedTrack => "◼ ",
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user