- add documentation
- add more info to README.MD - splited into multiple files
This commit is contained in:
parent
d8155d86e0
commit
951f61fbd4
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
*.exe
|
||||
sounds/**
|
||||
sounds/**
|
||||
conf.json
|
||||
|
28
README.MD
28
README.MD
@ -1,2 +1,28 @@
|
||||
![Soundr Logo](/resources/logo.svg "Soundr Logo")
|
||||
|
||||
# Soundr
|
||||
An opensource audio server meant for professional applications
|
||||
Soundr is a simple, open-source, cross-platform audio playing server written in go.
|
||||
It aims to be simple to setup and work in many envoriments. It is also designed to be
|
||||
easy to use and maintain.
|
||||
Soundr is able to play multiple audio files at the same time. It is able to intigrate well as it uses a REST endpoint.
|
||||
Swagger Documentation for that endpoint is available in `apiDocs.yml`.
|
||||
The software it self is written in go and uses the BEEP library. It is made to be shipped as a single executable.
|
||||
Another target was a minimal dependency tree.
|
||||
Initally it was written to be used with [Bitfocus Companion](https://bitfocus.io/companion) in a more professional envoriment. (A client for Companion is currently WiP)
|
||||
|
||||
# Installation
|
||||
Installation is as simple as it gets as it is a single executable.
|
||||
Download one of the releases, drop your sounds into the /sounds folder and run the executable.
|
||||
|
||||
# Configuration
|
||||
TODO, no config yet. Soon ports and other settings will be added.
|
||||
|
||||
# Usage
|
||||
Drop your sounds into the /sounds. You can play them by sending a GET request to the /v1/play endpoint.
|
||||
You need to know the base64 encoded file name of the sound you want to play. You can get started by querying /v1/list. It will return a list of all sounds with their respective base64 encoded file name.
|
||||
Use that base64 as the `file` parameter in the request.
|
||||
|
||||
**Note**: The sounds must be in the format `*.mp3` (more will be supported soon :tm:).
|
||||
|
||||
# ToDo
|
||||
- [ ] Add support for other audio formats
|
144
apiDocs.yml
Normal file
144
apiDocs.yml
Normal file
@ -0,0 +1,144 @@
|
||||
openapi: '3.0.2'
|
||||
info:
|
||||
title: Soundr
|
||||
version: '1.0'
|
||||
servers:
|
||||
- url: http://localhost:8082/v1/
|
||||
paths:
|
||||
/play:
|
||||
get:
|
||||
summary: Plays a sound by it's base64'd name. Will load it to buffer first if not already loaded.
|
||||
parameters:
|
||||
- in: query
|
||||
name: file
|
||||
description: A base64 encoded version of the file name
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: number
|
||||
description: The ID of the playing sound
|
||||
'400':
|
||||
description: Bad Request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
reason:
|
||||
type: string
|
||||
description: The error message, in this case probably "file not found"
|
||||
/buffer:
|
||||
get:
|
||||
summary: Loads a sound into the buffer.
|
||||
parameters:
|
||||
- in: query
|
||||
name: file
|
||||
description: A base64 encoded version of the file name
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
|
||||
'400':
|
||||
description: Bad Request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
reason:
|
||||
type: string
|
||||
description: The error message, in this case probably "file not found"
|
||||
/bufferAll:
|
||||
get:
|
||||
summary: Loads all sounds into the buffer.
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
/stop:
|
||||
get:
|
||||
summary: Stops a given sound by it's ID.
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The ID of the sound to stop
|
||||
schema:
|
||||
type: number
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
'400':
|
||||
description: Bad Request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
reason:
|
||||
type: string
|
||||
description: The error message
|
||||
/stopAll:
|
||||
get:
|
||||
summary: Stops all sounds.
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
/current:
|
||||
get:
|
||||
summary: Gets the current playing sound(s).
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
sounds:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: number
|
||||
description: The ID of the sound
|
||||
name:
|
||||
type: string
|
||||
description: The name of the sound
|
||||
loaded:
|
||||
type: boolean
|
||||
description: Whether the sound is loaded into the buffer
|
||||
/list:
|
||||
get: # TODO REWORK!!!!!
|
||||
summary: Lists all sounds in the buffer.
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
sounds:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: The name of the sound
|
||||
base64:
|
||||
type: string
|
||||
description: The base64 version of the name
|
||||
url:
|
||||
type: string
|
||||
description: The URL to the sound
|
78
handlerFunctions.go
Normal file
78
handlerFunctions.go
Normal file
@ -0,0 +1,78 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/faiface/beep"
|
||||
"github.com/faiface/beep/mp3"
|
||||
"github.com/faiface/beep/speaker"
|
||||
)
|
||||
|
||||
func BufferSound(file string) bool {
|
||||
_, ok := streamMap[file]
|
||||
if !ok {
|
||||
fmt.Println("Not in memory, loading")
|
||||
f, err := os.Open("./sounds/" + file)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("Opened file")
|
||||
streamer, format, _ := mp3.Decode(f)
|
||||
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
|
||||
|
||||
fmt.Println("Decoded file")
|
||||
buffer := beep.NewBuffer(format)
|
||||
buffer.Append(streamer)
|
||||
streamer.Close()
|
||||
fmt.Println("Bufferd file")
|
||||
|
||||
// Save to streamMap
|
||||
streamMap[file] = streamBuf{
|
||||
Streamer: streamer,
|
||||
Format: format,
|
||||
Buffer: buffer,
|
||||
}
|
||||
return (true)
|
||||
} else {
|
||||
return (false)
|
||||
}
|
||||
}
|
||||
|
||||
func PlaySound(file string, index int) int {
|
||||
playbacks[index] = playback{
|
||||
File: file,
|
||||
IsLoaded: false,
|
||||
Streamer: nil,
|
||||
Control: nil,
|
||||
}
|
||||
|
||||
fmt.Println("Playing sound: " + file)
|
||||
var buffer *beep.Buffer
|
||||
BufferSound(file)
|
||||
buffer = streamMap[file].Buffer
|
||||
streamer := streamMap[file].Streamer
|
||||
|
||||
fmt.Println("Trying to play sound")
|
||||
shot := buffer.Streamer(0, buffer.Len())
|
||||
|
||||
done := make(chan bool)
|
||||
ctrl := &beep.Ctrl{Streamer: beep.Seq(shot, beep.Callback(func() {
|
||||
done <- true
|
||||
})), Paused: false}
|
||||
|
||||
playbacks[index] = playback{
|
||||
File: file,
|
||||
IsLoaded: true,
|
||||
Streamer: streamer,
|
||||
Control: ctrl,
|
||||
}
|
||||
speaker.Play(ctrl)
|
||||
<-done
|
||||
fmt.Println("Finished playing sound: " + file)
|
||||
delete(playbacks, index)
|
||||
return 1
|
||||
}
|
181
resources/logo.svg
Normal file
181
resources/logo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 29 KiB |
236
soundr.go
236
soundr.go
@ -1,22 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/faiface/beep"
|
||||
"github.com/faiface/beep/mp3"
|
||||
"github.com/faiface/beep/speaker"
|
||||
)
|
||||
|
||||
type playback struct {
|
||||
@ -38,198 +30,66 @@ type streamBuf struct {
|
||||
Buffer *beep.Buffer
|
||||
}
|
||||
|
||||
type Configuration struct {
|
||||
Port int
|
||||
}
|
||||
|
||||
var playbacks map[int]playback
|
||||
var mapMutex = sync.Mutex{}
|
||||
|
||||
var streamMap map[string]streamBuf
|
||||
|
||||
func BufferSound(file string) bool {
|
||||
_, ok := streamMap[file]
|
||||
if !ok {
|
||||
fmt.Println("Not in memory, loading")
|
||||
f, err := os.Open("./sounds/" + file)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("Opened file")
|
||||
streamer, format, err := mp3.Decode(f)
|
||||
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
|
||||
|
||||
fmt.Println("Decoded file")
|
||||
buffer := beep.NewBuffer(format)
|
||||
buffer.Append(streamer)
|
||||
streamer.Close()
|
||||
fmt.Println("Bufferd file")
|
||||
|
||||
// Save to streamMap
|
||||
streamMap[file] = streamBuf{
|
||||
Streamer: streamer,
|
||||
Format: format,
|
||||
Buffer: buffer,
|
||||
}
|
||||
return (true)
|
||||
} else {
|
||||
return (false)
|
||||
}
|
||||
}
|
||||
|
||||
func PlaySound(file string, index int) int {
|
||||
playbacks[index] = playback{
|
||||
File: file,
|
||||
IsLoaded: false,
|
||||
Streamer: nil,
|
||||
Control: nil,
|
||||
}
|
||||
|
||||
fmt.Println("Playing sound: " + file)
|
||||
var buffer *beep.Buffer
|
||||
BufferSound(file)
|
||||
buffer = streamMap[file].Buffer
|
||||
streamer := streamMap[file].Streamer
|
||||
|
||||
fmt.Println("Trying to play sound")
|
||||
shot := buffer.Streamer(0, buffer.Len())
|
||||
|
||||
done := make(chan bool)
|
||||
ctrl := &beep.Ctrl{Streamer: beep.Seq(shot, beep.Callback(func() {
|
||||
done <- true
|
||||
})), Paused: false}
|
||||
|
||||
playbacks[index] = playback{
|
||||
File: file,
|
||||
IsLoaded: true,
|
||||
Streamer: streamer,
|
||||
Control: ctrl,
|
||||
}
|
||||
speaker.Play(ctrl)
|
||||
<-done
|
||||
fmt.Println("Finished playing sound: " + file)
|
||||
delete(playbacks, index)
|
||||
return 1
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Welcome to Soundr!")
|
||||
|
||||
playbacks = make(map[int]playback)
|
||||
streamMap = make(map[string]streamBuf)
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Query().Get("name")))
|
||||
})
|
||||
// Create /sounds if not exists
|
||||
if _, err := os.Stat("./sounds"); os.IsNotExist(err) {
|
||||
fmt.Println("Created /sounds folder")
|
||||
os.Mkdir("./sounds", 0777)
|
||||
}
|
||||
|
||||
http.HandleFunc("/v1/play", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var cnt = r.URL.Query().Get("file")
|
||||
bytArr, err := base64.StdEncoding.DecodeString(cnt)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
// Handle config
|
||||
fmt.Println("Opening conf.json")
|
||||
file, fOpenError := os.Open("conf.json") // Try to open the file
|
||||
|
||||
if errors.Is(fOpenError, os.ErrNotExist) { // If it does not exist, create it
|
||||
fmt.Println("Creating conf.json")
|
||||
file, fOpenError = os.Create("conf.json")
|
||||
if fOpenError != nil {
|
||||
log.Fatal(fOpenError)
|
||||
}
|
||||
fmt.Println(string(bytArr[:]))
|
||||
t, err := os.Stat("./sounds/" + string(bytArr[:]))
|
||||
t = t
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
var currIndex = len(playbacks)
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\", \"id\":%d}", currIndex)
|
||||
defer file.Close()
|
||||
fmt.Println("Writing to conf.json")
|
||||
// Write the default config to the file
|
||||
json.NewEncoder(file).Encode(Configuration{
|
||||
Port: 8080,
|
||||
})
|
||||
fmt.Println("Wrote to conf.json")
|
||||
}
|
||||
defer file.Close()
|
||||
// Decode the config
|
||||
decoder := json.NewDecoder(file)
|
||||
configuration := Configuration{}
|
||||
err := decoder.Decode(&configuration)
|
||||
|
||||
go PlaySound(string(bytArr[:]), currIndex)
|
||||
if err != nil {
|
||||
fmt.Println("error:", err)
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"file not found\"}")
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
http.HandleFunc("/v1/buffer", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var cnt = r.URL.Query().Get("file")
|
||||
bytArr, err := base64.StdEncoding.DecodeString(cnt)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
t, err := os.Stat("./sounds/" + string(bytArr[:]))
|
||||
t = t
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\"}")
|
||||
go BufferSound(string(bytArr[:]))
|
||||
} else {
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"file not found\"}")
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
http.HandleFunc("/v1/stopAll", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
playbacks = make(map[int]playback)
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\"}")
|
||||
speaker.Clear()
|
||||
//fmt.Fprintf(w, "{\"status\":\"ok\", \"id\":%d}", currIndex)
|
||||
|
||||
})
|
||||
|
||||
http.HandleFunc("/v1/stop", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var cnt, err = strconv.Atoi(r.URL.Query().Get("id"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"invalid id\"}")
|
||||
}
|
||||
|
||||
value, ok := playbacks[cnt]
|
||||
if !ok {
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"audio not playing\"}")
|
||||
} else {
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\", \"id\":%d}", value)
|
||||
value.Control.Paused = true
|
||||
value.Control.Streamer = nil
|
||||
delete(playbacks, cnt)
|
||||
}
|
||||
//fmt.Fprintf(w, "{\"status\":\"ok\", \"id\":%d}", currIndex)
|
||||
|
||||
})
|
||||
|
||||
http.HandleFunc("/v1/current", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var tempResultSet map[int]playbackWebReturn
|
||||
tempResultSet = make(map[int]playbackWebReturn)
|
||||
|
||||
for index, element := range playbacks {
|
||||
tempResultSet[index] = playbackWebReturn{File: element.File, IsLoaded: element.IsLoaded, Id: index}
|
||||
}
|
||||
|
||||
j, err := json.Marshal(tempResultSet)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s", err.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
fmt.Fprintf(w, string(j))
|
||||
})
|
||||
|
||||
http.HandleFunc("/v1/list", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var temp [][3]string
|
||||
files, err := ioutil.ReadDir("./sounds/")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
var soundObj [3]string
|
||||
soundObj[0] = f.Name()
|
||||
soundObj[1] = base64.StdEncoding.EncodeToString([]byte(f.Name()))
|
||||
soundObj[2] = r.URL.Host + "/v1/play?file=" + soundObj[1]
|
||||
temp = append(temp, soundObj)
|
||||
}
|
||||
|
||||
j, err := json.Marshal(temp)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s", err.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
fmt.Fprintf(w, string(j))
|
||||
})
|
||||
log.Fatal(http.ListenAndServe(":8081", nil))
|
||||
// Web server stuff
|
||||
// Play route, takes file as parameter, file is base64 encoded
|
||||
http.HandleFunc("/v1/play", handlePlay)
|
||||
// Buffer route, buffers file
|
||||
http.HandleFunc("/v1/buffer", handleBuffer)
|
||||
http.HandleFunc("/v1/bufferAll", handleBufferAll)
|
||||
http.HandleFunc("/v1/stop", handleStop)
|
||||
http.HandleFunc("/v1/stopAll", handleStopAll)
|
||||
http.HandleFunc("/v1/current", handleCurrent)
|
||||
http.HandleFunc("/v1/list", handleListing)
|
||||
|
||||
fmt.Println("Listening on port " + fmt.Sprint(configuration.Port))
|
||||
log.Fatal(http.ListenAndServe(":"+fmt.Sprint(configuration.Port), nil))
|
||||
}
|
||||
|
208
webRoutes.go
Normal file
208
webRoutes.go
Normal file
@ -0,0 +1,208 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/faiface/beep/speaker"
|
||||
)
|
||||
|
||||
func handlePlay(w http.ResponseWriter, r *http.Request) {
|
||||
// Rejct everything else then GET requests
|
||||
if r.Method != "GET" {
|
||||
http.Error(w, "Method is not supported.", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json") // Set the content type to json
|
||||
var cnt = r.URL.Query().Get("file") // Retrieve the file name from the query string
|
||||
bytArr, err := base64.StdEncoding.DecodeString(cnt) // Decode the base64 string
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
t, err := os.Stat("./sounds/" + string(bytArr[:])) // Check if the file exists
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"file not found\"}")
|
||||
return
|
||||
}
|
||||
|
||||
if t.IsDir() { // Make sure it is not a folder we are trying to play
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"target is folder\"}")
|
||||
return
|
||||
}
|
||||
|
||||
var currIndex = len(playbacks) // Create a new index for the playback
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\", \"id\":%d}", currIndex) // Return a JSON object to the user
|
||||
|
||||
go PlaySound(string(bytArr[:]), currIndex) // Play the sound
|
||||
|
||||
}
|
||||
|
||||
// Handle Buffering
|
||||
|
||||
func handleBufferAll(w http.ResponseWriter, r *http.Request) {
|
||||
// Rejct everything else then GET requests
|
||||
if r.Method != "GET" {
|
||||
http.Error(w, "Method is not supported.", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json") // Set the content type to json
|
||||
|
||||
var temp []string
|
||||
files, err := ioutil.ReadDir("./sounds/") // Read the directory
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Loop through the files and add the file name to the temp array
|
||||
// Also triggers the buffer process for the file
|
||||
for _, f := range files {
|
||||
temp = append(temp, f.Name())
|
||||
go BufferSound(f.Name())
|
||||
}
|
||||
// Return the amount of files buffered
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\", \"amount\":%d}", len(temp))
|
||||
|
||||
}
|
||||
|
||||
func handleBuffer(w http.ResponseWriter, r *http.Request) {
|
||||
// Rejct everything else then GET requests
|
||||
if r.Method != "GET" {
|
||||
http.Error(w, "Method is not supported.", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json") // Set the content type to json
|
||||
var cnt = r.URL.Query().Get("file") // Retrieve the file name from the query string
|
||||
bytArr, err := base64.StdEncoding.DecodeString(cnt) // Decode the base64 string
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
t, err := os.Stat("./sounds/" + string(bytArr[:])) // Check if the file exists
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"file not found\"}")
|
||||
return
|
||||
}
|
||||
|
||||
if t.IsDir() { // Make sure it is not a folder we are trying to play
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"target is folder\"}")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\"}")
|
||||
go BufferSound(string(bytArr[:]))
|
||||
|
||||
}
|
||||
|
||||
// Handeling Stop
|
||||
|
||||
func handleStop(w http.ResponseWriter, r *http.Request) {
|
||||
// Rejct everything else then GET requests
|
||||
if r.Method != "GET" {
|
||||
http.Error(w, "Method is not supported.", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json") // Set the content type to json
|
||||
var cnt, err = strconv.Atoi(r.URL.Query().Get("id")) // Retrieve the id, first convert it to an int
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"invalid id\"}")
|
||||
}
|
||||
|
||||
value, ok := playbacks[cnt] // Get value from playbacks map
|
||||
if !ok {
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"audio not playing\"}")
|
||||
} else {
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\"}")
|
||||
// Stop by pausing first then, set the streamer to nil. Finally delete it from the map
|
||||
value.Control.Paused = true
|
||||
value.Control.Streamer = nil
|
||||
delete(playbacks, cnt)
|
||||
}
|
||||
}
|
||||
|
||||
func handleStopAll(w http.ResponseWriter, r *http.Request) {
|
||||
// Rejct everything else then GET requests
|
||||
if r.Method != "GET" {
|
||||
http.Error(w, "Method is not supported.", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json") // Set the content type to json
|
||||
|
||||
// Pause and stop all playbacks
|
||||
for _, v := range playbacks {
|
||||
v.Control.Paused = true
|
||||
v.Control.Streamer = nil
|
||||
}
|
||||
speaker.Clear() // Clear the speaker and make it shut up
|
||||
|
||||
// Reset the map
|
||||
playbacks = make(map[int]playback)
|
||||
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\"}")
|
||||
}
|
||||
|
||||
func handleCurrent(w http.ResponseWriter, r *http.Request) {
|
||||
// Rejct everything else then GET requests
|
||||
if r.Method != "GET" {
|
||||
http.Error(w, "Method is not supported.", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json") // Set the content type to json
|
||||
|
||||
var tempResultSet map[int]playbackWebReturn = make(map[int]playbackWebReturn) // Create a new map to store the results
|
||||
// Iterate through the playbacks map and add important information to the tempResultSet map
|
||||
for index, element := range playbacks {
|
||||
tempResultSet[index] = playbackWebReturn{File: element.File, IsLoaded: element.IsLoaded, Id: index}
|
||||
}
|
||||
// Convert the map to a JSON object and return it to the user
|
||||
j, err := json.Marshal(tempResultSet)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s", err.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
fmt.Fprintf(w, string(j))
|
||||
}
|
||||
}
|
||||
|
||||
func handleListing(w http.ResponseWriter, r *http.Request) {
|
||||
// Rejct everything else then GET requests
|
||||
if r.Method != "GET" {
|
||||
http.Error(w, "Method is not supported.", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json") // Set the content type to json
|
||||
|
||||
var temp [][3]string
|
||||
files, err := ioutil.ReadDir("./sounds/") // Find all files in the sounds directory
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Add the file data to the temp array
|
||||
for _, f := range files {
|
||||
var soundObj [3]string
|
||||
soundObj[0] = f.Name()
|
||||
soundObj[1] = base64.StdEncoding.EncodeToString([]byte(f.Name()))
|
||||
soundObj[2] = r.URL.Host + "/v1/play?file=" + soundObj[1]
|
||||
temp = append(temp, soundObj)
|
||||
}
|
||||
// Convert the array to a JSON object and return it to the user
|
||||
j, err := json.Marshal(temp)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s", err.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
fmt.Fprintf(w, string(j))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user