9 releases (4 breaking)

0.4.4 Nov 18, 2021
0.4.3 Oct 19, 2021
0.4.1 Jul 29, 2021
0.3.0 Jun 28, 2021
0.0.0 Jan 29, 2021
Download history 7/week @ 2021-08-10 1033/week @ 2021-08-17 432/week @ 2021-08-24 419/week @ 2021-08-31 299/week @ 2021-09-07 269/week @ 2021-09-14 194/week @ 2021-09-21 139/week @ 2021-09-28 177/week @ 2021-10-05 170/week @ 2021-10-12 148/week @ 2021-10-19 162/week @ 2021-10-26 141/week @ 2021-11-02 233/week @ 2021-11-09 265/week @ 2021-11-16 295/week @ 2021-11-23

962 downloads per month

MIT license

40KB
874 lines

Crates.io Docs CI

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

Souvlaki

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

Windows

  • Update metadata:
    image
  • Play and pause polling.
    play_pause

MacOS

Screenshots coming soon.

Linux

Coming soon.

Example

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

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

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

    // 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 💗

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

Dependencies

~0–51MB
~806K SLoC