Improve synchronization of playback times

Take librespot timestamps instead of approximating them in ncspot.
This commit is contained in:
Henrik Friedrichsen
2021-04-11 15:17:10 +02:00
parent 44da16dc0e
commit decf7c2aef
5 changed files with 36 additions and 27 deletions

View File

@@ -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()

View File

@@ -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() {

View File

@@ -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));
}

View File

@@ -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 { .. } => {

View File

@@ -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 => "",
}
}