Souvlaki Crates.io Docs CI

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

Supported platforms

Windows

Linux

$ cd souvlaki $ cargo run --example example

In another shell

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

MacOS

Usage

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:

Linux backends: D-Bus and zbus

When using the library on Linux, the default backend is dbus-crossroads. This backend has some issues with consistency in general, but is more stable and uses the native D-Bus library behind the scenes. The zbus backend however, is more modern and is written in pure Rust. It spawns another thread and stars an async pollster runtime, handling the incoming MPRIS messages.

To enable the zbus backend, in your Cargo.toml, set default-features to false and enable the use_zbus feature:

toml souvlaki = { version = "<version>", default-features = false, features = ["use_zbus"] }

Note: If you think there's a better way of using the zbus library regarding the async runtime in another thread, feel free to leave a PR or issue.

Example

```rust 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!();
    Some(handle.hwnd)
};

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

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

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

// Update the media metadata.
controls
    .set_metadata(MediaMetadata {
        title: Some("Souvlaki Space Station"),
        artist: Some("Slowdive"),
        album: Some("Souvlaki"),
        ..Default::default()
    })
    .unwrap();

// Your actual logic goes here.
loop {
    std::thread::sleep(std::time::Duration::from_secs(1));
}

// The controls automatically detach on drop.

} ```

Check out this example here.

Thanks 💗