Cleanup of body response, add host to config, rename entries
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
DataHoarder 2022-03-03 10:32:53 +01:00
parent b1a290e7d0
commit 853211cec8
7 changed files with 57 additions and 47 deletions

View file

@ -20,6 +20,10 @@ func getQueueEntryFromBody(body []byte) *QueueTrackEntry {
if err != nil { if err != nil {
return nil return nil
} }
err = json.Unmarshal(body, &entry.Metadata)
if err != nil {
return nil
}
var val interface{} var val interface{}
var strVal string var strVal string
@ -29,26 +33,6 @@ func getQueueEntryFromBody(body []byte) *QueueTrackEntry {
entry.Path = strVal entry.Path = strVal
} }
} }
if val, ok = entry.original["title"]; ok {
if strVal, ok = val.(string); ok {
entry.Metadata.Title = strVal
}
}
if val, ok = entry.original["album"]; ok {
if strVal, ok = val.(string); ok {
entry.Metadata.Album = strVal
}
}
if val, ok = entry.original["artist"]; ok {
if strVal, ok = val.(string); ok {
entry.Metadata.Artist = strVal
}
}
if val, ok = entry.original["art"]; ok {
if strVal, ok = val.(string); ok {
entry.Metadata.Art = strVal
}
}
if len(entry.Path) > 0 { if len(entry.Path) > 0 {
return entry return entry
@ -89,6 +73,7 @@ func main() {
return nil return nil
} }
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body) body, err := ioutil.ReadAll(response.Body)
if err != nil { if err != nil {
return nil return nil
@ -109,10 +94,13 @@ func main() {
sendNowRandom := func(nr *QueueTrackEntry) { sendNowRandom := func(nr *QueueTrackEntry) {
if config.Queue.NowRandom != "" { if config.Queue.NowRandom != "" {
jsonData, _ := json.Marshal(nr.original) jsonData, _ := json.Marshal(nr.original)
_, err := http.DefaultClient.Post(config.Queue.NowRandom, "application/json; charset=utf-8", bytes.NewReader(jsonData)) response, err := http.DefaultClient.Post(config.Queue.NowRandom, "application/json; charset=utf-8", bytes.NewReader(jsonData))
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
if response != nil {
defer response.Body.Close()
}
} }
} }
@ -139,10 +127,13 @@ func main() {
defer wg.Done() defer wg.Done()
for np := range queue.NowPlaying { for np := range queue.NowPlaying {
jsonData, _ := json.Marshal(np.original) jsonData, _ := json.Marshal(np.original)
_, err := http.DefaultClient.Post(config.Queue.NowPlaying, "application/json; charset=utf-8", bytes.NewReader(jsonData)) response, err := http.DefaultClient.Post(config.Queue.NowPlaying, "application/json; charset=utf-8", bytes.NewReader(jsonData))
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
if response != nil {
response.Body.Close()
}
} }
}() }()
@ -151,7 +142,7 @@ func main() {
defer wg.Done() defer wg.Done()
server := http.Server{ server := http.Server{
Addr: fmt.Sprintf(":%d", config.Api.Port), Addr: fmt.Sprintf("%s:%d", config.Api.Host, config.Api.Port),
Handler: http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { Handler: http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.Header().Set("Server", "MeteorLight/api") writer.Header().Set("Server", "MeteorLight/api")
writer.Header().Set("Content-Type", "application/json; charset=utf-8") writer.Header().Set("Content-Type", "application/json; charset=utf-8")
@ -162,16 +153,26 @@ func main() {
case "listeners": case "listeners":
jsonData, _ := json.Marshal(queue.GetListeners()) jsonData, _ := json.Marshal(queue.GetListeners())
writer.Write(jsonData) writer.Write(jsonData)
return
case "np": case "np":
if e := queue.GetNowPlaying(); e != nil { if e := queue.GetNowPlaying(); e != nil {
jsonData, _ := json.Marshal(e.original) jsonData, _ := json.Marshal(e.original)
writer.Write(jsonData) writer.Write(jsonData)
} else {
writer.Write([]byte{'{', '}'})
} }
return
case "random": case "random":
if nr != nil { if nr != nil {
jsonData, _ := json.Marshal(nr.original) jsonData, _ := json.Marshal(nr.original)
writer.Write(jsonData) writer.Write(jsonData)
} else {
writer.Write([]byte{'{', '}'})
} }
return
case "queue": case "queue":
if len(pathSegments) == 2 { if len(pathSegments) == 2 {
if request.Method != "GET" { if request.Method != "GET" {
@ -183,6 +184,8 @@ func main() {
} }
jsonData, _ := json.Marshal(blobs) jsonData, _ := json.Marshal(blobs)
writer.Write(jsonData) writer.Write(jsonData)
return
} else { } else {
switch pathSegments[2] { switch pathSegments[2] {
case "head": case "head":
@ -255,6 +258,7 @@ func main() {
jsonData, _ := json.Marshal(result) jsonData, _ := json.Marshal(result)
writer.Write(jsonData) writer.Write(jsonData)
return
default: default:
if request.Method != "POST" { if request.Method != "POST" {
@ -268,6 +272,7 @@ func main() {
jsonData, _ := json.Marshal(result) jsonData, _ := json.Marshal(result)
writer.Write(jsonData) writer.Write(jsonData)
return
} }
} }
@ -283,11 +288,12 @@ func main() {
jsonData, _ := json.Marshal(result) jsonData, _ := json.Marshal(result)
writer.Write(jsonData) writer.Write(jsonData)
return
} }
} else {
writer.WriteHeader(http.StatusNotFound)
writer.Write([]byte{'{', '}'})
} }
writer.WriteHeader(http.StatusNotFound)
writer.Write([]byte{'{', '}'})
}), }),
} }

View file

@ -8,12 +8,13 @@ This project is a Work in Progress.
# Improvements / differences from Kawa # Improvements / differences from Kawa
* Does not use libav ([see supported formats/codecs on Kirika](https://git.gammaspectra.live/S.O.N.G/Kirika#codecs-supported)) * Does not use libav ([see supported formats/codecs on Kirika](https://git.gammaspectra.live/S.O.N.G/Kirika#codecs-supported))
* No Vorbis support.
* Supports HTTP clients that have more than 16 HTTP request headers. * Supports HTTP clients that have more than 16 HTTP request headers.
* Does not restart stream per-track, instead being a continuous stream without parameter changes. * Does not restart stream per-track, instead being a continuous stream without parameter changes.
* Normalized channels / sample rates for mounts. * Normalized channels / sample rates for mounts.
* Implements ICY metadata * Implements ICY metadata
* Uses sample/timed packet buffers, instead of kawa byte buffers, which cause wild differences between endpoints. Mounts usually align within 0.2s of each other, depending on client. * Uses sample/timed packet buffers, instead of kawa byte buffers, which cause wild differences between endpoints. Mounts usually align within 0.2s of each other, depending on client.
* Implements `queue.nr` and `/nr` (To be Deprecated/Changed) * Implements `queue.nr` and `/random` (To be Deprecated/Changed)
## Dependencies ## Dependencies
@ -25,7 +26,7 @@ Kirika is a collection of audio utilities for decoding/encoding files and stream
Check its native dependencies that must be installed before usage. Check its native dependencies that must be installed before usage.
## Usage ## Usage
Start by copying example_config.toml to the location of your choice and reading through it. Of importance are `queue.fallback`, and `queue.random_song_api`. Start by copying [example_config.toml](example_config.toml) to the location of your choice and reading through it. Of importance are `queue.fallback`, and `queue.random_song_api`.
MeteorLight will search for `config.toml` in its working directory. Alternatively you can pass `-config "/example/path/config.toml"` to specify a different location. MeteorLight will search for `config.toml` in its working directory. Alternatively you can pass `-config "/example/path/config.toml"` to specify a different location.

View file

@ -4,7 +4,8 @@ import "github.com/BurntSushi/toml"
type Config struct { type Config struct {
Api struct { Api struct {
Port int `toml:"port"` Host string `toml:"host"`
Port int `toml:"port"`
} `toml:"api"` } `toml:"api"`
Queue struct { Queue struct {
RandomSongApi string `toml:"random_song_api"` RandomSongApi string `toml:"random_song_api"`

View file

@ -2,50 +2,52 @@
[api] [api]
# #
# The HTTP port the Kawa API listens on. Kawa will listen on localhost. # The HTTP port the MeteorLight API listens on.
port=4040 port=4040
# The HTTP bind address API will listen on.
host="127.0.0.1"
[queue] [queue]
# #
# An HTTP GET is sent to this URL when Kawa's queue is empty and it needs a new # An HTTP GET is sent to this URL when MeteorLight's queue is empty and it needs a new
# random track to play. The expected response is an arbitrary JSON blob that # random track to play. The expected response is an arbitrary JSON blob that
# Kawa stores in its queue. At a minimum, it must include the "path" property: # MeteorLight stores in its queue. At a minimum, it must include the "path" property:
# #
# { # {
# "path": "/path/to/audio/file" # "path": "/path/to/audio/file"
# } # }
# #
# The path is the path to an audio file on the filesystem you want Kawa to play. # The path is the path to an audio file on the filesystem you want MeteorLight to play.
random_song_api="http://localhost:8012/api/random" random_song_api="http://localhost:8012/api/random"
# #
# An HTTP POST is issued to this URL when Kawa starts playing a track. The body # An HTTP POST is issued to this URL when MeteorLight starts playing a track. The body
# will be identical to the JSON blob in the queue. # will be identical to the JSON blob in the queue.
np="http://localhost:8012/api/np" np="http://localhost:8012/api/np"
# #
# An HTTP POST is issued to this URL when Kawa fetches a random track. The body # An HTTP POST is issued to this URL when MeteorLight fetches a random track. The body
# will be identical to the JSON blob in memory. # will be identical to the JSON blob in memory.
nr="http://localhost:8012/api/nr" nr="http://localhost:8012/api/nr"
# #
# When no tracks are available for whatever reason (such as external service # When no tracks are available for whatever reason (such as external service
# outages), this track will be played. # outages), this track will be played.
fallback="/tmp/in.flac" fallback="/tmp/in.flac"
# Length of buffer to maintain in KiB # Length of buffer to maintain in KiB (not implemented)
buffer_len=4096 buffer_len=4096
[radio] [radio]
# #
# The port to stream actual audio on. Kawa will listen on localhost. # The port to stream actual audio on. MeteorLight will listen on localhost.
port=8001 port=8001
# Name of the stream. # Name of the stream.
name="my radio" name="my radio"
# #
# A list of streams to make available at [radio.port]/(mount) follows. The # A list of streams to make available at [radio.port]/*(mount) follows. The
# following properties are available: # following properties are available:
# #
# mount: the HTTP address to serve the stream from # mount: the HTTP address to serve the stream from
# container: the container format to use (ogg, flac, aac, or mp3) # container: the container format to use (ogg, flac, aac, or mp3). See Kirika's supported format list.
# codec: the audio codec to use (opus, vorbis, flac, aac, do not specify for mp3 streams) # codec: the audio codec to use (opus, flac, aac, do not specify for mp3 streams)
# bitrate: the desired bitrate of the stream in Kb/s, if not specified (or 0) an appropriate # bitrate: the desired bitrate of the stream in Kb/s, if not specified (or 0) an appropriate
# bitrate will be automatically selected based on the container/codec # bitrate will be automatically selected based on the container/codec
# MeteorLight extension: bitrate can be a string (for example, v0/v1/v2/v3 on MP3). codec can also be he-aacv2. No vorbis support # MeteorLight extension: bitrate can be a string (for example, v0/v1/v2/v3 on MP3). codec can also be he-aacv2. No vorbis support

2
go.mod
View file

@ -3,7 +3,7 @@ module git.gammaspectra.live/S.O.N.G/MeteorLight
go 1.18 go 1.18
require ( require (
git.gammaspectra.live/S.O.N.G/Kirika v0.0.0-20220302151314-7b6b11dd6c5c git.gammaspectra.live/S.O.N.G/Kirika v0.0.0-20220303091537-9e01c732f300
github.com/BurntSushi/toml v1.0.0 github.com/BurntSushi/toml v1.0.0
) )

4
go.sum
View file

@ -1,5 +1,5 @@
git.gammaspectra.live/S.O.N.G/Kirika v0.0.0-20220302151314-7b6b11dd6c5c h1:8Tcq/ueYofDoeRgovGwekXHhyH0i15vm79W5wK/WwpE= git.gammaspectra.live/S.O.N.G/Kirika v0.0.0-20220303091537-9e01c732f300 h1:tBRw3QkXCkybDhZ5lwqjNDbyB4YfI2pJ8ZXR+pkago0=
git.gammaspectra.live/S.O.N.G/Kirika v0.0.0-20220302151314-7b6b11dd6c5c/go.mod h1:NYC/3wOINygtTYvAqEtMfgWBeJ/9Gfv0NvDxnWmg+yA= git.gammaspectra.live/S.O.N.G/Kirika v0.0.0-20220303091537-9e01c732f300/go.mod h1:NYC/3wOINygtTYvAqEtMfgWBeJ/9Gfv0NvDxnWmg+yA=
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220228131722-e9cb84c52f48 h1:MaKiBfXQl0keyfdCi1PxGOKRTiWhIs8PqCal5GhKDi0= git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220228131722-e9cb84c52f48 h1:MaKiBfXQl0keyfdCi1PxGOKRTiWhIs8PqCal5GhKDi0=
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220228131722-e9cb84c52f48/go.mod h1:pkWt//S9hLVEQaJDPu/cHHPk8vPpo/0+zHy0me4LIP4= git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220228131722-e9cb84c52f48/go.mod h1:pkWt//S9hLVEQaJDPu/cHHPk8vPpo/0+zHy0me4LIP4=
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220227175608-6cc027f24dba h1:JEaxCVgdr3XXAuDCPAx7ttLFZaaHzTEzG+oRnVUtUKU= git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220227175608-6cc027f24dba h1:JEaxCVgdr3XXAuDCPAx7ttLFZaaHzTEzG+oRnVUtUKU=

View file

@ -21,10 +21,10 @@ type QueueTrackEntry struct {
QueueIdentifier audio.QueueIdentifier QueueIdentifier audio.QueueIdentifier
Path string Path string
Metadata struct { Metadata struct {
Title string Title string `json:"title"`
Album string Album string `json:"album"`
Artist string Artist string `json:"artist"`
Art string Art string `json:"art"`
} }
original map[string]interface{} original map[string]interface{}