Skip to main content
MusicVoting
  1. Technical Docs/

Spotify-Integration

·274 words·2 mins·
Developer
Table of Contents

Spotify ist über das MusicProvider-Interface angebunden (SpotifyMusicProvider, ausgewählt per MusicProviderFactory). Pro Party hält SpotifyCredentials Access-/Refresh-Token, Ablaufzeit, deviceId und lastPlaybackActive.

Important

Spotify-Wiedergabe erfordert ein Premium-Konto des Hosts (Playback-API ist Premium-only).

OAuth-Flow
#

  1. Host erstellt die Party (POST /api/party) und geht zu GET /api/party/{id}/spotify/login.
  2. Login leitet zur Spotify-Consent-Seite weiter (state trägt den Party-Bezug).
  3. Spotify ruft GET /api/spotify/callback?code=&state= (Web) bzw. /api/spotify/ios/callback (iOS).
  4. Das Backend tauscht den code gegen Access-/Refresh-Token und bindet sie an diese Party.

Tokens sind party-scoped: nicht zwischen Partys geteilt, beim Party-Ende gelöscht. Eine neue Party erfordert einen neuen Login.

PlantUML diagram

Automatischer Token-Refresh
#

Ein Access-Token läuft nach ~1 h ab. Damit eine Party länger als eine Stunde ohne Host-Eingriff läuft:

  • Proaktiv: Läuft das Token in < 60 s ab, erneuert das Backend es vor der nächsten Anfrage.
  • Reaktiv: Bei HTTP 401 von Spotify erneuert das Backend das Token einmal per Refresh-Token und wiederholt den Request.
  • Fehlschlag: Schlägt der Refresh fehl (Token widerrufen), liefert das Backend 401 mit "Spotify-Sitzung abgelaufen. Bitte neu anmelden." – der Host muss die Party neu starten.

Wiedergabe & Geräte-Registrierung
#

  • Die Startpage/TV lädt das Spotify Web Playback SDK (Token über GET /api/party/{id}/spotify/token) und registriert ein Playback-Gerät via PUT /api/party/{id}/spotify/deviceId.
  • deviceActive (in GET /track/current) ist true, sobald eine nicht-leere deviceId registriert ist. Solange false, sind Host-Controls gesperrt.
  • Re-Registrierung setzt fort, statt zurückzuspulen: restoreCurrentTrackOnDevice berechnet die aktuelle Position (pausedPositionMs bzw. now() − playbackStartedAt) und spielt den aktuellen Track mit position_ms an dieser Stelle; danach track-changed-Event.

Wichtig
#

  • GET /track/current ruft nicht Spotifys „currently-playing“-API auf – der aktuelle Track und der Fortschritt kommen aus der DB (currently_playing_entry_id, playback_started_at, paused_position_ms).
  • Die Queue wird nie aus der Spotify-Playlist gelesen; die DB ist die Quelle der Wahrheit.