diff --git a/README.MD b/README.MD index bb1bf15..1dae3fa 100644 --- a/README.MD +++ b/README.MD @@ -28,7 +28,4 @@ Drop your sounds into the /sounds. You can play them by sending a GET request to 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 \ No newline at end of file +**Note**: The sounds must be in the format `*.mp3`, `*.wav`, `*.flac` or `*.ogg` (`flac` files may take longer time to buffer). diff --git a/go.mod b/go.mod index 6324c70..332238a 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,14 @@ go 1.18 require ( github.com/faiface/beep v1.1.0 // indirect + github.com/h2non/filetype v1.1.3 // indirect github.com/hajimehoshi/go-mp3 v0.3.3 // indirect github.com/hajimehoshi/oto v1.0.1 // indirect + github.com/icza/bitio v1.0.0 // indirect + github.com/jfreymuth/oggvorbis v1.0.1 // indirect + github.com/jfreymuth/vorbis v1.0.0 // indirect + github.com/mewkiz/flac v1.0.7 // indirect + github.com/mewkiz/pkg v0.0.0-20190919212034-518ade7978e2 // indirect github.com/pkg/errors v0.9.1 // indirect golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 // indirect golang.org/x/exp/shiny v0.0.0-20220428152302-39d4317da171 // indirect diff --git a/go.sum b/go.sum index ea4c406..c449b99 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebK github.com/go-audio/audio v1.0.0/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs= github.com/go-audio/riff v1.0.0/go.mod h1:l3cQwc85y79NQFCRB7TiPoNiaijp6q8Z0Uv38rVG498= github.com/go-audio/wav v1.0.0/go.mod h1:3yoReyQOsiARkvPl3ERCi8JFjihzG6WhjYpZCf5zAWE= +github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= +github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= github.com/hajimehoshi/go-mp3 v0.3.0/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM= github.com/hajimehoshi/go-mp3 v0.3.3 h1:cWnfRdpye2m9ElSoVqneYRcpt/l3ijttgjMeQh+r+FE= github.com/hajimehoshi/go-mp3 v0.3.3/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM= @@ -15,13 +17,18 @@ github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2h github.com/hajimehoshi/oto v0.7.1/go.mod h1:wovJ8WWMfFKvP587mhHgot/MBr4DnNy9m6EepeVGnos= github.com/hajimehoshi/oto v1.0.1 h1:8AMnq0Yr2YmzaiqTg/k1Yzd6IygUGk2we9nmjgbgPn4= github.com/hajimehoshi/oto v1.0.1/go.mod h1:wovJ8WWMfFKvP587mhHgot/MBr4DnNy9m6EepeVGnos= +github.com/icza/bitio v1.0.0 h1:squ/m1SHyFeCA6+6Gyol1AxV9nmPPlJFT8c2vKdj3U8= github.com/icza/bitio v1.0.0/go.mod h1:0jGnlLAx8MKMr9VGnn/4YrvZiprkvBelsVIbA9Jjr9A= github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA= +github.com/jfreymuth/oggvorbis v1.0.1 h1:NT0eXBgE2WHzu6RT/6zcb2H10Kxj6Fm3PccT0LE6bqw= github.com/jfreymuth/oggvorbis v1.0.1/go.mod h1:NqS+K+UXKje0FUYUPosyQ+XTVvjmVjps1aEZH1sumIk= +github.com/jfreymuth/vorbis v1.0.0 h1:SmDf783s82lIjGZi8EGUUaS7YxPHgRj4ZXW/h7rUi7U= github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mewkiz/flac v1.0.7 h1:uIXEjnuXqdRaZttmSFM5v5Ukp4U6orrZsnYGGR3yow8= github.com/mewkiz/flac v1.0.7/go.mod h1:yU74UH277dBUpqxPouHSQIar3G1X/QIclVbFahSd1pU= +github.com/mewkiz/pkg v0.0.0-20190919212034-518ade7978e2 h1:EyTNMdePWaoWsRSGQnXiSoQu0r6RS1eA557AwJhlzHU= github.com/mewkiz/pkg v0.0.0-20190919212034-518ade7978e2/go.mod h1:3E2FUC/qYUfM8+r9zAwpeHJzqRVVMIYnpzD/clwWxyA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/handlerFunctions.go b/handlerFunctions.go index 23f72d8..7bdf2d4 100644 --- a/handlerFunctions.go +++ b/handlerFunctions.go @@ -2,13 +2,18 @@ package main import ( "fmt" + "io/ioutil" "log" "os" "time" "github.com/faiface/beep" + "github.com/faiface/beep/flac" "github.com/faiface/beep/mp3" "github.com/faiface/beep/speaker" + "github.com/faiface/beep/vorbis" + "github.com/faiface/beep/wav" + "github.com/h2non/filetype" ) func BufferSound(file string) bool { @@ -21,7 +26,26 @@ func BufferSound(file string) bool { } fmt.Println("Opened file") - streamer, format, _ := mp3.Decode(f) + buf, _ := ioutil.ReadFile("sounds/" + string(file)) + + kind, _ := filetype.Match(buf) + + fmt.Println("File type: " + kind.MIME.Subtype) + var streamer beep.StreamSeekCloser + var format beep.Format + if kind.MIME.Subtype == "mpeg" { + streamer, format, _ = mp3.Decode(f) + } else if kind.MIME.Subtype == "x-wav" { + streamer, format, _ = wav.Decode(f) + } else if kind.MIME.Subtype == "x-flac" { + streamer, format, _ = flac.Decode(f) + } else if kind.MIME.Subtype == "ogg" { + streamer, format, _ = vorbis.Decode(f) + } else { + fmt.Println("!!!!! Unsupported file type for " + file) + return false + } + speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10)) fmt.Println("Decoded file") diff --git a/webRoutes.go b/webRoutes.go index 1efb930..0f71c1e 100644 --- a/webRoutes.go +++ b/webRoutes.go @@ -12,6 +12,7 @@ import ( "strconv" "github.com/faiface/beep/speaker" + "github.com/h2non/filetype" ) func handlePlay(w http.ResponseWriter, r *http.Request) { @@ -40,6 +41,19 @@ func handlePlay(w http.ResponseWriter, r *http.Request) { return } + buf, _ := ioutil.ReadFile("sounds/" + string(bytArr[:])) + + kind, _ := filetype.Match(buf) + if kind == filetype.Unknown { + fmt.Println("Unknown file type") + fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"file has unknown type\"}") + return + } + if kind.MIME.Type != "audio" { + fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"file is not an audio file\"}") + 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 @@ -65,6 +79,18 @@ func handleBufferAll(w http.ResponseWriter, r *http.Request) { // 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 { + buf, _ := ioutil.ReadFile("sounds/" + string(f.Name())) + + kind, _ := filetype.Match(buf) + if kind == filetype.Unknown { + fmt.Println("Unknown file type") + + continue + } + if kind.MIME.Type != "audio" { + fmt.Println("Not an audio file") + continue + } temp = append(temp, f.Name()) go BufferSound(f.Name()) } @@ -99,6 +125,19 @@ func handleBuffer(w http.ResponseWriter, r *http.Request) { return } + buf, _ := ioutil.ReadFile("sounds/" + string(bytArr[:])) + + kind, _ := filetype.Match(buf) + if kind == filetype.Unknown { + fmt.Println("Unknown file type") + fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"file has unknown type\"}") + return + } + if kind.MIME.Type != "audio" { + fmt.Fprintf(w, "{\"status\":\"fail\", \"reason\":\"file is not an audio file\"}") + return + } + fmt.Fprintf(w, "{\"status\":\"ok\"}") go BufferSound(string(bytArr[:])) @@ -195,6 +234,20 @@ func handleListing(w http.ResponseWriter, r *http.Request) { soundObj[0] = f.Name() soundObj[1] = base64.StdEncoding.EncodeToString([]byte(f.Name())) soundObj[2] = r.URL.Host + "/v1/play?file=" + soundObj[1] + + buf, _ := ioutil.ReadFile("sounds/" + f.Name()) + + kind, _ := filetype.Match(buf) + fmt.Println(f.Name() + " " + kind.MIME.Type) + if kind == filetype.Unknown { + fmt.Println("Unknown file type") + continue + } + if kind.MIME.Type != "audio" { + fmt.Println("Not an audio file") + continue + } + temp = append(temp, soundObj) } // Convert the array to a JSON object and return it to the user