forked from Keelrleek/SoulStream
Registering with the System Media Transport Controls is what makes an app a media app to the OS rather than a window that happens to make noise. The card that the media-key overlay, the taskbar media flyout and the lock screen all draw now carries our cover, title, artist and album; the hardware media keys reach us with the window unfocused; and the transport buttons on that card drive this app. Verified against the OS's own session list: title/artist/album/albumArtist, type Music, a live scrubber, a present thumbnail, and play disabled while playing. Where each half of it comes from follows where the truth already lives. Status and position are pushed by the backend's player event pump, which already sees every transport change and every position tick — the card is driven by the same events the UI is, so it cannot drift from the window, and it costs no IPC at all. Metadata goes the other way, once per track, published by the player bar: the queue lives in the frontend and so does the derivation the bar displays, and publishing exactly what the bar shows means the two can never disagree. Deriving it a second time in Rust would guarantee that one day they do. Button presses are forwarded as `soulseek:media-button` rather than handled in Rust, because nextTrack knows about shuffle, repeat, the album fill and re-sourcing a track restored from the last session, and none of that is knowable from that side. They run the same functions the on-screen transport runs — the play/pause branch moved into togglePlayPause() so there is one implementation, not two that drift. Proven by driving the app from the OS session: next advanced the queue, pause and play moved the status, previous restarted the track on the >3s rule the app already had. Stop is deliberately disabled: this transport has no stop, only pause, and a dead button on the card is worse than a missing one. Buffering maps to Changing, which is what "finding best source…" honestly is. The thumbnail is the bar's own data URL decoded into an in-memory stream — no temp files — and it is explicitly cleared when a track has no cover, because the previous track's art outliving it is worse than none. The debug handle gains the local playback entry points beside the streaming ones it already had. That is not only convenience: verifying this end to end needs a track playing, and every run that reaches for Soulseek to get one costs a login the server starts ignoring after a burst.
53 lines
1.4 KiB
TOML
53 lines
1.4 KiB
TOML
[package]
|
|
name = "app"
|
|
version.workspace = true
|
|
description = "SoulStream — music player, downloader and streamer for the Soulseek network"
|
|
authors.workspace = true
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
|
|
[lib]
|
|
name = "app_lib"
|
|
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
|
|
[build-dependencies]
|
|
tauri-build = { version = "2", features = [] }
|
|
|
|
[dependencies]
|
|
tauri = { version = "2", features = [] }
|
|
tauri-plugin-log = "2"
|
|
tauri-plugin-dialog = "2"
|
|
serde.workspace = true
|
|
serde_json.workspace = true
|
|
log.workspace = true
|
|
image.workspace = true
|
|
tokio.workspace = true
|
|
|
|
base64 = "0.22"
|
|
keyring = { version = "3", features = ["windows-native"] }
|
|
sysinfo = "0.33"
|
|
soulseek-proto = { path = "../crates/soulseek-proto" }
|
|
soulseek-client = { path = "../crates/soulseek-client" }
|
|
player = { path = "../crates/player" }
|
|
tagger = { path = "../crates/tagger" }
|
|
metadata = { path = "../crates/metadata" }
|
|
library = { path = "../crates/library" }
|
|
|
|
[target.'cfg(windows)'.dependencies]
|
|
windows = { version = "0.61.3", features = [
|
|
"AI_MachineLearning",
|
|
"Foundation_Collections",
|
|
"Globalization",
|
|
"Graphics_Imaging",
|
|
# SystemMediaTransportControls — the OS media card (see src/smtc.rs).
|
|
"Media",
|
|
"Media_FaceAnalysis",
|
|
"Media_Ocr",
|
|
"Storage_Streams",
|
|
"Win32_Foundation",
|
|
"Win32_System_Performance",
|
|
"Win32_System_ProcessStatus",
|
|
"Win32_System_Threading",
|
|
"Win32_System_WinRT",
|
|
] }
|