fix(jukebox): scrobble and count plays for jukebox playback

Jukebox playback happens entirely server-side via mpv, so the client
never calls the reportPlayback endpoint that normally drives play
counts and scrobbling. As a result, songs played through jukebox mode
were never scrobbled and never incremented their play count.

Thread the existing scrobbler.PlayTracker into the playback device and
report StateStarting/StateStopped transitions at the same points a
client-driven session would: on track start, on skip, on clear, and on
natural end-of-track. The async track-switcher goroutine has no HTTP
request of its own, so the acting user/player/client are captured from
the last jukebox request and carried on the device's long-lived
context for it to use.

Fixes #5693
This commit is contained in:
fossisawesome-macbook-with-linux 2026-07-04 23:39:35 -04:00
commit ad9db704d1
3 changed files with 116 additions and 8 deletions

View file

@ -108,7 +108,7 @@ func CreateSubsonicAPIRouter(ctx context.Context) *subsonic.Router {
playlistsPlaylists := playlists.NewPlaylists(dataStore, imageUploadService)
modelScanner := scanner.New(ctx, dataStore, cacheWarmer, broker, playlistsPlaylists, metricsMetrics)
playTracker := scrobbler.GetPlayTracker(dataStore, broker, manager)
playbackServer := playback.GetInstance(dataStore)
playbackServer := playback.GetInstance(dataStore, playTracker)
lyricsLyrics := lyrics.NewLyrics(dataStore, manager)
transcodeDecider := stream.NewTranscodeDecider(dataStore, fFmpeg)
sonicSonic := sonic.New(dataStore, manager, matcherMatcher)
@ -206,7 +206,11 @@ func CreateScanWatcher(ctx context.Context) scanner.Watcher {
func GetPlaybackServer() playback.PlaybackServer {
sqlDB := db.Db()
dataStore := persistence.New(sqlDB)
playbackServer := playback.GetInstance(dataStore)
broker := events.GetBroker()
metricsMetrics := metrics.GetPrometheusInstance(dataStore)
manager := plugins.GetManager(dataStore, broker, metricsMetrics)
playTracker := scrobbler.GetPlayTracker(dataStore, broker, manager)
playbackServer := playback.GetInstance(dataStore, playTracker)
return playbackServer
}