File: README.md

package info (click to toggle)
rust-mpris-server 0.8.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 464 kB
  • sloc: makefile: 2
file content (144 lines) | stat: -rw-r--r-- 5,643 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# MPRIS Server

[![github](https://img.shields.io/badge/github-seadve/mpris-server)](https://github.com/SeaDve/mpris-server)
[![crates.io](https://img.shields.io/crates/v/mpris-server)](https://crates.io/crates/mpris-server)
[![docs](https://docs.rs/mpris-server/badge.svg)](https://docs.rs/mpris-server/)
[![CI](https://github.com/SeaDve/mpris-server/actions/workflows/ci.yml/badge.svg)](https://github.com/SeaDve/mpris-server/actions/workflows/ci.yml)

Implement MPRIS D-Bus interface in your application.

This library provides the essential functionalities for implementing the [MPRIS D-Bus interface](https://specifications.freedesktop.org/mpris-spec/latest/) 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`](https://github.com/Mange/mpris-rs).

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

* [org.mpris.MediaPlayer2](https://specifications.freedesktop.org/mpris-spec/latest/Media_Player.html)
* [org.mpris.MediaPlayer2.Player](https://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html)
* [org.mpris.MediaPlayer2.TrackList](https://specifications.freedesktop.org/mpris-spec/latest/Track_List_Interface.html)
* [org.mpris.MediaPlayer2.Playlists](https://specifications.freedesktop.org/mpris-spec/latest/Playlists_Interface.html)

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      |

## Examples

For more detailed examples, see also the [examples directory](https://github.com/SeaDve/mpris-server/tree/main/examples).

There is also a real-world example of this library being used in [Mousai](https://github.com/SeaDve/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<String> {
        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](http://mozilla.org/MPL/2.0/).