Cleanup of body response, add host to config, rename entries
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
b1a290e7d0
commit
853211cec8
|
@ -20,6 +20,10 @@ func getQueueEntryFromBody(body []byte) *QueueTrackEntry {
|
|||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
err = json.Unmarshal(body, &entry.Metadata)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var val interface{}
|
||||
var strVal string
|
||||
|
@ -29,26 +33,6 @@ func getQueueEntryFromBody(body []byte) *QueueTrackEntry {
|
|||
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 {
|
||||
return entry
|
||||
|
@ -89,6 +73,7 @@ func main() {
|
|||
return nil
|
||||
}
|
||||
|
||||
defer response.Body.Close()
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
@ -109,10 +94,13 @@ func main() {
|
|||
sendNowRandom := func(nr *QueueTrackEntry) {
|
||||
if config.Queue.NowRandom != "" {
|
||||
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 {
|
||||
log.Print(err)
|
||||
}
|
||||
if response != nil {
|
||||
defer response.Body.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,10 +127,13 @@ func main() {
|
|||
defer wg.Done()
|
||||
for np := range queue.NowPlaying {
|
||||
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 {
|
||||
log.Print(err)
|
||||
}
|
||||
if response != nil {
|
||||
response.Body.Close()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -151,7 +142,7 @@ func main() {
|
|||
defer wg.Done()
|
||||
|
||||
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) {
|
||||
writer.Header().Set("Server", "MeteorLight/api")
|
||||
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
@ -162,16 +153,26 @@ func main() {
|
|||
case "listeners":
|
||||
jsonData, _ := json.Marshal(queue.GetListeners())
|
||||
writer.Write(jsonData)
|
||||
|
||||
return
|
||||
case "np":
|
||||
if e := queue.GetNowPlaying(); e != nil {
|
||||
jsonData, _ := json.Marshal(e.original)
|
||||
writer.Write(jsonData)
|
||||
} else {
|
||||
writer.Write([]byte{'{', '}'})
|
||||
}
|
||||
|
||||
return
|
||||
case "random":
|
||||
if nr != nil {
|
||||
jsonData, _ := json.Marshal(nr.original)
|
||||
writer.Write(jsonData)
|
||||
} else {
|
||||
writer.Write([]byte{'{', '}'})
|
||||
}
|
||||
|
||||
return
|
||||
case "queue":
|
||||
if len(pathSegments) == 2 {
|
||||
if request.Method != "GET" {
|
||||
|
@ -183,6 +184,8 @@ func main() {
|
|||
}
|
||||
jsonData, _ := json.Marshal(blobs)
|
||||
writer.Write(jsonData)
|
||||
|
||||
return
|
||||
} else {
|
||||
switch pathSegments[2] {
|
||||
case "head":
|
||||
|
@ -255,6 +258,7 @@ func main() {
|
|||
|
||||
jsonData, _ := json.Marshal(result)
|
||||
writer.Write(jsonData)
|
||||
return
|
||||
|
||||
default:
|
||||
if request.Method != "POST" {
|
||||
|
@ -268,6 +272,7 @@ func main() {
|
|||
|
||||
jsonData, _ := json.Marshal(result)
|
||||
writer.Write(jsonData)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,11 +288,12 @@ func main() {
|
|||
|
||||
jsonData, _ := json.Marshal(result)
|
||||
writer.Write(jsonData)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
writer.Write([]byte{'{', '}'})
|
||||
}
|
||||
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
writer.Write([]byte{'{', '}'})
|
||||
}),
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,13 @@ This project is a Work in Progress.
|
|||
|
||||
# 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))
|
||||
* No Vorbis support.
|
||||
* 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.
|
||||
* Normalized channels / sample rates for mounts.
|
||||
* 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.
|
||||
* Implements `queue.nr` and `/nr` (To be Deprecated/Changed)
|
||||
* Implements `queue.nr` and `/random` (To be Deprecated/Changed)
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
## 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.
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ import "github.com/BurntSushi/toml"
|
|||
|
||||
type Config struct {
|
||||
Api struct {
|
||||
Port int `toml:"port"`
|
||||
Host string `toml:"host"`
|
||||
Port int `toml:"port"`
|
||||
} `toml:"api"`
|
||||
Queue struct {
|
||||
RandomSongApi string `toml:"random_song_api"`
|
||||
|
|
|
@ -2,50 +2,52 @@
|
|||
|
||||
[api]
|
||||
#
|
||||
# The HTTP port the Kawa API listens on. Kawa will listen on localhost.
|
||||
# The HTTP port the MeteorLight API listens on.
|
||||
port=4040
|
||||
# The HTTP bind address API will listen on.
|
||||
host="127.0.0.1"
|
||||
|
||||
[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
|
||||
# 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"
|
||||
# }
|
||||
#
|
||||
# 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"
|
||||
#
|
||||
# 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.
|
||||
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.
|
||||
nr="http://localhost:8012/api/nr"
|
||||
#
|
||||
# When no tracks are available for whatever reason (such as external service
|
||||
# outages), this track will be played.
|
||||
fallback="/tmp/in.flac"
|
||||
# Length of buffer to maintain in KiB
|
||||
# Length of buffer to maintain in KiB (not implemented)
|
||||
buffer_len=4096
|
||||
|
||||
[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
|
||||
# Name of the stream.
|
||||
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:
|
||||
#
|
||||
# mount: the HTTP address to serve the stream from
|
||||
# container: the container format to use (ogg, flac, aac, or mp3)
|
||||
# codec: the audio codec to use (opus, vorbis, flac, aac, do not specify for mp3 streams)
|
||||
# container: the container format to use (ogg, flac, aac, or mp3). See Kirika's supported format list.
|
||||
# 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 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
|
||||
|
|
2
go.mod
2
go.mod
|
@ -3,7 +3,7 @@ module git.gammaspectra.live/S.O.N.G/MeteorLight
|
|||
go 1.18
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
|
|
4
go.sum
4
go.sum
|
@ -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-20220302151314-7b6b11dd6c5c/go.mod h1:NYC/3wOINygtTYvAqEtMfgWBeJ/9Gfv0NvDxnWmg+yA=
|
||||
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-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/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=
|
||||
|
|
8
queue.go
8
queue.go
|
@ -21,10 +21,10 @@ type QueueTrackEntry struct {
|
|||
QueueIdentifier audio.QueueIdentifier
|
||||
Path string
|
||||
Metadata struct {
|
||||
Title string
|
||||
Album string
|
||||
Artist string
|
||||
Art string
|
||||
Title string `json:"title"`
|
||||
Album string `json:"album"`
|
||||
Artist string `json:"artist"`
|
||||
Art string `json:"art"`
|
||||
}
|
||||
|
||||
original map[string]interface{}
|
||||
|
|
Loading…
Reference in a new issue