mirror of
https://github.com/librespot-org/librespot.git
synced 2025-10-03 09:49:31 +02:00
add initial MPRIS support using zbus
- following the spec at https://specifications.freedesktop.org/mpris-spec/latest/ - some properties/commands are not fully supported, yet
This commit is contained in:
parent
feb2dc6b1b
commit
01ac2e3b60
4 changed files with 1507 additions and 13 deletions
271
Cargo.lock
generated
271
Cargo.lock
generated
|
@ -160,6 +160,65 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener-strategy",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"futures-io",
|
||||
"futures-lite",
|
||||
"parking",
|
||||
"polling",
|
||||
"rustix 1.1.2",
|
||||
"slab",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "3.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-process"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"async-signal",
|
||||
"async-task",
|
||||
"blocking",
|
||||
"cfg-if",
|
||||
"event-listener",
|
||||
"futures-lite",
|
||||
"rustix 1.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-recursion"
|
||||
version = "1.1.1"
|
||||
|
@ -171,6 +230,30 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-signal"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c"
|
||||
dependencies = [
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"atomic-waker",
|
||||
"cfg-if",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"rustix 1.1.2",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-task"
|
||||
version = "4.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.89"
|
||||
|
@ -248,6 +331,19 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blocking"
|
||||
version = "1.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-task",
|
||||
"futures-io",
|
||||
"futures-lite",
|
||||
"piper",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
|
@ -1210,6 +1306,12 @@ version = "0.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
|
@ -1861,8 +1963,11 @@ dependencies = [
|
|||
"sha1",
|
||||
"sysinfo",
|
||||
"thiserror 2.0.16",
|
||||
"time",
|
||||
"tokio",
|
||||
"url",
|
||||
"zbus 4.4.0",
|
||||
"zvariant 4.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1985,7 +2090,7 @@ dependencies = [
|
|||
"sha1",
|
||||
"thiserror 2.0.16",
|
||||
"tokio",
|
||||
"zbus",
|
||||
"zbus 5.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2205,6 +2310,19 @@ dependencies = [
|
|||
"jni-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.30.1"
|
||||
|
@ -2633,6 +2751,17 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "piper"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"fastrand",
|
||||
"futures-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.7.5"
|
||||
|
@ -2660,6 +2789,20 @@ version = "0.3.32"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "3.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"hermit-abi",
|
||||
"pin-project-lite",
|
||||
"rustix 1.1.2",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.11.1"
|
||||
|
@ -4865,6 +5008,16 @@ version = "0.6.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||
|
||||
[[package]]
|
||||
name = "xdg-home"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.0"
|
||||
|
@ -4889,6 +5042,39 @@ dependencies = [
|
|||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "4.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-process",
|
||||
"async-recursion",
|
||||
"async-trait",
|
||||
"enumflags2",
|
||||
"event-listener",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"hex",
|
||||
"nix 0.29.0",
|
||||
"ordered-stream",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
"sha1",
|
||||
"static_assertions",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"uds_windows",
|
||||
"windows-sys 0.52.0",
|
||||
"xdg-home",
|
||||
"zbus_macros 4.4.0",
|
||||
"zbus_names 3.0.0",
|
||||
"zvariant 4.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "5.11.0"
|
||||
|
@ -4903,7 +5089,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-lite",
|
||||
"hex",
|
||||
"nix",
|
||||
"nix 0.30.1",
|
||||
"ordered-stream",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
|
@ -4912,9 +5098,22 @@ dependencies = [
|
|||
"uds_windows",
|
||||
"windows-sys 0.60.2",
|
||||
"winnow",
|
||||
"zbus_macros",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
"zbus_macros 5.11.0",
|
||||
"zbus_names 4.2.0",
|
||||
"zvariant 5.7.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "4.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"zvariant_utils 2.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4927,9 +5126,20 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
"zvariant_utils",
|
||||
"zbus_names 4.2.0",
|
||||
"zvariant 5.7.0",
|
||||
"zvariant_utils 3.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_names"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"zvariant 4.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4941,7 +5151,7 @@ dependencies = [
|
|||
"serde",
|
||||
"static_assertions",
|
||||
"winnow",
|
||||
"zvariant",
|
||||
"zvariant 5.7.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5024,6 +5234,19 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe"
|
||||
dependencies = [
|
||||
"endi",
|
||||
"enumflags2",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"zvariant_derive 4.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "5.7.0"
|
||||
|
@ -5034,8 +5257,21 @@ dependencies = [
|
|||
"enumflags2",
|
||||
"serde",
|
||||
"winnow",
|
||||
"zvariant_derive",
|
||||
"zvariant_utils",
|
||||
"zvariant_derive 5.7.0",
|
||||
"zvariant_utils 3.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_derive"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"zvariant_utils 2.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5048,7 +5284,18 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"zvariant_utils",
|
||||
"zvariant_utils 3.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_utils"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -37,7 +37,7 @@ repository = "https://github.com/librespot-org/librespot"
|
|||
edition = "2024"
|
||||
|
||||
[features]
|
||||
default = ["native-tls", "rodio-backend", "with-libmdns"]
|
||||
default = ["native-tls", "rodio-backend", "with-libmdns", "with-mpris"]
|
||||
|
||||
# TLS backends (mutually exclusive - compile-time checks in oauth/src/lib.rs)
|
||||
# Note: Feature validation is in oauth crate since it's compiled first in the dependency tree.
|
||||
|
@ -133,6 +133,10 @@ with-dns-sd = ["librespot-discovery/with-dns-sd"]
|
|||
# data.
|
||||
passthrough-decoder = ["librespot-playback/passthrough-decoder"]
|
||||
|
||||
# MPRIS: Allow external tool to have access to playback
|
||||
# status, metadata and to control the player.
|
||||
with-mpris = ["dep:zbus", "dep:zvariant"]
|
||||
|
||||
[lib]
|
||||
name = "librespot"
|
||||
path = "src/lib.rs"
|
||||
|
@ -181,7 +185,10 @@ tokio = { version = "1", features = [
|
|||
"sync",
|
||||
"process",
|
||||
] }
|
||||
time = { version = "0.3", features = ["formatting"] }
|
||||
url = "2.2"
|
||||
zbus = { version = "4", default-features = false, features = ["tokio"], optional = true }
|
||||
zvariant = { version = "4", default-features = false, optional = true }
|
||||
|
||||
[package.metadata.deb]
|
||||
maintainer = "Librespot Organization <noreply@github.com>"
|
||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -41,6 +41,11 @@ use url::Url;
|
|||
mod player_event_handler;
|
||||
use player_event_handler::{EventHandler, run_program_on_sink_events};
|
||||
|
||||
#[cfg(feature = "with-mpris")]
|
||||
mod mpris_event_handler;
|
||||
#[cfg(feature = "with-mpris")]
|
||||
use mpris_event_handler::MprisEventHandler;
|
||||
|
||||
fn device_id(name: &str) -> String {
|
||||
HEXLOWER.encode(&Sha1::digest(name.as_bytes()))
|
||||
}
|
||||
|
@ -1991,6 +1996,14 @@ async fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "with-mpris")]
|
||||
let mpris = MprisEventHandler::spawn(player.clone())
|
||||
.await
|
||||
.unwrap_or_else(|e| {
|
||||
error!("could not initialize MPRIS: {e}");
|
||||
exit(1);
|
||||
});
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
credentials = async {
|
||||
|
@ -2044,6 +2057,10 @@ async fn main() {
|
|||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(feature = "with-mpris")]
|
||||
mpris.set_spirc(spirc_.clone());
|
||||
|
||||
spirc = Some(spirc_);
|
||||
spirc_task = Some(Box::pin(spirc_task_));
|
||||
|
||||
|
@ -2089,6 +2106,9 @@ async fn main() {
|
|||
|
||||
let mut shutdown_tasks = tokio::task::JoinSet::new();
|
||||
|
||||
#[cfg(feature = "with-mpris")]
|
||||
shutdown_tasks.spawn(mpris.quit_and_join());
|
||||
|
||||
// Shutdown spirc if necessary
|
||||
if let Some(spirc) = spirc {
|
||||
if let Err(e) = spirc.shutdown() {
|
||||
|
|
1220
src/mpris_event_handler.rs
Normal file
1220
src/mpris_event_handler.rs
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue