{"id":17041150,"url":"https://github.com/seadve/mpris-server","last_synced_at":"2025-08-08T18:48:03.424Z","repository":{"id":193799642,"uuid":"689314635","full_name":"SeaDve/mpris-server","owner":"SeaDve","description":"Implement MPRIS D-Bus interface in your application","archived":false,"fork":false,"pushed_at":"2025-04-01T13:33:13.000Z","size":3815,"stargazers_count":27,"open_issues_count":5,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-09T03:07:53.461Z","etag":null,"topics":["dbus","mpris","rust"],"latest_commit_sha":null,"homepage":"https://seadve.github.io/mpris-server/mpris_server/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SeaDve.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"SeaDve","custom":["https://www.buymeacoffee.com/seadve"]}},"created_at":"2023-09-09T12:22:43.000Z","updated_at":"2025-04-06T02:22:33.000Z","dependencies_parsed_at":"2023-11-06T22:58:55.152Z","dependency_job_id":"fde3b0af-a9f7-42fa-b460-1a66e10818ed","html_url":"https://github.com/SeaDve/mpris-server","commit_stats":{"total_commits":217,"total_committers":1,"mean_commits":217.0,"dds":0.0,"last_synced_commit":"0e237b8e7257e14fa79b3d187eb53be59b390517"},"previous_names":["seadve/mpris-server"],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeaDve%2Fmpris-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeaDve%2Fmpris-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeaDve%2Fmpris-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeaDve%2Fmpris-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SeaDve","download_url":"https://codeload.github.com/SeaDve/mpris-server/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247968721,"owners_count":21025871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dbus","mpris","rust"],"created_at":"2024-10-14T09:11:31.085Z","updated_at":"2025-08-08T18:48:03.403Z","avatar_url":"https://github.com/SeaDve.png","language":"Rust","funding_links":["https://github.com/sponsors/SeaDve","https://www.buymeacoffee.com/seadve"],"categories":[],"sub_categories":[],"readme":"# MPRIS Server\n\n[![github](https://img.shields.io/badge/github-seadve/mpris-server)](https://github.com/SeaDve/mpris-server)\n[![crates.io](https://img.shields.io/crates/v/mpris-server)](https://crates.io/crates/mpris-server)\n[![docs](https://docs.rs/mpris-server/badge.svg)](https://docs.rs/mpris-server/)\n[![CI](https://github.com/SeaDve/mpris-server/actions/workflows/ci.yml/badge.svg)](https://github.com/SeaDve/mpris-server/actions/workflows/ci.yml)\n\nImplement MPRIS D-Bus interface in your application.\n\nThis 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).\n\nThis library supports all the following interfaces as defined in the specification:\n\n* [org.mpris.MediaPlayer2](https://specifications.freedesktop.org/mpris-spec/latest/Media_Player.html)\n* [org.mpris.MediaPlayer2.Player](https://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html)\n* [org.mpris.MediaPlayer2.TrackList](https://specifications.freedesktop.org/mpris-spec/latest/Track_List_Interface.html)\n* [org.mpris.MediaPlayer2.Playlists](https://specifications.freedesktop.org/mpris-spec/latest/Playlists_Interface.html)\n\nTo 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.\n\n## Optional Features\n\n| Feature    | Description                                  | Default |\n| ---------- | -------------------------------------------- | ------- |\n| `unstable` | Enables internal APIs and unstable features. | No      |\n| `tokio`    | Enables `tokio` feature for `zbus`.          | No      |\n\n## Examples\n\nFor more detailed examples, see also the [examples directory](https://github.com/SeaDve/mpris-server/tree/main/examples).\n\nThere is also a real-world example of this library being used in [Mousai](https://github.com/SeaDve/Mousai), a music recognizer application for Linux.\n\n### Manual Implementation (via `Server` or `LocalServer`)\n\nIf 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.\n\n```rust,ignore\nuse std::future;\n\nuse mpris_server::{\n    zbus::{fdo, Result},\n    Metadata, PlayerInterface, Property, RootInterface, Server, Signal, Time, Volume,\n};\n\npub struct MyPlayer;\n\nimpl RootInterface for MyPlayer {\n    async fn identity(\u0026self) -\u003e fdo::Result\u003cString\u003e {\n        Ok(\"MyPlayer\".into())\n    }\n\n    // Other methods...\n}\n\nimpl PlayerInterface for MyPlayer {\n    async fn set_volume(\u0026self, volume: Volume) -\u003e Result\u003c()\u003e {\n        self.volume.set(volume);\n        Ok(())\n    }\n\n    async fn metadata(\u0026self) -\u003e fdo::Result\u003cMetadata\u003e {\n        let metadata = Metadata::builder()\n            .title(\"My Song\")\n            .artist([\"My Artist\"])\n            .album(\"My Album\")\n            .length(Time::from_micros(123))\n            .build();\n        Ok(metadata)\n    }\n\n    // Other methods...\n}\n\n#[async_std::main]\nasync fn main() -\u003e Result\u003c()\u003e {\n    let server = Server::new(\"com.my.Application\", MyPlayer).await?;\n\n    // Emit `PropertiesChanged` signal for `CanSeek` and `Metadata` properties\n    server\n        .properties_changed([\n            Property::CanSeek(false),\n            Property::Metadata(Metadata::new()),\n        ])\n        .await?;\n\n    // Emit `Seeked` signal\n    server\n        .emit(Signal::Seeked {\n            position: Time::from_micros(124),\n        })\n        .await?;\n\n    // Prevent the program from exiting.\n    future::pending::\u003c()\u003e().await;\n\n    Ok(())\n}\n```\n\n### Ready-to-use Implementation (via `Player`)\n\nIf 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.\n\nHowever, `Player` currently only supports the more commonly used `org.mpris.MediaPlayer2` and `org.mpris.MediaPlayer2.Player` interfaces.\n\n```rust,ignore\nuse std::future;\n\nuse mpris_server::{zbus::Result, Player, Time};\n\n#[async_std::main]\nasync fn main() -\u003e Result\u003c()\u003e {\n    let player = Player::builder(\"com.my.Application\")\n        .can_play(true)\n        .can_pause(true)\n        .build()\n        .await?;\n\n    // Handle `PlayPause` method call\n    player.connect_play_pause(|_player| {\n        println!(\"PlayPause\");\n    });\n\n    // Run event handler task\n    async_std::task::spawn_local(player.run());\n\n    // Update `CanPlay` property and emit `PropertiesChanged` signal for it\n    player.set_can_play(false).await?;\n\n    // Emit `Seeked` signal\n    player.seeked(Time::from_millis(1000)).await?;\n\n    // Prevent the program from exiting.\n    future::pending::\u003c()\u003e().await;\n\n    Ok(())\n}\n```\n\n## License\n\nCopyright 2024 Dave Patrick Caberto\n\nThis 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/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseadve%2Fmpris-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseadve%2Fmpris-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseadve%2Fmpris-server/lists"}