Merge pull request #793 from Tim-Kaiser/ISSUE/787
Fixes #787 : StopAfterCurrent shouldn't clear the queue
This commit is contained in:
+2
-2
@@ -598,8 +598,8 @@ func (a *App) checkFlagsAndSendIPCMsg(cli *ipc.Client) error {
|
||||
return cli.SeekNext()
|
||||
case *FlagStop:
|
||||
return cli.Stop()
|
||||
case *FlagStopAfterCurrent:
|
||||
return cli.StopAfterCurrent()
|
||||
case *FlagPauseAfterCurrent:
|
||||
return cli.PauseAfterCurrent()
|
||||
case *FlagShow:
|
||||
return cli.Show()
|
||||
case VolumeCLIArg >= 0:
|
||||
|
||||
+12
-12
@@ -22,18 +22,18 @@ var (
|
||||
SearchPlaylistCLIArg string = ""
|
||||
SearchTrackCLIArg string = ""
|
||||
|
||||
FlagPlay = flag.Bool("play", false, "unpause or begin playback")
|
||||
FlagPause = flag.Bool("pause", false, "pause playback")
|
||||
FlagPlayPause = flag.Bool("play-pause", false, "toggle play/pause state")
|
||||
FlagPrevious = flag.Bool("previous", false, "seek to previous track or beginning of current")
|
||||
FlagNext = flag.Bool("next", false, "seek to next track")
|
||||
FlagStop = flag.Bool("stop", false, "stop playback")
|
||||
FlagStopAfterCurrent = flag.Bool("stop-after-current", false, "stop playback after current track")
|
||||
FlagStartMinimized = flag.Bool("start-minimized", false, "start app minimized")
|
||||
FlagShow = flag.Bool("show", false, "show minimized app")
|
||||
FlagShuffle = flag.Bool("shuffle", false, "shuffle the tracklist (to be used with either -play-album-by-id or -play-playlist-by-id)")
|
||||
FlagVersion = flag.Bool("version", false, "print app version and exit")
|
||||
FlagHelp = flag.Bool("help", false, "print command line options and exit")
|
||||
FlagPlay = flag.Bool("play", false, "unpause or begin playback")
|
||||
FlagPause = flag.Bool("pause", false, "pause playback")
|
||||
FlagPlayPause = flag.Bool("play-pause", false, "toggle play/pause state")
|
||||
FlagPrevious = flag.Bool("previous", false, "seek to previous track or beginning of current")
|
||||
FlagNext = flag.Bool("next", false, "seek to next track")
|
||||
FlagStop = flag.Bool("stop", false, "stop playback")
|
||||
FlagPauseAfterCurrent = flag.Bool("pause-after-current", false, "pause playback after current track")
|
||||
FlagStartMinimized = flag.Bool("start-minimized", false, "start app minimized")
|
||||
FlagShow = flag.Bool("show", false, "show minimized app")
|
||||
FlagShuffle = flag.Bool("shuffle", false, "shuffle the tracklist (to be used with either -play-album-by-id or -play-playlist-by-id)")
|
||||
FlagVersion = flag.Bool("version", false, "print app version and exit")
|
||||
FlagHelp = flag.Bool("help", false, "print command line options and exit")
|
||||
|
||||
FlagPlayAlbum *bool
|
||||
FlagPlayPlaylist *bool
|
||||
|
||||
+20
-20
@@ -7,26 +7,26 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
PingPath = "/ping"
|
||||
PlayPath = "/transport/play"
|
||||
PlayAlbumPath = "/transport/play-album" // ?id=<album ID>&t=<firstTrack>&s=<shuffle>
|
||||
PlayPlaylistPath = "/transport/play-playlist" // ?id=<playlist ID>&t=<firstTrack>&s=<shuffle>
|
||||
PlayTrackPath = "/transport/play-track" // ?id=<track ID>
|
||||
SearchAlbumPath = "/transport/search-album" // ?s=<searchQuery>
|
||||
SearchPlaylistPath = "/transport/search-playlist" // ?s=<searchQuery>
|
||||
SearchTrackPath = "/transport/search-track" // ?s=<searchQuery>
|
||||
PlayPausePath = "/transport/playpause"
|
||||
PausePath = "/transport/pause"
|
||||
StopPath = "/transport/stop"
|
||||
StopAfterCurrentPath = "/transport/stop-after-current"
|
||||
PreviousPath = "/transport/previous"
|
||||
NextPath = "/transport/next"
|
||||
TimePosPath = "/transport/timepos" // ?s=<seconds>
|
||||
SeekByPath = "/transport/seek-by" // ?s=<+/- seconds>
|
||||
VolumePath = "/volume" // ?v=<vol>
|
||||
VolumeAdjustPath = "/volume/adjust" // ?pct=<+/- percentage>
|
||||
ShowPath = "/window/show"
|
||||
QuitPath = "/window/quit"
|
||||
PingPath = "/ping"
|
||||
PlayPath = "/transport/play"
|
||||
PlayAlbumPath = "/transport/play-album" // ?id=<album ID>&t=<firstTrack>&s=<shuffle>
|
||||
PlayPlaylistPath = "/transport/play-playlist" // ?id=<playlist ID>&t=<firstTrack>&s=<shuffle>
|
||||
PlayTrackPath = "/transport/play-track" // ?id=<track ID>
|
||||
SearchAlbumPath = "/transport/search-album" // ?s=<searchQuery>
|
||||
SearchPlaylistPath = "/transport/search-playlist" // ?s=<searchQuery>
|
||||
SearchTrackPath = "/transport/search-track" // ?s=<searchQuery>
|
||||
PlayPausePath = "/transport/playpause"
|
||||
PausePath = "/transport/pause"
|
||||
StopPath = "/transport/stop"
|
||||
PauseAfterCurrentPath = "/transport/pause-after-current"
|
||||
PreviousPath = "/transport/previous"
|
||||
NextPath = "/transport/next"
|
||||
TimePosPath = "/transport/timepos" // ?s=<seconds>
|
||||
SeekByPath = "/transport/seek-by" // ?s=<+/- seconds>
|
||||
VolumePath = "/volume" // ?v=<vol>
|
||||
VolumeAdjustPath = "/volume/adjust" // ?pct=<+/- percentage>
|
||||
ShowPath = "/window/show"
|
||||
QuitPath = "/window/quit"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
|
||||
@@ -83,8 +83,8 @@ func (c *Client) Stop() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) StopAfterCurrent() error {
|
||||
_, err := c.sendRequest(StopAfterCurrentPath)
|
||||
func (c *Client) PauseAfterCurrent() error {
|
||||
_, err := c.sendRequest(PauseAfterCurrentPath)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ type PlaybackHandler interface {
|
||||
Continue()
|
||||
SeekBackOrPrevious()
|
||||
SeekNext()
|
||||
SetStopAfterCurrent(bool)
|
||||
SetPauseAfterCurrent(bool)
|
||||
SeekSeconds(float64)
|
||||
SeekBySeconds(float64)
|
||||
Volume() int
|
||||
@@ -83,8 +83,8 @@ func (s *serverImpl) createHandler() http.Handler {
|
||||
m.HandleFunc(PausePath, s.makeSimpleEndpointHandler(s.pbHandler.Pause))
|
||||
m.HandleFunc(PlayPausePath, s.makeSimpleEndpointHandler(s.pbHandler.PlayPause))
|
||||
m.HandleFunc(StopPath, s.makeSimpleEndpointHandler(s.pbHandler.Stop))
|
||||
m.HandleFunc(StopAfterCurrentPath, s.makeSimpleEndpointHandler(func() {
|
||||
s.pbHandler.SetStopAfterCurrent(true)
|
||||
m.HandleFunc(PauseAfterCurrentPath, s.makeSimpleEndpointHandler(func() {
|
||||
s.pbHandler.SetPauseAfterCurrent(true)
|
||||
}))
|
||||
m.HandleFunc(PreviousPath, s.makeSimpleEndpointHandler(s.pbHandler.SeekBackOrPrevious))
|
||||
m.HandleFunc(NextPath, s.makeSimpleEndpointHandler(s.pbHandler.SeekNext))
|
||||
|
||||
+11
-10
@@ -66,7 +66,7 @@ type playbackEngine struct {
|
||||
isRadio bool
|
||||
loopMode LoopMode
|
||||
|
||||
stopAfterCurrent bool // flag to stop playback after current track ends
|
||||
pauseAfterCurrent bool // flag to pause playback after current track ends
|
||||
|
||||
// flags for handleOnTrackChange / handleOnStopped callbacks - reset to false in the callbacks
|
||||
wasStopped bool // true iff player was stopped before handleOnTrackChange invocation
|
||||
@@ -337,13 +337,8 @@ func (p *playbackEngine) Stop() error {
|
||||
return p.player.Stop(false)
|
||||
}
|
||||
|
||||
func (p *playbackEngine) SetStopAfterCurrent(stopAfterCurrent bool) {
|
||||
p.stopAfterCurrent = stopAfterCurrent
|
||||
if p.stopAfterCurrent {
|
||||
p.setNextTrack(-1) // clear next playing track from internal player, if any
|
||||
} else if p.loopMode != LoopNone || p.nowPlayingIdx < len(p.playQueue)-1 {
|
||||
p.needToSetNextTrack = true // need to restore next track to internal player queue
|
||||
}
|
||||
func (p *playbackEngine) SetPauseAfterCurrent(pauseAfterCurrent bool) {
|
||||
p.pauseAfterCurrent = pauseAfterCurrent
|
||||
}
|
||||
|
||||
func (p *playbackEngine) Pause() error {
|
||||
@@ -632,6 +627,12 @@ func (p *playbackEngine) handleOnTrackChange() {
|
||||
p.invokeOnSongChangeCallbacks()
|
||||
p.handleTimePosUpdate(false)
|
||||
p.handleNextTrackUpdated()
|
||||
|
||||
if p.pauseAfterCurrent {
|
||||
p.Pause()
|
||||
p.SetPauseAfterCurrent(false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (p *playbackEngine) handleOnStopped() {
|
||||
@@ -646,7 +647,7 @@ func (p *playbackEngine) handleOnStopped() {
|
||||
p.alreadyScrobbled = false
|
||||
p.wasStopped = true
|
||||
p.nowPlayingIdx = -1
|
||||
p.stopAfterCurrent = false
|
||||
p.pauseAfterCurrent = false
|
||||
}
|
||||
|
||||
// to be invoked as soon as the next item in the queue that should play changes
|
||||
@@ -868,7 +869,7 @@ func (p *playbackEngine) handleTimePosUpdate(seeked bool) {
|
||||
meta = np.Metadata()
|
||||
}
|
||||
isNearEnd := meta.Type != mediaprovider.MediaItemTypeRadioStation && s.TimePos > meta.Duration.Seconds()-10
|
||||
if p.needToSetNextTrack && !p.stopAfterCurrent && isNearEnd {
|
||||
if p.needToSetNextTrack && isNearEnd {
|
||||
p.needToSetNextTrack = false
|
||||
p.setNextTrack(p.nextPlayingIndex())
|
||||
}
|
||||
|
||||
@@ -687,12 +687,12 @@ func (p *PlaybackManager) PlayPause() {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PlaybackManager) SetStopAfterCurrent(stopAfterCurrent bool) {
|
||||
p.engine.SetStopAfterCurrent(stopAfterCurrent)
|
||||
func (p *PlaybackManager) SetPauseAfterCurrent(pauseAfterCurrent bool) {
|
||||
p.engine.SetPauseAfterCurrent(pauseAfterCurrent)
|
||||
}
|
||||
|
||||
func (p *PlaybackManager) IsStopAfterCurrent() bool {
|
||||
return p.engine.stopAfterCurrent
|
||||
func (p *PlaybackManager) IsPauseAfterCurrent() bool {
|
||||
return p.engine.pauseAfterCurrent
|
||||
}
|
||||
|
||||
func (p *PlaybackManager) enqueueAutoplayTracks() {
|
||||
@@ -827,7 +827,14 @@ func (p *PlaybackManager) runCmdQueue(ctx context.Context) {
|
||||
case cmdForceRestartPlayback:
|
||||
if mpv, ok := p.engine.CurrentPlayer().(*mpv.Player); ok {
|
||||
log.Println("Force-restarting MPV playback")
|
||||
mpv.ForceRestartPlayback()
|
||||
|
||||
// restart player, but perserve the state
|
||||
isPaused := false
|
||||
stat := p.engine.CurrentPlayer().GetStatus()
|
||||
if stat.State == player.Paused {
|
||||
isPaused = true
|
||||
}
|
||||
mpv.ForceRestartPlayback(isPaused)
|
||||
}
|
||||
}
|
||||
if c.OnDone != nil {
|
||||
|
||||
@@ -349,9 +349,10 @@ func (p *Player) Continue() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Player) ForceRestartPlayback() error {
|
||||
func (p *Player) ForceRestartPlayback(isPaused bool) error {
|
||||
p.mpv.SetProperty("pause", mpv.FORMAT_FLAG, true)
|
||||
return p.mpv.SetProperty("pause", mpv.FORMAT_FLAG, false)
|
||||
p.mpv.SetProperty("pause", mpv.FORMAT_FLAG, false)
|
||||
return p.mpv.SetProperty("pause", mpv.FORMAT_FLAG, isPaused)
|
||||
}
|
||||
|
||||
// Get the current status of the player.
|
||||
|
||||
@@ -229,6 +229,7 @@
|
||||
"Unset favorite": "Von Favoriten entfernen",
|
||||
"Remove from queue": "Aus Wiedergabeliste entfernen",
|
||||
"Play song radio": "Liedradio abspielen",
|
||||
"Pause after current track": "Nach dem aktuellen Lied pausieren",
|
||||
"to": "bis",
|
||||
"by": "von",
|
||||
"Jan": "Jan",
|
||||
|
||||
@@ -228,7 +228,7 @@
|
||||
"Soundtrack": "Soundtrack",
|
||||
"Spoken Word": "Spoken Word",
|
||||
"Startup page": "Startup page",
|
||||
"Stop after current track": "Stop after current track",
|
||||
"Pause after current track": "Pause after current track",
|
||||
"Stopped": "Stopped",
|
||||
"Success": "Success",
|
||||
"Successfully created playlist": "Successfully created playlist",
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
"Soundtrack": "Bande originale",
|
||||
"Spoken Word": "Spoken Word",
|
||||
"Startup page": "Page de démarrage",
|
||||
"Stop after current track": "Arrêter après la piste en cours",
|
||||
"Pause after current track": "Arrêter après la piste en cours",
|
||||
"Stopped": "Arrêté",
|
||||
"Success": "Succès",
|
||||
"Support the project": "Soutenir le projet",
|
||||
@@ -283,7 +283,6 @@
|
||||
"Oct": "Oct",
|
||||
"Nov": "Nov",
|
||||
"Dec": "Déc",
|
||||
|
||||
"playlist.addedtracks": {
|
||||
"one": "Une piste ajoutée à la liste de lecture",
|
||||
"other": "{{.trackCount}} pistes ajoutées à la liste de lecture"
|
||||
|
||||
@@ -59,7 +59,7 @@ type Controller struct {
|
||||
|
||||
popUpQueue *widget.PopUp
|
||||
popUpQueueList *widgets.PlayQueueList
|
||||
stopAfterCurrent *widget.Check
|
||||
pauseAfterCurrent *widget.Check
|
||||
popUpQueueLastUsed int64
|
||||
escapablePopUp fyne.CanvasObject
|
||||
haveModal bool
|
||||
@@ -198,10 +198,10 @@ func (m *Controller) ShowPopUpPlayQueue() {
|
||||
title := widget.NewRichTextWithText(lang.L("Play Queue"))
|
||||
title.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignCenter
|
||||
title.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = true
|
||||
m.stopAfterCurrent = widget.NewCheck(lang.L("Stop after current track"), func(b bool) {
|
||||
m.App.PlaybackManager.SetStopAfterCurrent(b)
|
||||
m.pauseAfterCurrent = widget.NewCheck(lang.L("Pause after current track"), func(b bool) {
|
||||
m.App.PlaybackManager.SetPauseAfterCurrent(b)
|
||||
})
|
||||
bottomRow := container.NewHBox(layout.NewSpacer(), m.stopAfterCurrent)
|
||||
bottomRow := container.NewHBox(layout.NewSpacer(), m.pauseAfterCurrent)
|
||||
ctr := container.NewBorder(title, bottomRow, nil, nil,
|
||||
container.NewPadded(m.popUpQueueList),
|
||||
)
|
||||
@@ -231,7 +231,7 @@ func (m *Controller) ShowPopUpPlayQueue() {
|
||||
fynetooltip.DestroyPopUpToolTipLayer(m.popUpQueue)
|
||||
m.popUpQueue = nil
|
||||
m.popUpQueueList = nil
|
||||
m.stopAfterCurrent = nil
|
||||
m.pauseAfterCurrent = nil
|
||||
m.popUpQueueLastUsed = 0
|
||||
t.Stop()
|
||||
return
|
||||
@@ -260,7 +260,7 @@ func (m *Controller) ShowPopUpPlayQueue() {
|
||||
))
|
||||
pop.Resize(size)
|
||||
popUpQueueList.ScrollToNowPlaying() // must come after resize
|
||||
m.stopAfterCurrent.SetChecked(m.App.PlaybackManager.IsStopAfterCurrent())
|
||||
m.pauseAfterCurrent.SetChecked(m.App.PlaybackManager.IsPauseAfterCurrent())
|
||||
pop.ShowAtPosition(fyne.NewPos(
|
||||
canvasSize.Width-size.Width-10,
|
||||
canvasSize.Height-size.Height-100,
|
||||
|
||||
Reference in New Issue
Block a user