xfyun.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package services
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/rdlucklib/rdluck_tools/crypt"
  7. "hongze/hongze_task/models"
  8. "net/url"
  9. "strings"
  10. "time"
  11. "github.com/gorilla/websocket"
  12. "hongze/hongze_task/utils"
  13. )
  14. type XfParams struct {
  15. XfAPPID string
  16. XfAPIKey string
  17. XfAPISecret string
  18. }
  19. // 科大讯飞,语音合成
  20. func GetXfVideo(body []byte, savePath string, req XfParams) (err error) {
  21. path, err := assembleAuthUrl(req)
  22. if err != nil {
  23. return
  24. }
  25. conn, _, err := websocket.DefaultDialer.Dial(path, nil)
  26. if err != nil {
  27. return
  28. }
  29. defer conn.Close()
  30. err = conn.WriteMessage(websocket.TextMessage, body)
  31. if err != nil {
  32. return
  33. }
  34. for {
  35. _, message, err := conn.ReadMessage()
  36. if err != nil {
  37. fmt.Println("ReadMessage Err:" + err.Error())
  38. return err
  39. }
  40. item := new(models.XfReciveResult)
  41. err = json.Unmarshal(message, &item)
  42. if err != nil {
  43. fmt.Println("json.Unmarshal Err:" + err.Error())
  44. return err
  45. }
  46. if item.Code != 0 {
  47. goto readWebSocketFail
  48. }
  49. if item.Code == 0 && item.Data != nil {
  50. if item.Data.Status == 1 {
  51. audio := item.Data.Audio
  52. err = utils.SaveBase64ToFileBySeek(audio, savePath)
  53. if err != nil {
  54. fmt.Println("文件保存失败", err.Error())
  55. goto readWebSocketFail
  56. }
  57. } else {
  58. audio := item.Data.Audio
  59. err = utils.SaveBase64ToFileBySeek(audio, savePath)
  60. if err != nil {
  61. fmt.Println("文件保存失败", err.Error())
  62. goto webSocketClose
  63. //return
  64. }
  65. fmt.Println("goto close")
  66. goto webSocketClose
  67. }
  68. }
  69. }
  70. readWebSocketFail:
  71. conn.Close()
  72. fmt.Println("goto readWebSocketFail")
  73. webSocketClose:
  74. conn.Close()
  75. fmt.Println("goto webSocketClose")
  76. return nil
  77. }
  78. // @hosturl : like wss://iat-api.xfyun.cn/v2/iat
  79. // @apikey : apiKey
  80. // @apiSecret : apiSecret
  81. func assembleAuthUrl(req XfParams) (callUrl string, err error) {
  82. ul, err := url.Parse(utils.XfHostUrl)
  83. if err != nil {
  84. return
  85. }
  86. //签名时间
  87. date := time.Now().UTC().Format(time.RFC1123)
  88. //参与签名的字段 host ,date, request-line
  89. signString := []string{"host: " + ul.Host, "date: " + date, "GET " + ul.Path + " HTTP/1.1"}
  90. //拼接签名字符串
  91. sign := strings.Join(signString, "\n")
  92. fmt.Println("sign:", sign)
  93. //签名结果
  94. sha := crypt.HmacSha256EncryptToBase64([]byte(sign), []byte(req.XfAPISecret))
  95. //构建请求参数 此时不需要urlencoding
  96. authUrl := fmt.Sprintf("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", req.XfAPIKey,
  97. "hmac-sha256", "host date request-line", sha)
  98. //将请求参数使用base64编码
  99. authorization := base64.StdEncoding.EncodeToString([]byte(authUrl))
  100. v := url.Values{}
  101. v.Add("host", ul.Host)
  102. v.Add("date", date)
  103. v.Add("authorization", authorization)
  104. //将编码后的字符串url encode后添加到url后面
  105. callUrl = utils.XfHostUrl + "?" + v.Encode()
  106. return
  107. }