Fix #578: scrobble correct track when skipping next

This commit is contained in:
Drew Weymouth
2025-03-12 17:11:01 -07:00
parent 7d39ea4daf
commit c79be131a7
+26 -8
View File
@@ -48,12 +48,15 @@ type playbackEngine struct {
latestTrackPosition float64 // cleared by checkScrobble latestTrackPosition float64 // cleared by checkScrobble
callbacksDisabled bool callbacksDisabled bool
playQueue []mediaprovider.MediaItem playQueue []mediaprovider.MediaItem
nowPlayingIdx int nowPlayingIdx int
isRadio bool isRadio bool
loopMode LoopMode
// flags for handleOnTrackChange / handleOnStopped callbacks - reset to false in the callbacks
wasStopped bool // true iff player was stopped before handleOnTrackChange invocation wasStopped bool // true iff player was stopped before handleOnTrackChange invocation
noIncrementNextTrackChange bool // true iff the nowPlayingIndex should not be incremente don the next onTrackChange noIncrementNextTrackChange bool // true iff the nowPlayingIndex should not be incremented on the next onTrackChange
loopMode LoopMode alreadyScrobbled bool // true iff the previously-playing track was already scrobbled
// to pass to onSongChange listeners; clear once listeners have been called // to pass to onSongChange listeners; clear once listeners have been called
lastScrobbled *mediaprovider.Track lastScrobbled *mediaprovider.Track
@@ -127,6 +130,9 @@ func (p *playbackEngine) PlayTrackAt(idx int) error {
if idx < 0 || idx >= len(p.playQueue) { if idx < 0 || idx >= len(p.playQueue) {
return errors.New("track index out of range") return errors.New("track index out of range")
} }
// scrobble current track if needed
p.checkScrobble()
p.alreadyScrobbled = true
p.noIncrementNextTrackChange = true p.noIncrementNextTrackChange = true
err := p.setTrack(idx, false) err := p.setTrack(idx, false)
if err == nil { if err == nil {
@@ -385,6 +391,7 @@ func (p *playbackEngine) RemoveTracksFromQueue(idxs []int) {
isPlayingTrackRemoved = true isPlayingTrackRemoved = true
// If we are removing the currently playing track, we need to scrobble it // If we are removing the currently playing track, we need to scrobble it
p.checkScrobble() p.checkScrobble()
p.alreadyScrobbled = true
} else if nowPlaying >= 0 && i == nowPlaying+1 { } else if nowPlaying >= 0 && i == nowPlaying+1 {
isNextPlayingTrackremoved = true isNextPlayingTrackremoved = true
} }
@@ -456,7 +463,11 @@ func (p *playbackEngine) SetReplayGainMode(mode player.ReplayGainMode) {
} }
func (p *playbackEngine) handleOnTrackChange() { func (p *playbackEngine) handleOnTrackChange() {
p.checkScrobble() // scrobble the previous song if needed // scrobble the previous song if needed
if !p.alreadyScrobbled {
p.checkScrobble()
}
if p.player.GetStatus().State == player.Playing { if p.player.GetStatus().State == player.Playing {
p.playTimeStopwatch.Start() p.playTimeStopwatch.Start()
} }
@@ -466,11 +477,15 @@ func (p *playbackEngine) handleOnTrackChange() {
p.nowPlayingIdx = 0 // wrapped around p.nowPlayingIdx = 0 // wrapped around
} }
} }
p.noIncrementNextTrackChange = false
nowPlaying := p.playQueue[p.nowPlayingIdx] nowPlaying := p.playQueue[p.nowPlayingIdx]
_, isRadio := nowPlaying.(*mediaprovider.RadioStation) _, isRadio := nowPlaying.(*mediaprovider.RadioStation)
p.isRadio = isRadio p.isRadio = isRadio
// reset flags
p.noIncrementNextTrackChange = false
p.wasStopped = false p.wasStopped = false
p.alreadyScrobbled = false
p.curTrackDuration = float64(nowPlaying.Metadata().Duration) p.curTrackDuration = float64(nowPlaying.Metadata().Duration)
p.sendNowPlayingScrobble() // Must come before invokeOnChangeCallbacks b/c track may immediately be scrobbled p.sendNowPlayingScrobble() // Must come before invokeOnChangeCallbacks b/c track may immediately be scrobbled
p.invokeOnSongChangeCallbacks() p.invokeOnSongChangeCallbacks()
@@ -480,11 +495,14 @@ func (p *playbackEngine) handleOnTrackChange() {
func (p *playbackEngine) handleOnStopped() { func (p *playbackEngine) handleOnStopped() {
p.playTimeStopwatch.Stop() p.playTimeStopwatch.Stop()
p.checkScrobble() if !p.alreadyScrobbled {
p.checkScrobble()
}
p.stopPollTimePos() p.stopPollTimePos()
p.doUpdateTimePos(false) p.doUpdateTimePos(false)
p.invokeOnSongChangeCallbacks() p.invokeOnSongChangeCallbacks()
p.invokeNoArgCallbacks(p.onStopped) p.invokeNoArgCallbacks(p.onStopped)
p.alreadyScrobbled = false
p.wasStopped = true p.wasStopped = true
p.nowPlayingIdx = -1 p.nowPlayingIdx = -1
} }