diff --git a/CHANGELOG.md b/CHANGELOG.md index 3768c1d1c..27ce5f951 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Emit MPRIS `Seeked` signal + ### Fixed - Switch to OAuth2 login mechanism diff --git a/src/mpris.rs b/src/mpris.rs index 29fde7d6f..216e703ba 100644 --- a/src/mpris.rs +++ b/src/mpris.rs @@ -1,3 +1,5 @@ +#![allow(clippy::use_self)] + use log::info; use std::collections::HashMap; use std::error::Error; @@ -6,6 +8,7 @@ use std::time::Duration; use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; use tokio_stream::StreamExt; +use zbus::object_server::SignalContext; use zbus::zvariant::{ObjectPath, Value}; use zbus::{interface, ConnectionBuilder}; @@ -314,6 +317,9 @@ impl MprisPlayer { self.queue.get_current().is_some() } + #[zbus(signal)] + async fn seeked(context: &SignalContext<'_>, position: &i64) -> zbus::Result<()>; + fn next(&self) { self.queue.next(true) } @@ -472,6 +478,8 @@ pub enum MprisCommand { EmitVolumeStatus, /// Emit metadata EmitMetadataStatus, + /// Emit seeked position + EmitSeekedStatus(i64), } /// An MPRIS server that internally manager a thread which can be sent commands. This is internally @@ -539,6 +547,10 @@ impl MprisManager { Some(MprisCommand::EmitMetadataStatus) => { player_iface.metadata_changed(ctx).await?; } + Some(MprisCommand::EmitSeekedStatus(pos)) => { + info!("sending MPRIS seeked signal"); + MprisPlayer::seeked(ctx, &pos).await?; + } None => break, } } diff --git a/src/queue.rs b/src/queue.rs index ced8ad4b1..64f2a9c23 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -313,6 +313,10 @@ impl Queue { move || send_notification(&summary_txt, &body_txt, cover_url) }); } + + // Send a Seeked signal at start of new track + #[cfg(feature = "mpris")] + self.spotify.notify_seeked(0); } if reshuffle && self.get_shuffle() { diff --git a/src/spotify.rs b/src/spotify.rs index 2e2165aba..8d098ef1c 100644 --- a/src/spotify.rs +++ b/src/spotify.rs @@ -415,6 +415,8 @@ impl Spotify { /// Seek in the currently played [Playable] played by the [Player]. pub fn seek(&self, position_ms: u32) { self.send_worker(WorkerCommand::Seek(position_ms)); + #[cfg(feature = "mpris")] + self.notify_seeked(position_ms); } /// Seek relatively to the current playback position of the [Player]. @@ -429,6 +431,19 @@ impl Spotify { self.cfg.state().volume } + /// Send a Seeked signal on Mpris interface + #[cfg(feature = "mpris")] + pub fn notify_seeked(&self, position_ms: u32) { + let new_position = Duration::from_millis(position_ms.into()); + let command = MprisCommand::EmitSeekedStatus( + new_position + .as_micros() + .try_into() + .expect("track position exceeds MPRIS datatype"), + ); + self.send_mpris(command); + } + /// Set the current volume of the [Player]. If `notify` is true, also notify MPRIS clients about /// the update. pub fn set_volume(&self, volume: u16, notify: bool) {