Add play CLI commands for albums, playlists and tracks

This commit is contained in:
E1int
2025-08-06 00:52:46 +02:00
parent dbea096edf
commit 647984e92e
5 changed files with 89 additions and 4 deletions
+6
View File
@@ -558,6 +558,12 @@ func (a *App) checkFlagsAndSendIPCMsg(cli *ipc.Client) error {
return cli.SeekSeconds(SeekToCLIArg)
case SeekByCLIArg != 0:
return cli.SeekBySeconds(SeekByCLIArg)
case PlayAlbumCLIArg != "":
return cli.PlayAlbum(PlayAlbumCLIArg, FirstTrackCLIArg, *FlagShuffle)
case PlayPlaylistCLIArg != "":
return cli.PlayPlaylist(PlayPlaylistCLIArg, FirstTrackCLIArg, *FlagShuffle)
case PlayTrackCLIArg != "":
return cli.PlayTrack(PlayTrackCLIArg)
default:
return nil
}
+27 -4
View File
@@ -7,10 +7,14 @@ import (
)
var (
VolumeCLIArg int = -1
SeekToCLIArg float64 = -1
SeekByCLIArg float64 = 0
VolumePctCLIArg float64 = 0
VolumeCLIArg int = -1
SeekToCLIArg float64 = -1
SeekByCLIArg float64 = 0
VolumePctCLIArg float64 = 0
PlayAlbumCLIArg string = ""
PlayPlaylistCLIArg string = ""
PlayTrackCLIArg string = ""
FirstTrackCLIArg int = 0
FlagPlay = flag.Bool("play", false, "unpause or begin playback")
FlagPause = flag.Bool("pause", false, "pause playback")
@@ -19,6 +23,7 @@ var (
FlagNext = flag.Bool("next", false, "seek to next 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 or -play-playlist)")
FlagVersion = flag.Bool("version", false, "print app version and exit")
FlagHelp = flag.Bool("help", false, "print command line options and exit")
)
@@ -48,6 +53,24 @@ func init() {
VolumePctCLIArg = v
return err
})
flag.Func("play-album", "start playing the given album (ID)", func(s string) error {
PlayAlbumCLIArg = s
return nil
})
flag.Func("play-playlist", "start playing the given playlist (ID)", func(s string) error {
PlayPlaylistCLIArg = s
return nil
})
flag.Func("play-track", "start playing the given track (ID)", func(s string) error {
PlayTrackCLIArg = s
return nil
})
flag.Func("first-track", "start playing from given track (positive integer, to be used with either -play-album or -play-playlist)", func(s string) error {
v, err := strconv.Atoi(s)
FirstTrackCLIArg = v
return err
})
}
func HaveCommandLineOptions() bool {
+15
View File
@@ -5,6 +5,9 @@ import "fmt"
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>
PlayPausePath = "/transport/playpause"
PausePath = "/transport/pause"
StopPath = "/transport/stop"
@@ -37,3 +40,15 @@ func SeekToSecondsPath(secs float64) string {
func SeekBySecondsPath(secs float64) string {
return fmt.Sprintf("%s?s=%0.2f", SeekByPath, secs)
}
func BuildPlayAlbumPath(id string, firstTrack int, shuffle bool) string {
return fmt.Sprintf("%s?id=%s&t=%d&s=%t", PlayAlbumPath, id, firstTrack, shuffle)
}
func BuildPlayPlaylistPath(id string, firstTrack int, shuffle bool) string {
return fmt.Sprintf("%s?id=%s&t=%d&s=%t", PlayPlaylistPath, id, firstTrack, shuffle)
}
func BuildPlayTrackPath(id string) string {
return fmt.Sprintf("%s?id=%s", PlayTrackPath, id)
}
+12
View File
@@ -44,6 +44,18 @@ func (c *Client) Pause() error {
return c.sendRequest(PausePath)
}
func (c *Client) PlayAlbum(id string, firstTrack int, shuffle bool) error {
return c.sendRequest(BuildPlayAlbumPath(id, firstTrack, shuffle))
}
func (c *Client) PlayPlaylist(id string, firstTrack int, shuffle bool) error {
return c.sendRequest(BuildPlayPlaylistPath(id, firstTrack, shuffle))
}
func (c *Client) PlayTrack(id string) error {
return c.sendRequest(BuildPlayTrackPath(id))
}
func (c *Client) PlayPause() error {
return c.sendRequest(PlayPausePath)
}
+29
View File
@@ -19,6 +19,9 @@ type PlaybackHandler interface {
SeekBySeconds(float64)
Volume() int
SetVolume(int)
PlayAlbum(string, int, bool) error
PlayPlaylist(string, int, bool) error
PlayTrack(string) error
}
type IPCServer interface {
@@ -86,6 +89,13 @@ func (s *serverImpl) createHandler() http.Handler {
vol = vol + int(float64(vol)*(pct/100))
s.pbHandler.SetVolume(vol) // will clamp to range for us
}))
m.HandleFunc(PlayAlbumPath, s.makeTracklistEndpointHandler(s.pbHandler.PlayAlbum))
m.HandleFunc(PlayPlaylistPath, s.makeTracklistEndpointHandler(s.pbHandler.PlayPlaylist))
m.HandleFunc(PlayTrackPath, func(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
s.pbHandler.PlayTrack(id)
s.writeOK(w)
})
return m
}
@@ -108,6 +118,25 @@ func (s *serverImpl) makeFloatEndpointHandler(queryParam string, f func(float64)
}
}
func (s *serverImpl) makeTracklistEndpointHandler(f func(string, int, bool) error) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
id := query.Get("id")
firstTrack, err := strconv.Atoi(query.Get("t"))
if err != nil {
s.writeErr(w, err)
return
}
shuffle, err := strconv.ParseBool(query.Get("s"))
if err != nil {
s.writeErr(w, err)
return
}
f(id, firstTrack, shuffle)
s.writeOK(w)
}
}
func (s *serverImpl) writeOK(w http.ResponseWriter) (int, error) {
var r Response
b, err := json.Marshal(&r)