?say=XYZ to TTS
This commit is contained in:
64
src/device/input/parse/v01/tts.go
Normal file
64
src/device/input/parse/v01/tts.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package v01
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/faiface/beep"
|
||||
"github.com/faiface/beep/effects"
|
||||
"github.com/faiface/beep/speaker"
|
||||
"github.com/faiface/beep/wav"
|
||||
)
|
||||
|
||||
func (v01 *V01) tts(text string) {
|
||||
if err := v01._tts(text); err != nil {
|
||||
log.Printf("failed to tts: %s: %v", text, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (v01 *V01) _tts(text string) error {
|
||||
if v01.cfg.Feedback.TTSURL == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
url, err := url.Parse(v01.cfg.Feedback.TTSURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(url.Path) < 2 {
|
||||
url.Path = "/api/tts"
|
||||
}
|
||||
q := url.Query()
|
||||
if q.Get("voice") == "" {
|
||||
q.Set("voice", "en-us/glados-glow_tts")
|
||||
}
|
||||
if q.Get("lengthScale") == "" {
|
||||
q.Set("lengthScale", "1")
|
||||
}
|
||||
q.Set("text", text)
|
||||
url.RawQuery = q.Encode()
|
||||
|
||||
resp, err := http.Get(url.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
b, _ := io.ReadAll(resp.Body)
|
||||
if resp.StatusCode != http.StatusOK || resp.Header.Get("Content-Type") != "audio/wav" {
|
||||
return fmt.Errorf("failed to call ttsurl: (%d) %s", resp.StatusCode, b)
|
||||
}
|
||||
|
||||
decoder, format, err := wav.Decode(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/30))
|
||||
speaker.Play(&effects.Volume{Streamer: beep.ResampleRatio(4, 1, &beep.Ctrl{Streamer: beep.Loop(1, decoder)})})
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user