ipcast.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. package ipcast
  2. import (
  3. "crypto/rand"
  4. "encoding/hex"
  5. "errors"
  6. "fmt"
  7. "github.com/gin-gonic/gin"
  8. "github.com/goccy/go-json"
  9. "github.com/sirupsen/logrus"
  10. "io"
  11. "lcfns/model/common/response"
  12. ipResp "lcfns/model/ipcast/response"
  13. "net/http"
  14. "os"
  15. "strconv"
  16. "time"
  17. )
  18. type IpcastApi struct {
  19. }
  20. func (api *IpcastApi) Play(c *gin.Context) {
  21. url, err := GetIpcastUrl(c, Play)
  22. if err != nil {
  23. response.FailWithMessage(err.Error(), c)
  24. return
  25. }
  26. data, err := c.GetRawData()
  27. if err != nil {
  28. response.FailWithMessage("获取请求参数出错", c)
  29. logrus.Error(err)
  30. return
  31. }
  32. all, err := ipcastService.Common(url, http.MethodPost, data)
  33. if err != nil {
  34. response.Fail(c)
  35. logrus.Error(err)
  36. return
  37. }
  38. var resp ipResp.PingResp
  39. json.Unmarshal(all, &resp)
  40. response.OkWithDetailed(resp.Message, "播放成功!", c)
  41. }
  42. func (api *IpcastApi) Stop(c *gin.Context) {
  43. url, err := GetIpcastUrl(c, Stop)
  44. if err != nil {
  45. response.FailWithMessage(err.Error(), c)
  46. return
  47. }
  48. all, err := ipcastService.Common(url, http.MethodDelete, nil)
  49. if err != nil {
  50. response.Fail(c)
  51. logrus.Error(err)
  52. return
  53. }
  54. var resp ipResp.PingResp
  55. json.Unmarshal(all, &resp)
  56. response.OkWithDetailed(resp.Message, "操作成功!", c)
  57. }
  58. func (api *IpcastApi) Status(c *gin.Context) {
  59. url, err := GetIpcastUrl(c, Status)
  60. if err != nil {
  61. response.FailWithMessage(err.Error(), c)
  62. return
  63. }
  64. all, err := ipcastService.Common(url, http.MethodGet, nil)
  65. if err != nil {
  66. response.Fail(c)
  67. logrus.Error(err)
  68. return
  69. }
  70. var resp ipResp.StatusResp
  71. json.Unmarshal(all, &resp)
  72. response.OkWithData(resp.Data, c)
  73. }
  74. func (api *IpcastApi) Ping(c *gin.Context) {
  75. url, err := GetIpcastUrl(c, Ping)
  76. if err != nil {
  77. response.FailWithMessage(err.Error(), c)
  78. return
  79. }
  80. all, err := ipcastService.Common(url, http.MethodGet, nil)
  81. if err != nil {
  82. response.Fail(c)
  83. logrus.Error(err)
  84. return
  85. }
  86. var resp ipResp.PingResp
  87. json.Unmarshal(all, &resp)
  88. response.OkWithData(resp.Message, c)
  89. }
  90. func (api *IpcastApi) Volume(c *gin.Context) {
  91. url, err := GetIpcastUrl(c, Volume)
  92. if err != nil {
  93. response.FailWithMessage(err.Error(), c)
  94. return
  95. }
  96. data, err := c.GetRawData()
  97. if err != nil {
  98. response.FailWithMessage("获取请求参数出错", c)
  99. logrus.Error(err)
  100. return
  101. }
  102. all, err := ipcastService.Common(url, http.MethodPatch, data)
  103. if err != nil {
  104. response.Fail(c)
  105. logrus.Error(err)
  106. return
  107. }
  108. var resp ipResp.PingResp
  109. json.Unmarshal(all, &resp)
  110. response.OkWithDetailed(resp.Message, "操作成功!", c)
  111. }
  112. func (api *IpcastApi) List(c *gin.Context) {
  113. }
  114. //↓实现语音喊话功能↓
  115. var audio = make(map[string][]byte)
  116. // volume 播放⾳量:取值【1~100】
  117. // duration 循环(重复)播放时⻓(秒)
  118. // times 循环(重复)播放次数(次)
  119. // gap 循环(重复)播放中的间歇时间(秒)
  120. // todo 修改ip端口 106.52.134.22
  121. var ipcastData = `
  122. {
  123. "url": "http://192.168.110.69:8889/ipcast/AudioSource/%s",
  124. "sync": false,
  125. "queue": true,
  126. "volume": 70,
  127. "loop": {
  128. "duration": %s,
  129. "times": 1,
  130. "gap": 2
  131. }
  132. }
  133. `
  134. // PlayAudio 前端传递mp3资源
  135. func (api *IpcastApi) PlayAudio(c *gin.Context) {
  136. fmt.Println("headers:", c.Request.Header)
  137. //生成uuid
  138. uuid := make([]byte, 8)
  139. rand.Read(uuid)
  140. uuidString := hex.EncodeToString(uuid)
  141. defer func() {
  142. go func() {
  143. //数据传输完后清除数据
  144. time.Sleep(10 * time.Second)
  145. delete(audio, uuidString)
  146. }()
  147. }()
  148. //读取mp3数据
  149. mp3, err := c.FormFile("file")
  150. if err != nil {
  151. response.FailWithMessage("获取请求参数出错", c)
  152. logrus.Error(err)
  153. return
  154. }
  155. open, err := mp3.Open()
  156. if err != nil {
  157. logrus.Error("open err ", err)
  158. return
  159. }
  160. readAll, err := io.ReadAll(open)
  161. if err != nil {
  162. logrus.Error("ReadAll err ", err)
  163. return
  164. }
  165. //保存到内存
  166. audio[uuidString] = readAll
  167. os.WriteFile("map.wav", readAll, 0644)
  168. //播放
  169. t := c.PostForm("timeLength")
  170. data := []byte(fmt.Sprintf(ipcastData, uuidString, t))
  171. fmt.Println("data:", string(data))
  172. url, err := GetIpcastUrl(c, Play)
  173. if err != nil {
  174. response.FailWithMessage(err.Error(), c)
  175. return
  176. }
  177. fmt.Println("url:", url)
  178. all, err := ipcastService.Common(url, http.MethodPost, data)
  179. if err != nil {
  180. response.Fail(c)
  181. logrus.Error(err)
  182. return
  183. }
  184. var resp ipResp.PingResp
  185. json.Unmarshal(all, &resp)
  186. if resp.Code == 200 {
  187. response.OkWithDetailed(resp.Message, "播放成功", c)
  188. } else {
  189. response.FailWithDetailed(resp.Message, "播放失败", c)
  190. }
  191. }
  192. // AudioSource 给ip音柱播放的url资源
  193. func (api *IpcastApi) AudioSource(c *gin.Context) {
  194. id := c.Param("id")
  195. fmt.Println("id:", id)
  196. // 设置响应头,指定内容类型为 audio/mpeg
  197. c.Header("Content-Type", "audio/wav")
  198. c.Header("Access-Control-Allow-Origin", "*")
  199. c.Header("Content-Length", strconv.Itoa(len(audio[id])))
  200. // 将内存中的 MP3 数据作为响应返回给浏览器
  201. c.Data(http.StatusOK, "audio/wav", audio[id])
  202. }
  203. //↑实现语音喊话功能↑
  204. const (
  205. Play = iota
  206. Stop
  207. Status
  208. Ping
  209. Volume
  210. )
  211. func GetIpcastUrl(c *gin.Context, expr byte) (string, error) {
  212. baseUrl := IpcastBaseUrl(c)
  213. if baseUrl == "" {
  214. return "", errors.New("获取baseUrl失败")
  215. }
  216. switch expr {
  217. case Stop, Play:
  218. return baseUrl + "/v1/speech", nil
  219. case Status:
  220. return baseUrl + "/v1/play_status", nil
  221. case Ping:
  222. return baseUrl + "/v1/check_alive", nil
  223. case Volume:
  224. return baseUrl + "/v1/volume", nil
  225. default:
  226. return "", errors.New("获取baseUrl失败")
  227. }
  228. }