fix behavior of switching players while paused

This commit is contained in:
Drew Weymouth
2025-04-05 10:57:19 -07:00
parent 6e7480f48a
commit 28baf912f2
8 changed files with 57 additions and 37 deletions
+1 -1
View File
@@ -404,7 +404,7 @@ func (a *App) SetupWindowsSMTC(hwnd uintptr) {
})
a.PlaybackManager.OnSeek(func() {
dur := a.PlaybackManager.NowPlaying().Metadata().Duration
smtc.UpdatePosition(int(a.PlaybackManager.PlayerStatus().TimePos*1000), dur*1000)
smtc.UpdatePosition(int(a.PlaybackManager.PlaybackStatus().TimePos*1000), dur*1000)
})
a.PlaybackManager.OnPlaying(func() {
smtc.SetEnabled(true)
+3 -3
View File
@@ -84,17 +84,17 @@ func InitMPMediaHandler(playbackManager *PlaybackManager, artURLLookup func(trac
})
mp.playbackManager.OnSeek(func() {
C.update_os_now_playing_info_position(C.double(mp.playbackManager.PlayerStatus().TimePos))
C.update_os_now_playing_info_position(C.double(mp.playbackManager.PlaybackStatus().TimePos))
})
mp.playbackManager.OnPlaying(func() {
C.set_os_playback_state_playing()
C.update_os_now_playing_info_position(C.double(mp.playbackManager.PlayerStatus().TimePos))
C.update_os_now_playing_info_position(C.double(mp.playbackManager.PlaybackStatus().TimePos))
})
mp.playbackManager.OnPaused(func() {
C.set_os_playback_state_paused()
C.update_os_now_playing_info_position(C.double(mp.playbackManager.PlayerStatus().TimePos))
C.update_os_now_playing_info_position(C.double(mp.playbackManager.PlaybackStatus().TimePos))
})
return nil
+6 -6
View File
@@ -54,7 +54,7 @@ func NewMPRISHandler(playerName string, pm *PlaybackManager) *MPRISHandler {
pm.OnSeek(func() {
if m.connErr == nil {
pos := secondsToMicroseconds(pm.PlayerStatus().TimePos)
pos := secondsToMicroseconds(pm.PlaybackStatus().TimePos)
m.evt.Player.OnSeek(pos)
}
})
@@ -160,7 +160,7 @@ func (m *MPRISHandler) Previous() error {
}
func (m *MPRISHandler) Pause() error {
if m.pm.PlayerStatus().State == player.Playing {
if m.pm.PlaybackStatus().State == player.Playing {
m.pm.PlayPause()
}
return nil
@@ -177,7 +177,7 @@ func (m *MPRISHandler) Stop() error {
}
func (m *MPRISHandler) Play() error {
switch m.pm.PlayerStatus().State {
switch m.pm.PlaybackStatus().State {
case player.Paused:
m.pm.PlayPause()
case player.Stopped:
@@ -204,7 +204,7 @@ func (m *MPRISHandler) OpenUri(uri string) error {
}
func (m *MPRISHandler) PlaybackStatus() (types.PlaybackStatus, error) {
switch m.pm.PlayerStatus().State {
switch m.pm.PlaybackStatus().State {
case player.Playing:
return types.PlaybackStatusPlaying, nil
case player.Paused:
@@ -254,7 +254,7 @@ func (m *MPRISHandler) Metadata() (types.Metadata, error) {
if m.curTrackPath != "" {
trackObjPath = m.curTrackPath
}
status := m.pm.PlayerStatus()
status := m.pm.PlaybackStatus()
var meta mediaprovider.MediaItemMetadata
// metadata that can come only from tracks
@@ -307,7 +307,7 @@ func (m *MPRISHandler) SetVolume(v float64) error {
}
func (m *MPRISHandler) Position() (int64, error) {
return int64(secondsToMicroseconds(m.pm.PlayerStatus().TimePos)), nil
return int64(secondsToMicroseconds(m.pm.PlaybackStatus().TimePos)), nil
}
func (m *MPRISHandler) MinimumRate() (float64, error) {
+31 -18
View File
@@ -40,6 +40,14 @@ const (
LoopOne
)
type PlaybackState = player.State
type PlaybackStatus struct {
State PlaybackState
TimePos float64
Duration float64
}
type playbackEngine struct {
ctx context.Context
cancelPollPos context.CancelFunc
@@ -65,8 +73,8 @@ type playbackEngine struct {
// and reset this to -1
pendingTrackChangeNum int
pendingPlayerChange bool
pendingPlayerChangeTimePos float64
pendingPlayerChange bool
pendingPlayerChangeStatus player.Status
// to pass to onSongChange listeners; clear once listeners have been called
lastScrobbled *mediaprovider.Track
@@ -155,7 +163,7 @@ func (p *playbackEngine) SetPlayer(pl player.BasePlayer) error {
needToUnpause := false
stat := p.PlayerStatus()
stat := p.CurrentPlayer().GetStatus()
if p.pendingPlayerChange {
stat.State = player.Paused
}
@@ -165,9 +173,10 @@ func (p *playbackEngine) SetPlayer(pl player.BasePlayer) error {
// nothing
case player.Playing:
needToUnpause = true
p.stopPollTimePos()
fallthrough
case player.Paused:
p.pendingPlayerChangeTimePos = stat.TimePos
p.pendingPlayerChangeStatus = stat
p.pendingPlayerChange = true
}
p.unregisterPlayerCallbacks(p.player)
@@ -183,7 +192,7 @@ func (p *playbackEngine) SetPlayer(pl player.BasePlayer) error {
p.registerPlayerCallbacks(pl)
if needToUnpause {
p.playTrackAt(p.nowPlayingIdx, p.pendingPlayerChangeTimePos)
p.playTrackAt(p.nowPlayingIdx, p.pendingPlayerChangeStatus.TimePos)
p.pendingPlayerChange = false
}
p.invokeNoArgCallbacks(p.onPlayerChange)
@@ -239,8 +248,16 @@ func (p *playbackEngine) GetLoopMode() LoopMode {
return p.loopMode
}
func (p *playbackEngine) PlayerStatus() player.Status {
return p.player.GetStatus()
func (p *playbackEngine) PlaybackStatus() PlaybackStatus {
stat := p.pendingPlayerChangeStatus
if !p.pendingPlayerChange {
stat = p.CurrentPlayer().GetStatus()
}
return PlaybackStatus{
State: stat.State,
TimePos: stat.TimePos,
Duration: stat.Duration,
}
}
func (p *playbackEngine) SetVolume(vol int) error {
@@ -259,14 +276,14 @@ func (p *playbackEngine) CurrentPlayer() player.BasePlayer {
}
func (p *playbackEngine) SeekNext() error {
if p.PlayerStatus().State == player.Stopped {
if p.PlaybackStatus().State == player.Stopped {
return nil
}
return p.PlayTrackAt(p.nowPlayingIdx + 1)
}
func (p *playbackEngine) SeekBackOrPrevious() error {
if p.nowPlayingIdx == 0 || p.PlayerStatus().TimePos > 3 {
if p.nowPlayingIdx == 0 || p.PlaybackStatus().TimePos > 3 {
return p.player.SeekSeconds(0)
}
return p.PlayTrackAt(p.nowPlayingIdx - 1)
@@ -274,7 +291,7 @@ func (p *playbackEngine) SeekBackOrPrevious() error {
func (p *playbackEngine) SeekFwdBackN(n int) error {
idx := p.nowPlayingIdx
if n < 0 && p.PlayerStatus().TimePos > 3 {
if n < 0 && p.PlaybackStatus().TimePos > 3 {
n += 1 // first seek back is just seek to beginning of current
}
if n == 0 || (idx == 0 && n < 0) {
@@ -310,15 +327,11 @@ func (p *playbackEngine) Pause() error {
func (p *playbackEngine) Continue() error {
if p.pendingPlayerChange {
err := p.PlayTrackAt(p.nowPlayingIdx)
if p.pendingPlayerChangeTimePos != 0 {
p.SeekSeconds(p.pendingPlayerChangeTimePos)
}
p.pendingPlayerChange = false
return err
return p.playTrackAt(p.nowPlayingIdx, p.pendingPlayerChangeStatus.TimePos)
}
if p.PlayerStatus().State == player.Stopped {
if p.PlaybackStatus().State == player.Stopped {
return p.PlayTrackAt(0)
}
return p.player.Continue()
@@ -548,7 +561,7 @@ func (p *playbackEngine) handleOnTrackChange() {
p.checkScrobble()
}
if p.PlayerStatus().State == player.Playing {
if p.PlaybackStatus().State == player.Playing {
p.playTimeStopwatch.Start()
}
if p.pendingTrackChangeNum < 0 && (p.wasStopped || p.loopMode != LoopOne) {
@@ -785,7 +798,7 @@ func (p *playbackEngine) doUpdateTimePos(seeked bool) {
if p.callbacksDisabled {
return
}
s := p.PlayerStatus()
s := p.PlaybackStatus()
if s.TimePos > p.latestTrackPosition {
p.latestTrackPosition = s.TimePos
}
+5 -5
View File
@@ -85,7 +85,7 @@ func (p *PlaybackManager) addOnTrackChangeHook() {
return
}
// workaround for https://github.com/dweymouth/supersonic/issues/483 (see above comment)
if p.NowPlayingIndex() != len(p.engine.playQueue) && p.PlayerStatus().State == player.Playing {
if p.NowPlayingIndex() != len(p.engine.playQueue) && p.PlaybackStatus().State == player.Playing {
p.lastPlayTime = 0
go func() {
time.Sleep(300 * time.Millisecond)
@@ -476,8 +476,8 @@ func (p *PlaybackManager) IsAutoplay() bool {
return p.autoplay
}
func (p *PlaybackManager) PlayerStatus() player.Status {
return p.engine.PlayerStatus()
func (p *PlaybackManager) PlaybackStatus() PlaybackStatus {
return p.engine.PlaybackStatus()
}
func (p *PlaybackManager) SetVolume(vol int) {
@@ -510,7 +510,7 @@ func (p *PlaybackManager) SeekSeconds(sec float64) {
// Seek by given relative position in the current track by seconds.
func (p *PlaybackManager) SeekBySeconds(sec float64) {
status := p.engine.PlayerStatus()
status := p.engine.PlaybackStatus()
target := status.TimePos + sec
if target < 0 {
target = 0
@@ -548,7 +548,7 @@ func (p *PlaybackManager) Continue() {
}
func (p *PlaybackManager) PlayPause() {
switch p.engine.PlayerStatus().State {
switch p.engine.PlaybackStatus().State {
case player.Playing:
p.Pause()
case player.Paused:
+1 -1
View File
@@ -26,7 +26,7 @@ type serializedSavedPlayQueue struct {
// If the provided CanSavePlayQueue server is non-nil, it will also save to the server.
func SavePlayQueue(serverID string, pm *PlaybackManager, filepath string, server mediaprovider.CanSavePlayQueue) error {
queue := pm.GetPlayQueue()
stats := pm.PlayerStatus()
stats := pm.PlaybackStatus()
trackIdx := pm.NowPlayingIndex()
trackIDs := make([]string, 0, len(queue))