//! MPRIS2 D-Bus server (org.mpris.MediaPlayer2.riptune). //! //! Implementing this is what lets waybar's mpris module, GNOME/KDE media //! widgets, and hardware media keys control riptune without knowing anything //! about Subsonic — they only ever speak the standard MPRIS interface. //! Spec: use riptune_types::AudioCommand; use std::sync::mpsc::Sender; use zbus::{interface, ConnectionBuilder}; pub struct MprisHandle { conn: zbus::Connection, } impl MprisHandle { pub async fn shutdown(self) { drop(self.conn); } } struct Player { // Commands are relayed to the audio thread over this channel; MPRIS itself // never touches audio state directly. #[allow(dead_code)] audio_tx: Sender, } #[interface(name = "org.mpris.MediaPlayer2.Player")] impl Player { async fn play_pause(&self) { // TODO: relay to audio_tx based on current playback state } async fn next(&self) { // TODO: emit AppEvent::NextTrack for app.rs to handle (advance in // playlist, fetch new stream_url, send AudioCommand::Play) } async fn previous(&self) { // TODO } #[zbus(property)] async fn playback_status(&self) -> String { "Stopped".into() // TODO: reflect real state } } pub async fn spawn(audio_tx: Sender) -> zbus::Result { let player = Player { audio_tx }; let conn = ConnectionBuilder::session()? .name("org.mpris.MediaPlayer2.riptune")? .serve_at("/org/mpris/MediaPlayer2", player)? .build() .await?; Ok(MprisHandle { conn }) }