From f5bf1efc39e7dba96de8647e60bcdc6f3c9d1353 Mon Sep 17 00:00:00 2001 From: trymtv Date: Wed, 2 Feb 2022 16:42:17 +0100 Subject: [PATCH 1/6] Change to handle request body as audio content --- go.mod | 5 +++++ go.sum | 2 ++ main.go | 26 +++++++++++--------------- 3 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2a6d14d --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module ttsaas.com + +go 1.17 + +require github.com/hegedustibor/htgo-tts v0.0.0-20211106065519-4b33b08f698f diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..03fd796 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/hegedustibor/htgo-tts v0.0.0-20211106065519-4b33b08f698f h1:9hj9NB/nSMz1AF/uw1J51gNmbfInP8oQ446C/50o1gE= +github.com/hegedustibor/htgo-tts v0.0.0-20211106065519-4b33b08f698f/go.mod h1:Uqnv3qFrs2WtaeO2/+PQ35x4HdD4u2ZAX/PcQEEP5VY= diff --git a/main.go b/main.go index ad4d6d2..efb5e13 100644 --- a/main.go +++ b/main.go @@ -2,8 +2,7 @@ package main import ( "fmt" - "github.com/hegedustibor/htgo-tts" - "github.com/kennygrant/sanitize" + "io" "log" "net/http" "os" @@ -11,9 +10,12 @@ import ( "strconv" "strings" "time" + + htgotts "github.com/hegedustibor/htgo-tts" ) const audioFolder = "audio" +const fileName = "speech" const defaultPort = 1337 const volume = 2 @@ -35,31 +37,25 @@ func main() { func serveSpeech(w http.ResponseWriter, r *http.Request) { addCORSHeader(w) - + b, _ := io.ReadAll(r.Body) urlParts := strings.Split(strings.TrimPrefix(r.URL.Path, "/"), "/") if len(urlParts) < 1 { http.Error(w, "bad request", http.StatusBadRequest) log.Println("Bad request") return } - sentence := sanitize.BaseName(urlParts[0]) + sentence := string(b) - // Save audio file to audio folder speech := htgotts.Speech{Folder: audioFolder, Language: "no"} - err := speech.Speak(sentence) - if err != nil { - http.Error(w, "server error", http.StatusInternalServerError) - log.Printf("Error converting text to speech: %s\n", err) - return - } + speechFile, _ := speech.CreateSpeechFile(sentence,fileName) - fileURI := audioFolder + "/" + sentence + ".mp3" - loudFileURI := audioFolder + "/" + sentence + "LOUD" + ".mp3" + fileURI := speechFile + loudFileURI := audioFolder + "/" + fileName + "LOUD" + ".mp3" cmdString := fmt.Sprintf("ffmpeg -y -i %s -filter:a \"volume=%d\" %s", fileURI, volume, loudFileURI) - cmd := exec.Command("bash", "-c", cmdString) buf, err := cmd.Output() - if err != nil { + e := os.Remove(speechFile) + if (err != nil || e != nil) { http.Error(w, "server error", http.StatusInternalServerError) log.Printf("Error increasing audio volume: %s: %s\n", err, string(buf)) log.Printf(cmdString) From 9f82d032eb7dc489a7ec5e451d78fe7a91d9884e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Tj=C3=B8tta?= Date: Sat, 12 Feb 2022 22:47:52 +0100 Subject: [PATCH 2/6] Added Dockerfile and docker documentation --- Dockerfile | 31 +++++++++++++++++++++++++++++++ README.md | 11 +++++++++++ 2 files changed, 42 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..089c7a6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +FROM golang:1.17.2-alpine AS builder + +# Set the Current Working Directory inside the container +WORKDIR /app + +# Copy go mod and sum files +COPY go.mod go.sum ./ + +RUN go mod download + +# Copy the source from the current directory to the Working Directory inside the container +COPY . . + +RUN go build -o ttsaas + +FROM alpine:3.12 + +RUN apk update \ + && apk add bash \ + && apk add ffmpeg \ + && apk add mplayer \ + && rm -rf /var/chache/apk/* \ + && addgroup -S app && adduser -S app -G app + +USER app + +WORKDIR /app + +COPY --from=builder /app/ttsaas . + +ENTRYPOINT ["./ttsaas"] diff --git a/README.md b/README.md index 18086e0..5da9647 100644 --- a/README.md +++ b/README.md @@ -38,3 +38,14 @@ The api can be used as a source for audio tags. For example: ``` + +## Docker + +### Build +To build the docker image, run `docker build -t vektor/ttsaas:1.1 .` + +### Run +To run the docker image, run `docker run -p 1337:1337 vektor/ttsaas:1.1` + +(This will map to port 1337, change portnumber (`1337:`) to map to another port) + From bcc4e094110a77f48a25a69d80c3fec470bb6bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Tj=C3=B8tta?= Date: Sat, 12 Feb 2022 23:25:03 +0100 Subject: [PATCH 3/6] Exposing port in Dockerfile --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 089c7a6..644b34e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,4 +28,6 @@ WORKDIR /app COPY --from=builder /app/ttsaas . +EXPOSE 1337 + ENTRYPOINT ["./ttsaas"] From 5be69d86e56d905c6453ed588b84d30f661d2675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Tj=C3=B8tta?= Date: Sat, 12 Feb 2022 23:28:39 +0100 Subject: [PATCH 4/6] change expose placement --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 644b34e..7b29bfd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,6 +28,5 @@ WORKDIR /app COPY --from=builder /app/ttsaas . -EXPOSE 1337 - ENTRYPOINT ["./ttsaas"] +EXPOSE 1337 From 3e020081cf7a8e3ab73edc299885b50dafe59c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Tj=C3=B8tta?= Date: Sat, 12 Feb 2022 23:55:27 +0100 Subject: [PATCH 5/6] add better logging on error --- Dockerfile | 7 +++- main.go | 110 ++++++++++++++++++++++++++++------------------------- 2 files changed, 64 insertions(+), 53 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7b29bfd..b37b3f3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,9 @@ RUN apk update \ && apk add ffmpeg \ && apk add mplayer \ && rm -rf /var/chache/apk/* \ - && addgroup -S app && adduser -S app -G app + && mkdir -p /app/audio \ + && addgroup -S app && adduser -S app -G app \ + && chown -R app:app /app USER app @@ -28,5 +30,6 @@ WORKDIR /app COPY --from=builder /app/ttsaas . -ENTRYPOINT ["./ttsaas"] EXPOSE 1337 + +ENTRYPOINT ["./ttsaas"] diff --git a/main.go b/main.go index efb5e13..1b17101 100644 --- a/main.go +++ b/main.go @@ -1,17 +1,17 @@ package main import ( - "fmt" - "io" - "log" - "net/http" - "os" - "os/exec" - "strconv" - "strings" - "time" + "fmt" + "io" + "log" + "net/http" + "os" + "os/exec" + "strconv" + "strings" + "time" - htgotts "github.com/hegedustibor/htgo-tts" + htgotts "github.com/hegedustibor/htgo-tts" ) const audioFolder = "audio" @@ -20,55 +20,63 @@ const defaultPort = 1337 const volume = 2 func main() { - http.HandleFunc("/", serveSpeech) - port := defaultPort - if os.Getenv("TTSAAS_PORT") != "" { - var err error - port, err = strconv.Atoi(os.Getenv("TTSAAS_PORT")) - if err != nil { - log.Fatalf("Port environment variable set, but could not convert it to int %s\n", err) - } - } - log.Printf("Starting text to speech as a service on port %d\n", port) - if err := http.ListenAndServe(":"+strconv.Itoa(port), nil); err != nil { - panic(err) - } + http.HandleFunc("/", serveSpeech) + port := defaultPort + if os.Getenv("TTSAAS_PORT") != "" { + var err error + port, err = strconv.Atoi(os.Getenv("TTSAAS_PORT")) + if err != nil { + log.Fatalf("Port environment variable set, but could not convert it to int %s\n", err) + } + } + log.Printf("Starting text to speech as a service on port %d\n", port) + if err := http.ListenAndServe(":"+strconv.Itoa(port), nil); err != nil { + panic(err) + } } func serveSpeech(w http.ResponseWriter, r *http.Request) { - addCORSHeader(w) - b, _ := io.ReadAll(r.Body) - urlParts := strings.Split(strings.TrimPrefix(r.URL.Path, "/"), "/") - if len(urlParts) < 1 { - http.Error(w, "bad request", http.StatusBadRequest) - log.Println("Bad request") - return + addCORSHeader(w) + b, _ := io.ReadAll(r.Body) + urlParts := strings.Split(strings.TrimPrefix(r.URL.Path, "/"), "/") + if len(urlParts) < 1 { + http.Error(w, "bad request", http.StatusBadRequest) + log.Println("Bad request") + return + } + sentence := string(b) + + speech := htgotts.Speech{Folder: audioFolder, Language: "no"} + speechFile, err := speech.CreateSpeechFile(sentence,fileName) + if err != nil { + log.Printf("CreateSpeechFile fail %v", err) } - sentence := string(b) - speech := htgotts.Speech{Folder: audioFolder, Language: "no"} - speechFile, _ := speech.CreateSpeechFile(sentence,fileName) + log.Println(speechFile) + log.Println(sentence) + log.Println(fileName) - fileURI := speechFile - loudFileURI := audioFolder + "/" + fileName + "LOUD" + ".mp3" - cmdString := fmt.Sprintf("ffmpeg -y -i %s -filter:a \"volume=%d\" %s", fileURI, volume, loudFileURI) - cmd := exec.Command("bash", "-c", cmdString) - buf, err := cmd.Output() - e := os.Remove(speechFile) - if (err != nil || e != nil) { - http.Error(w, "server error", http.StatusInternalServerError) - log.Printf("Error increasing audio volume: %s: %s\n", err, string(buf)) - log.Printf(cmdString) - return - } + fileURI := speechFile + loudFileURI := audioFolder + "/" + fileName + "LOUD" + ".mp3" + cmdString := fmt.Sprintf("ffmpeg -y -i %s -filter:a \"volume=%d\" %s", fileURI, volume, loudFileURI) + cmd := exec.Command("bash", "-c", cmdString) + buf, err := cmd.CombinedOutput() + e := os.Remove(speechFile) + if (err != nil || e != nil) { + http.Error(w, "server error", http.StatusInternalServerError) + log.Printf("Error increasing audio volume: %s: %s\n", err, string(buf)) + log.Printf(cmdString) + //log.Printf(string(buf)) + return + } - time.Sleep(500 * time.Millisecond) - http.ServeFile(w, r, loudFileURI) + time.Sleep(500 * time.Millisecond) + http.ServeFile(w, r, loudFileURI) } func addCORSHeader(w http.ResponseWriter) { - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS") - w.Header().Set("Access-Control-Allow-Headers", - "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", + "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") } From 080577a1768de24a593d01311f65e46c7cbbbb2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Tj=C3=B8tta?= Date: Sun, 13 Feb 2022 01:14:57 +0100 Subject: [PATCH 6/6] Added default response if GET request --- main.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index 1b17101..647fb64 100644 --- a/main.go +++ b/main.go @@ -46,16 +46,17 @@ func serveSpeech(w http.ResponseWriter, r *http.Request) { } sentence := string(b) + if len(sentence) == 0 { + fmt.Fprintln(w, "TTSAAS is running...") + return + } + speech := htgotts.Speech{Folder: audioFolder, Language: "no"} speechFile, err := speech.CreateSpeechFile(sentence,fileName) if err != nil { log.Printf("CreateSpeechFile fail %v", err) } - log.Println(speechFile) - log.Println(sentence) - log.Println(fileName) - fileURI := speechFile loudFileURI := audioFolder + "/" + fileName + "LOUD" + ".mp3" cmdString := fmt.Sprintf("ffmpeg -y -i %s -filter:a \"volume=%d\" %s", fileURI, volume, loudFileURI) @@ -66,7 +67,6 @@ func serveSpeech(w http.ResponseWriter, r *http.Request) { http.Error(w, "server error", http.StatusInternalServerError) log.Printf("Error increasing audio volume: %s: %s\n", err, string(buf)) log.Printf(cmdString) - //log.Printf(string(buf)) return }