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..10117edfc 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,17 @@ impl Spotify { self.cfg.state().volume } + /// Send a Seeked signal on Mpris interface + #[cfg(feature = "mpris")] + pub fn notify_seeked(&self, position: u32) { + if let Some(mpris_manager) = self.mpris.lock().unwrap().as_ref() { + info!("Seeked event"); + // Mpris spec requires microseconds + let new_position = position * 1000; + mpris_manager.send(MprisCommand::EmitSeekedStatus(new_position.into())); + } + } + /// 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) {