handle LoopMode logic, plus some reorganization

This commit is contained in:
Drew Weymouth
2023-12-22 16:21:29 -08:00
parent de6ba5c120
commit cf41795659
+54 -25
View File
@@ -80,33 +80,12 @@ func NewPlaybackManager(
transcodeCfg: transcodeCfg, transcodeCfg: transcodeCfg,
nowPlayingIdx: -1, nowPlayingIdx: -1,
} }
p.OnTrackChange(func() { p.OnTrackChange(pm.handleOnTrackChange)
pm.checkScrobble() // scrobble the previous song if needed
if pm.player.GetStatus().State == player.Playing {
pm.playTimeStopwatch.Start()
}
pm.nowPlayingIdx++
pm.curTrackTime = float64(pm.playQueue[pm.nowPlayingIdx].Duration)
pm.sendNowPlayingScrobble() // Must come before invokeOnChangeCallbacks b/c track may immediately be scrobbled
pm.invokeOnSongChangeCallbacks()
pm.doUpdateTimePos()
if pm.nowPlayingIdx < len(pm.playQueue)-1 {
pm.setTrack(pm.nowPlayingIdx+1, true)
}
})
p.OnSeek(func() { p.OnSeek(func() {
pm.doUpdateTimePos() pm.doUpdateTimePos()
pm.invokeNoArgCallbacks(pm.onSeek) pm.invokeNoArgCallbacks(pm.onSeek)
}) })
p.OnStopped(func() { p.OnStopped(pm.handleOnStopped)
pm.playTimeStopwatch.Stop()
pm.checkScrobble()
pm.stopPollTimePos()
pm.doUpdateTimePos()
pm.invokeOnSongChangeCallbacks()
pm.invokeNoArgCallbacks(pm.onStopped)
pm.nowPlayingIdx = -1
})
p.OnPaused(func() { p.OnPaused(func() {
pm.playTimeStopwatch.Stop() pm.playTimeStopwatch.Stop()
pm.stopPollTimePos() pm.stopPollTimePos()
@@ -232,7 +211,7 @@ func (p *PlaybackManager) LoadTracks(tracks []*mediaprovider.Track, appendToQueu
p.playQueue = append(p.playQueue, &tr) p.playQueue = append(p.playQueue, &tr)
} }
if needToSetNext { if needToSetNext {
p.setTrack(p.nowPlayingIdx+1, true) p.setNextTrack(p.nowPlayingIdx + 1)
} }
return nil return nil
} }
@@ -330,6 +309,7 @@ func (p *PlaybackManager) OnTrackRatingChanged(id string, rating int) {
} }
} }
// TODO: fixme!!
func (p *PlaybackManager) RemoveTracksFromQueue(trackIDs []string) { func (p *PlaybackManager) RemoveTracksFromQueue(trackIDs []string) {
newQueue := make([]*mediaprovider.Track, 0, len(p.playQueue)-len(trackIDs)) newQueue := make([]*mediaprovider.Track, 0, len(p.playQueue)-len(trackIDs))
//rmCount := 0 //rmCount := 0
@@ -429,7 +409,7 @@ func (p *PlaybackManager) SetNextLoopMode() {
func (p *PlaybackManager) SetLoopMode(loopMode LoopMode) { func (p *PlaybackManager) SetLoopMode(loopMode LoopMode) {
p.loopMode = loopMode p.loopMode = loopMode
// TODO: update next track if needed p.setNextTrackBasedOnLoopMode()
for _, cb := range p.onLoopModeChange { for _, cb := range p.onLoopModeChange {
cb(loopMode) cb(loopMode)
@@ -516,6 +496,51 @@ func (p *PlaybackManager) PlayPause() error {
return errors.New("unreached - invalid player state") return errors.New("unreached - invalid player state")
} }
func (p *PlaybackManager) handleOnTrackChange() {
p.checkScrobble() // scrobble the previous song if needed
if p.player.GetStatus().State == player.Playing {
p.playTimeStopwatch.Start()
}
if p.loopMode != LoopOne {
p.nowPlayingIdx++
if p.loopMode == LoopAll && p.nowPlayingIdx == len(p.playQueue) {
p.nowPlayingIdx = 0 // wrapped around
}
}
p.curTrackTime = float64(p.playQueue[p.nowPlayingIdx].Duration)
p.sendNowPlayingScrobble() // Must come before invokeOnChangeCallbacks b/c track may immediately be scrobbled
p.invokeOnSongChangeCallbacks()
p.doUpdateTimePos()
p.setNextTrackBasedOnLoopMode()
}
func (p *PlaybackManager) handleOnStopped() {
p.playTimeStopwatch.Stop()
p.checkScrobble()
p.stopPollTimePos()
p.doUpdateTimePos()
p.invokeOnSongChangeCallbacks()
p.invokeNoArgCallbacks(p.onStopped)
p.nowPlayingIdx = -1
}
func (p *PlaybackManager) setNextTrackBasedOnLoopMode() {
switch p.loopMode {
case LoopNone:
if p.nowPlayingIdx < len(p.playQueue)-1 {
p.setNextTrack(p.nowPlayingIdx + 1)
}
case LoopOne:
p.setNextTrack(p.nowPlayingIdx)
case LoopAll:
if p.nowPlayingIdx >= len(p.playQueue)-1 {
p.setNextTrack(0)
} else {
p.setNextTrack(p.nowPlayingIdx + 1)
}
}
}
func (p *PlaybackManager) setTrack(idx int, next bool) error { func (p *PlaybackManager) setTrack(idx int, next bool) error {
if urlP, ok := p.player.(player.URLPlayer); ok { if urlP, ok := p.player.(player.URLPlayer); ok {
url, err := p.sm.Server.GetStreamURL(p.playQueue[idx].ID, p.transcodeCfg.ForceRawFile) url, err := p.sm.Server.GetStreamURL(p.playQueue[idx].ID, p.transcodeCfg.ForceRawFile)
@@ -535,6 +560,10 @@ func (p *PlaybackManager) setTrack(idx int, next bool) error {
panic("Unsupported player type") panic("Unsupported player type")
} }
func (p *PlaybackManager) setNextTrack(idx int) error {
return p.setTrack(idx, true)
}
// call BEFORE updating p.nowPlayingIdx // call BEFORE updating p.nowPlayingIdx
func (p *PlaybackManager) checkScrobble() { func (p *PlaybackManager) checkScrobble() {
if !p.scrobbleCfg.Enabled || len(p.playQueue) == 0 || p.nowPlayingIdx < 0 { if !p.scrobbleCfg.Enabled || len(p.playQueue) == 0 || p.nowPlayingIdx < 0 {