feat: album cover art in Discord Rich Presence via iTunes Search API

Fetches album artwork from the iTunes Search API and passes the URL
directly to Discord's large_image field. Subsonic cover URLs require
auth and can't be used by Discord directly.

- 3-strategy search: exact quoted → relaxed → track title fallback
- 1-hour in-memory cache per artist|album key
- iTunes search runs in tokio::task::spawn_blocking (reqwest::blocking
  must not run on the Tokio async executor)
- artwork_cache wrapped in Arc<Mutex<...>> for cross-thread sharing
- Fallback to the pre-uploaded "psysonic" asset when no match found
- Cargo.toml: blocking feature alongside rustls-tls

Co-Authored-By: kilyabin <kilyabin@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-06 19:30:22 +02:00
parent b448c2bc82
commit 1197c1f916
4 changed files with 237 additions and 16 deletions
+3
View File
@@ -522,6 +522,9 @@ export function initAudioListeners(): () => void {
// Pass elapsed when playing so Discord shows a live running timer.
// Pass null when paused — Discord shows the song/artist without a timer.
elapsedSecs: isPlaying ? currentTime : null,
// coverArtUrl is intentionally not passed — Subsonic URLs require auth.
// Backend will fetch artwork from iTunes Search API instead.
coverArtUrl: null,
}).catch(() => {});
}