diff --git a/app/pages/Soundboard/Soundboard.js b/app/pages/Soundboard/Soundboard.js index cba0d61..2e391aa 100644 --- a/app/pages/Soundboard/Soundboard.js +++ b/app/pages/Soundboard/Soundboard.js @@ -13,6 +13,7 @@ export default class Soundboard extends React.Component { this.state = { uploaded: false, percentCompleted: 0, + password: "", } self = this; } @@ -40,16 +41,19 @@ export default class Soundboard extends React.Component { let formData = new FormData(); formData.append("name", file.name); formData.append("file", file); + formData.append("password", this.state.password); axios.put("/upload", formData, this.config) - .then(() => { + .then((response) => { this.setState({ + password: "", percentCompleted: 0, uploaded: true, uploadError: undefined, }); }).catch((err) => { this.setState({ + password: "", percentCompleted: 0, uploaded: false, uploadError: "Upload error.", @@ -57,9 +61,22 @@ export default class Soundboard extends React.Component { }); } + passwordOnChange(event) { + this.setState({ + password: event.target.value, + }); + } + render() { return (
+ + +
{this.state.uploadError}
: ""}
+ ) } } diff --git a/app/pages/Soundboard/Soundboard.scss b/app/pages/Soundboard/Soundboard.scss index a1ebb53..bde49c6 100644 --- a/app/pages/Soundboard/Soundboard.scss +++ b/app/pages/Soundboard/Soundboard.scss @@ -2,11 +2,21 @@ .Soundboard { display: flex; + flex-direction: column; align-items: center; justify-content: center; height: 100%; } +.Soundboard__input { + border-radius: 3px; + border: 1px solid lighten($gray1, 5%); + margin-bottom: 10px; + padding-left: 5px; + padding-right: 5px; + height: 30px; +} + .Dropzone { display: flex; flex-direction: column; diff --git a/config.template.json b/config.template.json index 8785dd6..57f8f05 100644 --- a/config.template.json +++ b/config.template.json @@ -1,4 +1,7 @@ { "Token": "", - "BotPrefix": "#" + "BotPrefix": "#", + "SoundsPath": "./sounds/", + "UploadPassword": "", + "ServerAddr": ":80" } \ No newline at end of file diff --git a/dist/GoBot-linux b/dist/GoBot-linux index 8b1e5bd..880d0bf 100755 Binary files a/dist/GoBot-linux and b/dist/GoBot-linux differ diff --git a/dist/config.template.json b/dist/config.template.json index 60c5103..57f8f05 100644 --- a/dist/config.template.json +++ b/dist/config.template.json @@ -2,5 +2,6 @@ "Token": "", "BotPrefix": "#", "SoundsPath": "./sounds/", - "UploadPassword": "" + "UploadPassword": "", + "ServerAddr": ":80" } \ No newline at end of file diff --git a/index.html.fasthttp.gz b/index.html.fasthttp.gz deleted file mode 100644 index 8ccda5f..0000000 Binary files a/index.html.fasthttp.gz and /dev/null differ diff --git a/makefile b/makefile index 703d0fe..1de6519 100644 --- a/makefile +++ b/makefile @@ -15,7 +15,5 @@ clean: copyfiles: cp config.template.json ./dist/config.template.json - cp -r ./sounds ./dist/ - cp ./dca-rs ./dist/ all: linux mac windows copyfiles diff --git a/server/config/config.go b/server/config/config.go index 66171f5..0a29054 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -11,8 +11,11 @@ import ( var Config configStruct type configStruct struct { - Token string `json:"Token"` - BotPrefix string `json:"BotPrefix"` //prefix to use for bot commands + Token string `json:"Token"` + BotPrefix string `json:"BotPrefix"` //prefix to use for bot commands + SoundsPath string `json:"SoundsPath"` + UploadPassword string `json:"UploadPassword"` + ServerAddr string `json:"ServerAddr` } func Init() { diff --git a/server/handlers/sounds.go b/server/handlers/sounds.go index d0d9632..5c3d1ae 100644 --- a/server/handlers/sounds.go +++ b/server/handlers/sounds.go @@ -2,20 +2,29 @@ package handlers import ( "../config" + "bufio" "encoding/binary" "errors" "fmt" "github.com/bwmarrin/discordgo" "io" "io/ioutil" - "os" + "layeh.com/gopus" + "os/exec" + "strconv" "strings" "time" ) -var ( - sounds = make(map[string]*AudioClip, 0) +const ( + channels int = 2 // 1 for mono, 2 for stereo + frameRate int = 48000 // audio sampling rate + frameSize int = 960 // uint16 size of each audio frame + maxBytes int = (frameSize * 2) * 2 // max size of opus data +) +var ( + sounds = make(map[string]*AudioClip, 0) soundPlayingLock = false ) @@ -31,7 +40,7 @@ func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) { // exit function call if sound is playing if soundPlayingLock { - fmt.Println("Exiting function call") + fmt.Println("Function in progress, exiting function call...") return } @@ -82,10 +91,9 @@ func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) { // load dca file into memory func loadFile(fileName string) error { - fmt.Println("Loading file: " + fileName + ".dca") // scan directory for file - files, _ := ioutil.ReadDir("./sounds") + files, _ := ioutil.ReadDir(config.Config.SoundsPath) var fextension string var fname string for _, f := range files { @@ -103,12 +111,30 @@ func loadFile(fileName string) error { return errors.New("File not found") } - // open file and load into memory - file, err := os.Open(SOUNDS_DIR + fileName + ".dca") + fmt.Println("Loading file: " + fname + fextension) + + // use ffmpeg to convert file into a format we can use + cmd := exec.Command("ffmpeg", "-i", config.Config.SoundsPath+fname+fextension, "-f", "s16le", "-ar", strconv.Itoa(frameRate), "-ac", strconv.Itoa(channels), "pipe:1") + + ffmpegout, err := cmd.StdoutPipe() if err != nil { - fmt.Println("Error opening dca file :", err) - return err + return errors.New("Stdout error.") + } + + ffmpegbuf := bufio.NewReaderSize(ffmpegout, 16348) + + err = cmd.Start() + + if err != nil { + return errors.New("CMD Start error.") + } + + // crate encoder to convert audio to opus codec + opusEncoder, err := gopus.NewEncoder(frameRate, channels, gopus.Audio) + + if err != nil { + return errors.New("NewEncoder error.") } sounds[fileName] = &AudioClip{ @@ -117,35 +143,28 @@ func loadFile(fileName string) error { Extension: fextension, } - var opuslen int16 - for { - // Read opus frame length from dca file. - err = binary.Read(file, binary.LittleEndian, &opuslen) - - // If this is the end of the file, just return. + // read data from ffmpeg stdout + audiobuf := make([]int16, frameSize*channels) + err = binary.Read(ffmpegbuf, binary.LittleEndian, &audiobuf) + if err == io.EOF || err == io.ErrUnexpectedEOF { + return nil + } if err != nil { - file.Close() - if err == io.EOF { - return nil - } else if err == io.ErrUnexpectedEOF { - return err - } + return errors.New("Error reading from ffmpeg stdout.") } - // Read encoded pcm from dca file. - InBuf := make([]byte, opuslen) - err = binary.Read(file, binary.LittleEndian, &InBuf) - - // Should not be any end of file errors + // convert audio to opus codec + opus, err := opusEncoder.Encode(audiobuf, frameSize, maxBytes) if err != nil { - fmt.Println("Error reading from dca file :", err) - return err + return errors.New("Encoding error.") } - sounds[fileName].Content = append(sounds[fileName].Content, InBuf) + // append sound bytes to the content for this audio file + sounds[fileName].Content = append(sounds[fileName].Content, opus) } + return nil } // playSound plays the current buffer to the provided channel. @@ -165,7 +184,7 @@ func playSound(s *discordgo.Session, guildID, channelID string, sound string) (e } // Sleep for a specified amount of time before playing the sound - time.Sleep(250 * time.Millisecond) + time.Sleep(100 * time.Millisecond) // Start speaking. _ = vc.Speaking(true) diff --git a/server/webserver/server.go b/server/webserver/server.go index 733ed6b..e8cec88 100644 --- a/server/webserver/server.go +++ b/server/webserver/server.go @@ -1,15 +1,12 @@ package webserver import ( - "fmt" + "../config" "github.com/buaazp/fasthttprouter" "github.com/valyala/fasthttp" "io" "log" "os" - "os/exec" - "strings" - "sync" ) func logger(next fasthttp.RequestHandler) fasthttp.RequestHandler { @@ -22,7 +19,6 @@ func logger(next fasthttp.RequestHandler) fasthttp.RequestHandler { func applyMiddleware(handler fasthttp.RequestHandler) fasthttp.RequestHandler { newHandler := logger(handler) - //newHandler = fasthttp.CompressHandler(newHandler) return newHandler } @@ -47,128 +43,54 @@ func Start() { handlers := applyMiddleware(router.Handler) // start web server - log.Fatal(fasthttp.ListenAndServe("0.0.0.0:8080", handlers)) + log.Fatal(fasthttp.ListenAndServe(config.Config.ServerAddr, handlers)) } func fileUpload(ctx *fasthttp.RequestCtx) { + password := ctx.FormValue("password") + + if string(password) != config.Config.UploadPassword { + ctx.Error("Invalid password.", 400) + return + } file, err := ctx.FormFile("file") if err != nil { - ctx.SetStatusCode(500) - fmt.Fprint(ctx, "Error reading file.") + ctx.Error("Error reading file.", 400) return } src, err := file.Open() if err != nil { - ctx.SetStatusCode(500) - fmt.Fprint(ctx, "Error opening file.") + ctx.Error("Error opening file.", 400) return } defer src.Close() // create uploads folder if it does not exist - if _, err := os.Stat("./uploads"); os.IsNotExist(err) { - os.Mkdir("./uploads", os.ModePerm) + if _, err := os.Stat(config.Config.SoundsPath); os.IsNotExist(err) { + os.Mkdir(config.Config.SoundsPath, os.ModePerm) } // check if file already exists - if _, err := os.Stat("./uploads/" + file.Filename); err == nil { - ctx.SetStatusCode(403) - fmt.Fprint(ctx, "File already exists.") + if _, err := os.Stat(config.Config.SoundsPath + file.Filename); err == nil { + ctx.Error("File already exists.", 400) return } - dst, err := os.Create("./uploads/" + file.Filename) + dst, err := os.Create(config.Config.SoundsPath + file.Filename) if err != nil { - ctx.SetStatusCode(500) - fmt.Fprint(ctx, "Error writing file.") + ctx.Error("Error creating file.", 400) return } defer dst.Close() if _, err = io.Copy(dst, src); err != nil { - ctx.SetStatusCode(500) - fmt.Fprint(ctx, "Error writing file.") + ctx.Error("Error writing file.", 400) return } - err = convertFile(file.Filename) - if err != nil { - ctx.SetStatusCode(500) - fmt.Fprint(ctx, err.Error()) - return - } - - fmt.Fprint(ctx, "Success") -} - -func convertFile(fileName string) error { - trimmedName := strings.Split(fileName, ".")[0] - outputPath := "./sounds/" - inputPath := "./uploads/" - - fmt.Println(inputPath + fileName) - fmt.Println(outputPath + trimmedName + ".dca") - - command := "./dca-rs " + "--raw " + "--i " + inputPath + fileName + " > " + outputPath + trimmedName + ".dca" - - wg := new(sync.WaitGroup) - commands := []string{command} - for _, str := range commands { - wg.Add(1) - go exe_cmd(str, wg) - } - wg.Wait() - - /* - cmd := exec.Command("./dca-rs", "--raw", "--i", inputPath+fileName+" > "+outputPath+trimmedName+".dca") - - _, err := cmd.Output() - - if err != nil { - fmt.Println(err.Error()) - } - - err = cmd.Wait() - if err == nil { - fmt.Println(err.Error()) - } - */ - - /* - outFile, err := os.Create(outputPath + trimmedName + ".dca") - if err != nil { - return err - } - defer outFile.Close() - - stdoutPipe, err := cmd.StdoutPipe() - if err != nil { - return err - } - - writer := bufio.NewWriter(outFile) - defer writer.Flush() - - fmt.Println(stdoutPipe) - go io.Copy(writer, stdoutPipe) - */ - - fmt.Println("working") - return nil -} - -func exe_cmd(cmd string, wg *sync.WaitGroup) { - fmt.Println(cmd) - parts := strings.Fields(cmd) - out, err := exec.Command(parts[0], parts[1]).Output() - if err != nil { - fmt.Println("error occured") - fmt.Printf("%s", err) - } - fmt.Printf("%s", out) - wg.Done() + ctx.Success("application/json", []byte("Success!")) } diff --git a/sounds/50dkp.dca b/sounds/50dkp.dca deleted file mode 100644 index a7e5a73..0000000 Binary files a/sounds/50dkp.dca and /dev/null differ diff --git a/sounds/airhorn.dca b/sounds/airhorn.dca deleted file mode 100644 index 39e7167..0000000 Binary files a/sounds/airhorn.dca and /dev/null differ diff --git a/sounds/arf.dca b/sounds/arf.dca deleted file mode 100644 index 10056d2..0000000 Binary files a/sounds/arf.dca and /dev/null differ diff --git a/sounds/blewit.dca b/sounds/blewit.dca deleted file mode 100644 index eea2c32..0000000 Binary files a/sounds/blewit.dca and /dev/null differ diff --git a/sounds/lata.dca b/sounds/lata.dca deleted file mode 100644 index 6e13ff3..0000000 Binary files a/sounds/lata.dca and /dev/null differ diff --git a/sounds/later.dca b/sounds/later.dca deleted file mode 100644 index 42b5f62..0000000 Binary files a/sounds/later.dca and /dev/null differ diff --git a/sounds/lying.dca b/sounds/lying.dca deleted file mode 100644 index 209c06f..0000000 Binary files a/sounds/lying.dca and /dev/null differ diff --git a/sounds/spaghet.dca b/sounds/spaghet.dca deleted file mode 100644 index eab176f..0000000 Binary files a/sounds/spaghet.dca and /dev/null differ diff --git a/sounds/stop.dca b/sounds/stop.dca deleted file mode 100644 index c985d47..0000000 Binary files a/sounds/stop.dca and /dev/null differ