Can control playlist
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing

This commit is contained in:
nemunaire 2024-01-07 15:01:03 +01:00
commit f7760416b9
7 changed files with 257 additions and 10 deletions

View file

@ -14,6 +14,7 @@ type InputState struct {
Name string `json:"name"`
Active bool `json:"active"`
Controlable bool `json:"controlable"`
HasPlaylist bool `json:"hasplaylist"`
Streams map[string]string `json:"streams,omitempty"`
Mixable bool `json:"mixable"`
Mixer map[string]*inputs.InputMixer `json:"mixer,omitempty"`
@ -32,10 +33,16 @@ func declareInputsRoutes(cfg *config.Config, router *gin.RouterGroup) {
mixer, _ = im.GetMixers()
}
var hasPlaylist bool
if p, withPlaylist := inp.(inputs.PlaylistInput); withPlaylist {
hasPlaylist = p.HasPlaylist()
}
ret[k] = &InputState{
Name: inp.GetName(),
Active: inp.IsActive(),
Controlable: controlable,
HasPlaylist: hasPlaylist,
Streams: inp.CurrentlyPlaying(),
Mixable: mixable,
Mixer: mixer,
@ -57,11 +64,16 @@ func declareInputsRoutes(cfg *config.Config, router *gin.RouterGroup) {
if mixable {
mixer, _ = im.GetMixers()
}
var hasPlaylist bool
if p, withPlaylist := inp.(inputs.PlaylistInput); withPlaylist {
hasPlaylist = p.HasPlaylist()
}
c.JSON(http.StatusOK, &InputState{
Name: inp.GetName(),
Active: inp.IsActive(),
Controlable: controlable,
HasPlaylist: hasPlaylist,
Streams: inp.CurrentlyPlaying(),
Mixable: mixable,
Mixer: mixer,
@ -84,6 +96,7 @@ func declareInputsRoutes(cfg *config.Config, router *gin.RouterGroup) {
streamRoutes := inputsRoutes.Group("/streams/:stream")
streamRoutes.Use(StreamHandler)
// ControlableInput
streamRoutes.POST("/pause", func(c *gin.Context) {
input, ok := c.MustGet("input").(inputs.ControlableInput)
if !ok {
@ -99,6 +112,8 @@ func declareInputsRoutes(cfg *config.Config, router *gin.RouterGroup) {
c.JSON(http.StatusOK, true)
})
// MixableInput
streamRoutes.POST("/volume", func(c *gin.Context) {
input, ok := c.MustGet("input").(inputs.MixableInput)
if !ok {
@ -121,6 +136,47 @@ func declareInputsRoutes(cfg *config.Config, router *gin.RouterGroup) {
c.JSON(http.StatusOK, true)
})
// PlaylistInput
streamRoutes.POST("/has_playlist", func(c *gin.Context) {
input, ok := c.MustGet("input").(inputs.PlaylistInput)
if !ok {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support that"})
return
}
c.JSON(http.StatusOK, input.HasPlaylist())
})
streamRoutes.POST("/next_track", func(c *gin.Context) {
input, ok := c.MustGet("input").(inputs.PlaylistInput)
if !ok {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support that"})
return
}
err := input.NextTrack()
if err != nil {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": err.Error()})
return
}
c.JSON(http.StatusOK, true)
})
streamRoutes.POST("/prev_track", func(c *gin.Context) {
input, ok := c.MustGet("input").(inputs.PlaylistInput)
if !ok {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support that"})
return
}
err := input.PreviousTrack()
if err != nil {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": err.Error()})
return
}
c.JSON(http.StatusOK, true)
})
}
func InputHandler(c *gin.Context) {

View file

@ -17,6 +17,7 @@ type SourceState struct {
Enabled bool `json:"enabled"`
Active *bool `json:"active,omitempty"`
Controlable bool `json:"controlable,omitempty"`
HasPlaylist bool `json:"hasplaylist,omitempty"`
CurrentTitle string `json:"currentTitle,omitempty"`
}
@ -28,6 +29,11 @@ func declareSourcesRoutes(cfg *config.Config, router *gin.RouterGroup) {
active := src.IsActive()
_, controlable := src.(inputs.ControlableInput)
var hasPlaylist bool
if p, withPlaylist := src.(inputs.PlaylistInput); withPlaylist {
hasPlaylist = p.HasPlaylist()
}
var title string
if s, ok := src.(sources.PlayingSource); ok && active {
title = s.CurrentlyPlaying()
@ -38,6 +44,7 @@ func declareSourcesRoutes(cfg *config.Config, router *gin.RouterGroup) {
Enabled: src.IsEnabled(),
Active: &active,
Controlable: controlable,
HasPlaylist: hasPlaylist,
CurrentTitle: title,
}
}
@ -54,6 +61,11 @@ func declareSourcesRoutes(cfg *config.Config, router *gin.RouterGroup) {
active := src.IsActive()
_, controlable := src.(inputs.ControlableInput)
var hasPlaylist bool
if p, withPlaylist := src.(inputs.PlaylistInput); withPlaylist {
hasPlaylist = p.HasPlaylist()
}
var title string
if s, ok := src.(sources.PlayingSource); ok && active {
title = s.CurrentlyPlaying()
@ -64,6 +76,7 @@ func declareSourcesRoutes(cfg *config.Config, router *gin.RouterGroup) {
Enabled: src.IsEnabled(),
Active: &active,
Controlable: controlable,
HasPlaylist: hasPlaylist,
CurrentTitle: title,
})
})
@ -123,6 +136,8 @@ func declareSourcesRoutes(cfg *config.Config, router *gin.RouterGroup) {
c.JSON(http.StatusOK, true)
})
// ControlableInput
sourcesRoutes.POST("/pause", func(c *gin.Context) {
src := c.MustGet("source").(sources.SoundSource)
@ -139,6 +154,68 @@ func declareSourcesRoutes(cfg *config.Config, router *gin.RouterGroup) {
c.JSON(http.StatusOK, s.TogglePause("default"))
})
// PlaylistInput
sourcesRoutes.POST("/has_playlist", func(c *gin.Context) {
src := c.MustGet("source").(sources.SoundSource)
if !src.IsActive() {
c.AbortWithStatusJSON(http.StatusNotAcceptable, gin.H{"errmsg": "Source not active"})
return
}
s, ok := src.(inputs.PlaylistInput)
if !ok {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support"})
return
}
c.JSON(http.StatusOK, s.HasPlaylist())
})
sourcesRoutes.POST("/next_track", func(c *gin.Context) {
src := c.MustGet("source").(sources.SoundSource)
if !src.IsActive() {
c.AbortWithStatusJSON(http.StatusNotAcceptable, gin.H{"errmsg": "Source not active"})
return
}
s, ok := src.(inputs.PlaylistInput)
if !ok || !s.HasPlaylist() {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support"})
return
}
err := s.NextTrack()
if err != nil {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": err.Error()})
return
}
c.JSON(http.StatusOK, true)
})
sourcesRoutes.POST("/prev_track", func(c *gin.Context) {
src := c.MustGet("source").(sources.SoundSource)
if !src.IsActive() {
c.AbortWithStatusJSON(http.StatusNotAcceptable, gin.H{"errmsg": "Source not active"})
return
}
s, ok := src.(inputs.PlaylistInput)
if !ok || !s.HasPlaylist() {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support"})
return
}
err := s.PreviousTrack()
if err != nil {
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": err.Error()})
return
}
c.JSON(http.StatusOK, true)
})
}
func SourceHandler(c *gin.Context) {