MCPcopy Index your code
hub / github.com/SeaDve/mpris-server

github.com/SeaDve/mpris-server @v0.10.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.10.0 ↗ · + Follow
465 symbols 910 edges 16 files 75 documented · 16%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

MPRIS Server

github crates.io docs CI

Implement MPRIS D-Bus interface in your application.

This library provides the essential functionalities for implementing the MPRIS D-Bus interface on the service side. This enables your application to become discoverable and controllable by other MPRIS-compatible media controllers, including but not limited to GNOME Shell, KDE Plasma, and other libraries such as mpris.

This library supports all the following interfaces as defined in the specification:

To implement these interfaces, this crate offers two flavors: you can either create your own struct and implement RootInterface and PlayerInterface (or with optional TrackListInterface and PlaylistsInterface), or you can use the ready-to-use Player struct.

Optional Features

Feature Description Default
unstable Enables internal APIs and unstable features. No
tokio Enables tokio feature for zbus. No

Examples

For more detailed examples, see also the examples directory.

There is also a real-world example of this library being used in Mousai, a music recognizer application for Linux.

Manual Implementation (via Server or LocalServer)

If you want to have more control, it is recommended to manually create your own implementation of the interfaces. You can do this by creating your own struct and implementing the required interfaces, then passing your struct as implementation in Server. You can also use LocalServer and the local version of the interfaces if your struct can't be sent and shared across threads.

```rust,ignore use std::future;

use mpris_server::{ zbus::{fdo, Result}, Metadata, PlayerInterface, Property, RootInterface, Server, Signal, Time, Volume, };

pub struct MyPlayer;

impl RootInterface for MyPlayer { async fn identity(&self) -> fdo::Result { Ok("MyPlayer".into()) }

// Other methods...

}

impl PlayerInterface for MyPlayer { async fn set_volume(&self, volume: Volume) -> Result<()> { self.volume.set(volume); Ok(()) }

async fn metadata(&self) -> fdo::Result<Metadata> {
    let metadata = Metadata::builder()
        .title("My Song")
        .artist(["My Artist"])
        .album("My Album")
        .length(Time::from_micros(123))
        .build();
    Ok(metadata)
}

// Other methods...

}

[async_std::main]

async fn main() -> Result<()> { let server = Server::new("com.my.Application", MyPlayer).await?;

// Emit `PropertiesChanged` signal for `CanSeek` and `Metadata` properties
server
    .properties_changed([
        Property::CanSeek(false),
        Property::Metadata(Metadata::new()),
    ])
    .await?;

// Emit `Seeked` signal
server
    .emit(Signal::Seeked {
        position: Time::from_micros(124),
    })
    .await?;

// Prevent the program from exiting.
future::pending::<()>().await;

Ok(())

}


### Ready-to-use Implementation (via `Player`)

If you want to create a simple player without having to implement the interfaces, you can use the ready-to-use `Player` struct that implements those interfaces internally. This struct has its own internal state, automatically emits properties changed signals, and allows you to connect to method and property setter calls.

However, `Player` currently only supports the more commonly used `org.mpris.MediaPlayer2` and `org.mpris.MediaPlayer2.Player` interfaces.

```rust,ignore
use std::future;

use mpris_server::{zbus::Result, Player, Time};

#[async_std::main]
async fn main() -> Result<()> {
    let player = Player::builder("com.my.Application")
        .can_play(true)
        .can_pause(true)
        .build()
        .await?;

    // Handle `PlayPause` method call
    player.connect_play_pause(|_player| {
        println!("PlayPause");
    });

    // Run event handler task
    async_std::task::spawn_local(player.run());

    // Update `CanPlay` property and emit `PropertiesChanged` signal for it
    player.set_can_play(false).await?;

    // Emit `Seeked` signal
    player.seeked(Time::from_millis(1000)).await?;

    // Prevent the program from exiting.
    future::pending::<()>().await;

    Ok(())
}

License

Copyright 2024 Dave Patrick Caberto

This software is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at this site.

Core symbols most depended-on inside this repo

imp
called by 64
src/server.rs
set
called by 41
src/metadata.rs
get
called by 39
src/metadata.rs
send_player
called by 28
src/local_server.rs
properties_changed
called by 24
src/server.rs
get_value
called by 23
src/metadata.rs
player
called by 16
src/player.rs
send_root
called by 12
src/local_server.rs

Shape

Method 423
Class 21
Enum 14
Function 7

Languages

Rust100%

Modules by API surface

src/local_server.rs86 symbols
src/player.rs81 symbols
src/server.rs75 symbols
src/metadata.rs60 symbols
examples/server.rs53 symbols
examples/local_server.rs53 symbols
src/time.rs25 symbols
src/track_id.rs8 symbols
src/loop_status.rs5 symbols
src/playlist_ordering.rs4 symbols
src/playlist.rs4 symbols
src/playback_status.rs4 symbols

For agents

$ claude mcp add mpris-server \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact