树莓派语音合成并播放服务,调用百度tts接口并通过mplayer播放。其他服务调用接口即可播放声音。

main.go 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package main
  2. import (
  3. "crypto/md5"
  4. "encoding/hex"
  5. "flag"
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "os"
  10. "os/exec"
  11. "sync"
  12. "time"
  13. "github.com/chenqinghe/baidu-ai-go-sdk/voice"
  14. "github.com/gin-gonic/gin"
  15. "github.com/sirupsen/logrus"
  16. )
  17. var client *voice.VoiceClient
  18. var addr string
  19. const (
  20. apiKey = "tVPKdPqxKwWOM9vsukPzseoH"
  21. apiSecret = "VFusINaQ3YjDUC4GoIB1cENME9g2f4Gn"
  22. )
  23. func init() {
  24. client = voice.NewVoiceClient(apiKey, apiSecret)
  25. flag.StringVar(&addr, "addr", ":8080", "server address")
  26. }
  27. func main() {
  28. flag.Parse()
  29. if addr == "" {
  30. flag.Usage()
  31. os.Exit(1)
  32. }
  33. r := gin.Default()
  34. handler := &handler{
  35. l: &sync.Mutex{},
  36. }
  37. r.GET("/", handler.tts)
  38. if err := r.Run(":8080"); err != nil {
  39. logrus.Fatalln("start server error:", err)
  40. }
  41. }
  42. type handler struct {
  43. l *sync.Mutex // 确保串行,不然会同时播放多个语音
  44. }
  45. func (h *handler) tts(c *gin.Context) {
  46. h.l.Lock()
  47. defer h.l.Unlock()
  48. content := c.Query("q")
  49. logrus.Infoln("tts content:", content)
  50. data, err := client.TextToSpeech(content)
  51. if err != nil {
  52. logrus.Errorln("sdk::TextToSpeech error:", err, "content:", content)
  53. http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
  54. return
  55. }
  56. filename := fmt.Sprintf("/tmp/%s.mp3", randomStr())
  57. err = ioutil.WriteFile(filename, data, os.ModePerm)
  58. if err != nil {
  59. logrus.Errorln("write file error:", err, "path:", filename)
  60. http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
  61. return
  62. }
  63. defer os.Remove(filename)
  64. cmd := exec.Command("mplayer", filename)
  65. if err := cmd.Run(); err != nil {
  66. logrus.Errorln("play error:", err)
  67. http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
  68. return
  69. }
  70. c.Writer.WriteHeader(http.StatusOK)
  71. c.Writer.WriteString("ok")
  72. }
  73. func randomStr() string {
  74. now := time.Now().Format("2006-01-02 15:04:05 9999")
  75. h := md5.New()
  76. h.Write([]byte(now))
  77. r := h.Sum(nil)
  78. return hex.EncodeToString(r)
  79. }