#metadata #media #cross-platform #key #change #handling #controls


A cross-platform media key and metadata handling library

11 releases (5 breaking)

0.5.1 Jan 25, 2022
0.4.4 Nov 18, 2021
0.4.1 Jul 29, 2021
0.1.0 Feb 20, 2021
Download history 234/week @ 2022-01-28 122/week @ 2022-02-04 229/week @ 2022-02-11 295/week @ 2022-02-18 153/week @ 2022-02-25 207/week @ 2022-03-04 295/week @ 2022-03-11 321/week @ 2022-03-18 240/week @ 2022-03-25 174/week @ 2022-04-01 140/week @ 2022-04-08 129/week @ 2022-04-15 222/week @ 2022-04-22 372/week @ 2022-04-29 278/week @ 2022-05-06 413/week @ 2022-05-13

1,325 downloads per month
Used in 2 crates

MIT license

877 lines

Crates.io Docs CI

DISCLAIMER: the project is still in an early state. All parts may be subject to change.


A cross-platform library for handling OS media controls and metadata. One abstraction for Linux, MacOS and Windows.

Supported platforms

  • Linux (via MPRIS)
  • MacOS
  • Windows


  • Update metadata:
  • Play and pause polling.





# In one shell
$ cd souvlaki 
$ cargo run --example example

# In another shell
$ playerctl metadata
my_player xesam:artist              Slowdive
my_player xesam:album               Souvlaki
my_player mpris:artUrl              https://c.pxhere.com/photos/34/c1/souvlaki_authentic_greek_greek_food_mezes-497780.jpg!d
my_player mpris:trackid             '/'
my_player mpris:length              290000000
my_player xesam:title               When The Sun Hits


Screenshots coming soon.


The main struct is MediaControls. In order to create this struct you need a PlatformConfig. This struct contains all of the platform-specific requirements for spawning media controls. Here are the differences between the platforms:

  • MacOS: No config needed.
  • Linux:
    • dbus_name: The way your player will appear on D-Bus. It should follow the D-Bus specification.
    • display_name: This could be however you want. It's the name that will be shown to the users.
  • Windows:
    • hwnd: In this platform, a window needs to be opened to create media controls. The argument required is an HWND, a value of type *mut c_void. This value can be extracted when you open a window in your program, for example using the raw_window_handle in winit.

A full cross-platform app would look like this:

use souvlaki::{MediaControlEvent, MediaControls, MediaMetadata, PlatformConfig};

fn main() {
    #[cfg(not(target_os = "windows"))]
    let hwnd = None;

    #[cfg(target_os = "windows")]
    let hwnd = {
        use raw_window_handle::windows::WindowsHandle;

        let handle: WindowsHandle = unimplemented!();

    let config = PlatformConfig {
        dbus_name: "my_player",
        display_name: "My Player",

    let mut controls = MediaControls::new(config);

    // The closure must be Send and have a static lifetime.
        .attach(|event: MediaControlEvent| println!("Event received: {:?}", event))

    // Update the media metadata.
        .set_metadata(MediaMetadata {
            title: Some("Souvlaki Space Station"),
            artist: Some("Slowdive"),
            album: Some("Souvlaki"),

    // Your actual logic goes here.
    loop {

    // The controls automatically detach on drop.

Check out this example here.

Thanks 💗

  • To jpochyla for being a contributor to library architecture and the sole developer of MacOS support.


~1M SLoC