Skip to content

Commit

Permalink
Add Seeked signal to Mpris interface
Browse files Browse the repository at this point in the history
The Mpris2 spec includes a `Seeked` signal which should be fired when
the track position changes in an unexpected way i.e. when the user
seeks to a different part of the track.

This PR implements this signal on seek events and also when a new track
begins. The latter is not strictly required but has been observed in
other players (e.g. VLC).

Closes #1492
  • Loading branch information
elParaguayo committed Aug 5, 2024
1 parent af2fe17 commit f829001
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/mpris.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,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};

Expand Down Expand Up @@ -314,6 +315,9 @@ impl MprisPlayer {
self.queue.get_current().is_some()
}

#[zbus(signal)]
async fn seeked(context: &SignalContext<'_>, position: &i64) -> Result<(), zbus::Error>;

fn next(&self) {
self.queue.next(true)
}
Expand Down Expand Up @@ -468,6 +472,8 @@ pub enum MprisCommand {
NotifyPlaybackUpdate,
/// Notify about volume updates.
NotifyVolumeUpdate,
/// Notify about seek changes,
NotifySeekedUpdate(i64),
}

/// An MPRIS server that internally manager a thread which can be sent commands. This is internally
Expand Down Expand Up @@ -533,6 +539,11 @@ impl MprisManager {
info!("sending MPRIS volume update signal");
player_iface.volume_changed(ctx).await?;
}
Some(MprisCommand::NotifySeekedUpdate(pos)) => {
// let pos = player_iface.position();
info!("sending MPRIS seeked signal");
MprisPlayer::seeked(ctx, &pos).await?;
}
None => break,
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,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() {
Expand Down
13 changes: 13 additions & 0 deletions src/spotify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,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].
Expand All @@ -408,6 +410,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::NotifySeekedUpdate(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) {
Expand Down

0 comments on commit f829001

Please sign in to comment.