Skip to content

Commit

Permalink
Implement MPRIS properties
Browse files Browse the repository at this point in the history
- `PlaybackStatus`
- `PlaybackRate`
- `Volume` (get/set)
  • Loading branch information
hrkfdn committed Mar 30, 2023
1 parent 1d634a3 commit 9181f7c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ fn main() -> Result<(), String> {
));

#[cfg(feature = "mpris")]
ASYNC_RUNTIME.spawn(mpris::serve());
ASYNC_RUNTIME.spawn(mpris::serve(event_manager.clone(), spotify.clone()));

let mut cmd_manager = CommandManager::new(
spotify.clone(),
Expand Down
51 changes: 49 additions & 2 deletions src/mpris.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
use std::{error::Error, future::pending};
use zbus::{dbus_interface, ConnectionBuilder};

use crate::{
events::EventManager,
spotify::{PlayerEvent, Spotify, VOLUME_PERCENT},
};

struct MprisRoot {}

#[dbus_interface(name = "org.mpris.MediaPlayer2")]
Expand Down Expand Up @@ -36,12 +41,54 @@ impl MprisRoot {
}
}

pub async fn serve() -> Result<(), Box<dyn Error + Sync + Send>> {
struct MprisPlayer {
event: EventManager,
spotify: Spotify,
}

#[dbus_interface(name = "org.mpris.MediaPlayer2.Player")]
impl MprisPlayer {
#[dbus_interface(property)]
fn playback_status(&self) -> &str {
match self.spotify.get_current_status() {
PlayerEvent::Playing(_) | PlayerEvent::FinishedTrack => "Playing",
PlayerEvent::Paused(_) => "Paused",
_ => "Stopped",
}
}

#[dbus_interface(property)]
fn playback_rate(&self) -> f64 {
1.0
}

#[dbus_interface(property)]
fn volume(&self) -> f64 {
self.spotify.volume() as f64 / 65535_f64
}

#[dbus_interface(property)]
fn set_volume(&self, volume: f64) {
log::info!("set volume: {volume}");
if (0.0..=1.0).contains(&volume) {
let vol = (VOLUME_PERCENT as f64) * volume * 100.0;
self.spotify.set_volume(vol as u16);
self.event.trigger();
}
}
}

pub async fn serve(
event: EventManager,
spotify: Spotify,
) -> Result<(), Box<dyn Error + Sync + Send>> {
let root = MprisRoot {};
let player = MprisPlayer { event, spotify };

let _conn = ConnectionBuilder::session()?
.name("org.mpris.MediaPlayer2.ncspot")?
.name("org.mpris.MediaPlayer2.ncspot_new")?
.serve_at("/org/mpris/MediaPlayer2", root)?
.serve_at("/org/mpris/MediaPlayer2", player)?
.build()
.await?;

Expand Down

0 comments on commit 9181f7c

Please sign in to comment.