Pārlūkot izejas kodu

前端传mp3使用url播放

longan 1 gadu atpakaļ
vecāks
revīzija
674c96a3a8

+ 114 - 33
api/v1/ipcast/ipcast.go

@@ -1,24 +1,24 @@
 package ipcast
 
 import (
+	"crypto/rand"
+	"encoding/hex"
+	"fmt"
 	"github.com/gin-gonic/gin"
 	"github.com/goccy/go-json"
 	"github.com/sirupsen/logrus"
 	"lcfns/model/common/response"
 	ipResp "lcfns/model/ipcast/response"
 	"net/http"
+	"strconv"
+	"time"
 )
 
 type IpcastApi struct {
 }
 
 func (api *IpcastApi) Play(c *gin.Context) {
-	baseUrl := IpcastBaseUrl(c)
-	if baseUrl == "" {
-		response.FailWithMessage("获取baseUrl失败", c)
-		return
-	}
-	url := baseUrl + "/v1/speech"
+	url := GetIpcastUrl(c, Play)
 	data, err := c.GetRawData()
 	if err != nil {
 		response.FailWithMessage("获取请求参数出错", c)
@@ -33,16 +33,11 @@ func (api *IpcastApi) Play(c *gin.Context) {
 	}
 	var resp ipResp.PingResp
 	json.Unmarshal(all, &resp)
-	response.OkWithData(resp.Message, c)
+	response.OkWithDetailed(resp.Message, "播放成功!", c)
 }
 
 func (api *IpcastApi) Stop(c *gin.Context) {
-	baseUrl := IpcastBaseUrl(c)
-	if baseUrl == "" {
-		response.FailWithMessage("获取baseUrl失败", c)
-		return
-	}
-	url := baseUrl + "/v1/speech"
+	url := GetIpcastUrl(c, Stop)
 	all, err := ipcastService.Common(url, http.MethodDelete, nil)
 	if err != nil {
 		response.Fail(c)
@@ -51,16 +46,11 @@ func (api *IpcastApi) Stop(c *gin.Context) {
 	}
 	var resp ipResp.PingResp
 	json.Unmarshal(all, &resp)
-	response.OkWithData(resp.Message, c)
+	response.OkWithDetailed(resp.Message, "操作成功!", c)
 }
 
 func (api *IpcastApi) Status(c *gin.Context) {
-	baseUrl := IpcastBaseUrl(c)
-	if baseUrl == "" {
-		response.FailWithMessage("获取baseUrl失败", c)
-		return
-	}
-	url := baseUrl + "/v1/play_status"
+	url := GetIpcastUrl(c, Status)
 	all, err := ipcastService.Common(url, http.MethodGet, nil)
 	if err != nil {
 		response.Fail(c)
@@ -73,12 +63,7 @@ func (api *IpcastApi) Status(c *gin.Context) {
 }
 
 func (api *IpcastApi) Ping(c *gin.Context) {
-	baseUrl := IpcastBaseUrl(c)
-	if baseUrl == "" {
-		response.FailWithMessage("获取baseUrl失败", c)
-		return
-	}
-	url := baseUrl + "/v1/check_alive"
+	url := GetIpcastUrl(c, Ping)
 	all, err := ipcastService.Common(url, http.MethodGet, nil)
 	if err != nil {
 		response.Fail(c)
@@ -91,12 +76,7 @@ func (api *IpcastApi) Ping(c *gin.Context) {
 }
 
 func (api *IpcastApi) Volume(c *gin.Context) {
-	baseUrl := IpcastBaseUrl(c)
-	if baseUrl == "" {
-		response.FailWithMessage("获取baseUrl失败", c)
-		return
-	}
-	url := baseUrl + "/v1/volume"
+	url := GetIpcastUrl(c, Volume)
 	data, err := c.GetRawData()
 	if err != nil {
 		response.FailWithMessage("获取请求参数出错", c)
@@ -111,9 +91,110 @@ func (api *IpcastApi) Volume(c *gin.Context) {
 	}
 	var resp ipResp.PingResp
 	json.Unmarshal(all, &resp)
-	response.OkWithData(resp.Message, c)
+	response.OkWithDetailed(resp.Message, "操作成功!", c)
 }
 
 func (api *IpcastApi) List(c *gin.Context) {
 
 }
+
+//↓实现语音喊话功能↓
+
+var audio = make(map[string][]byte)
+
+// volume 播放⾳量:取值【1~100】
+// duration 循环(重复)播放时⻓(秒)
+// times 循环(重复)播放次数(次)
+// gap  循环(重复)播放中的间歇时间(秒)
+// todo 修改ip端口 106.52.134.22
+var ipcastData = `
+{
+    "url": "http://192.168.110.69:8889/ipcast/AudioSource/%s",
+    "sync": false,
+    "queue": true,
+	"volume": 50,
+    "loop": {
+        "duration": 600,
+        "times": 1,
+        "gap": 2
+    }
+}
+`
+
+// PlayAudio 前端传递mp3资源
+func (api *IpcastApi) PlayAudio(c *gin.Context) {
+	//生成uuid
+	uuid := make([]byte, 8)
+	rand.Read(uuid)
+	uuidString := hex.EncodeToString(uuid)
+	defer func() {
+		go func() {
+			//播放完后清除数据
+			time.Sleep(10 * time.Second)
+			delete(audio, uuidString)
+		}()
+	}()
+	//读取mp3数据
+	mp3, err := c.GetRawData()
+	if err != nil {
+		response.FailWithMessage("获取请求参数出错", c)
+		logrus.Error(err)
+		return
+	}
+	//保存到内存
+	audio[uuidString] = mp3
+	//播放
+	data := []byte(fmt.Sprintf(ipcastData, uuidString))
+	all, err := ipcastService.Common(GetIpcastUrl(c, Play), http.MethodPost, data)
+	fmt.Println("data:", string(data))
+	if err != nil {
+		response.Fail(c)
+		logrus.Error(err)
+		return
+	}
+	var resp ipResp.PingResp
+	json.Unmarshal(all, &resp)
+	response.OkWithData(resp.Message, c)
+}
+
+// AudioSource 给ip音柱播放的url资源
+func (api *IpcastApi) AudioSource(c *gin.Context) {
+	id := c.Param("id")
+	fmt.Println("id:", id)
+	// 设置响应头,指定内容类型为 audio/mpeg
+	c.Header("Content-Type", "audio/mp3")
+	c.Header("Access-Control-Allow-Origin", "*")
+	c.Header("Content-Length", strconv.Itoa(len(audio[id])))
+
+	// 将内存中的 MP3 数据作为响应返回给浏览器
+	c.Data(http.StatusOK, "audio/mp3", audio[id])
+}
+
+//↑实现语音喊话功能↑
+
+const (
+	Play = iota
+	Stop
+	Status
+	Ping
+	Volume
+)
+
+func GetIpcastUrl(c *gin.Context, expr byte) string {
+	baseUrl := IpcastBaseUrl(c)
+	if baseUrl == "" {
+		response.FailWithMessage("获取baseUrl失败", c)
+		return ""
+	}
+	switch expr {
+	case Stop, Play:
+		return baseUrl + "/v1/speech"
+	case Status:
+		return baseUrl + "/v1/play_status"
+	case Ping:
+		return baseUrl + "/v1/check_alive"
+	case Volume:
+		return baseUrl + "/v1/volume"
+	}
+	return ""
+}

+ 1 - 10
api/v1/system/sys_jwt_blacklist.go

@@ -3,27 +3,18 @@ package system
 import (
 	"github.com/gin-gonic/gin"
 	"github.com/sirupsen/logrus"
-	"go.uber.org/zap"
 	"lcfns/model/common/response"
 	"lcfns/model/system"
 )
 
 type JwtApi struct{}
 
-// JsonInBlacklist
-// @Tags      Jwt
-// @Summary   jwt加入黑名单
-// @Security  ApiKeyAuth
-// @accept    application/json
-// @Produce   application/json
-// @Success   200  {object}  response.Response{msg=string}  "jwt加入黑名单"
-// @Router    /jwt/jsonInBlacklist [post]
 func (j *JwtApi) JsonInBlacklist(c *gin.Context) {
 	token := c.Request.Header.Get("x-token")
 	jwt := system.JwtBlacklist{Jwt: token}
 	err := jwtService.JsonInBlacklist(jwt)
 	if err != nil {
-		logrus.Error("jwt作废失败!", zap.Error(err))
+		logrus.Error("jwt作废失败!", err)
 		response.FailWithMessage("jwt作废失败", c)
 		return
 	}

+ 5 - 2
eventServer/eventServer.go

@@ -54,9 +54,10 @@ func handler(w http.ResponseWriter, r *http.Request) {
 			return
 		}
 		//处理事件 todo 邮箱
+		fmt.Println("application/xml 事件")
 		handleEvent_(event)
 	} else if strings.Contains(contentType, "multipart/form-data") {
-		//fmt.Println("multipart/form-data 事件")
+		fmt.Println("multipart/form-data 事件")
 		handleMultipart(r)
 	} else {
 		logrus.WithField("Content-Type", contentType).Error("该Content-Type没有写处理逻辑")
@@ -88,12 +89,13 @@ func handleMultipart(r *http.Request) {
 		// 检查 part 的 Content-Disposition
 		formName := part.FormName()
 		//fmt.Println("formName", formName)
-		if formName != "intrusionImage" {
+		if !strings.Contains(formName, "Image") {
 			//不含图片的xml部分数据
 			xmlData, err := ioutil.ReadAll(part)
 			if err != nil {
 				return
 			}
+			//fmt.Printf("xml:%s\n", string(xmlData))
 			xml.Unmarshal(xmlData, &eventAlert)
 			//event.Ip = eventAlert.IpAddress
 			//event.Type = eventAlert.EventType
@@ -128,6 +130,7 @@ func handleMultipart(r *http.Request) {
 			MacAddress: eventAlert.MacAddress,
 			EventType:  eventAlert.EventType,
 		}
+		fmt.Printf("事件信息:%+v\n", eventAlert)
 		//保存图片
 		go eventService.Save(event, picture, pictureData)
 		//邮件通知

+ 1 - 1
initialize/router.go

@@ -56,7 +56,7 @@ func Routers() *gin.Engine {
 	}
 	//ipcast
 	{
-		ipcast.InitInfoRouter(PrivateGroup)
+		ipcast.InitInfoRouter(PrivateGroup, PublicGroup)
 	}
 	//应用层
 	{

+ 6 - 1
isapi/client.go

@@ -41,7 +41,12 @@ func TouChuan(host string, o Operation, data []byte, c *gin.Context) (resp any,
 	resp, err = Com(host, o, data)
 	if err != nil {
 		logrus.Error(err)
-		response.FailWithDetailed(resp.(ResponseStatus), err.Error(), c)
+		if r, ok := resp.(ResponseStatus); ok {
+			response.FailWithDetailed(r, err.Error(), c)
+		} else {
+			//可能是摄像头未初始化成功,返回err!=nil,且resp!=ResponseStatus
+			response.FailWithDetailed("操作失败,请重试", err.Error(), c)
+		}
 		return
 	}
 	//断言成功,说明是配置响应,检查配置结果

+ 8 - 3
router/ipcast/ipcast.go

@@ -8,15 +8,20 @@ import (
 type IpcastRouter struct {
 }
 
-func (c *IpcastRouter) InitInfoRouter(Router *gin.RouterGroup) {
+func (c *IpcastRouter) InitInfoRouter(priRouter, pubRouter *gin.RouterGroup) {
 	var ipApi = v1.ApiGroupApp.IpcastApiGroup.IpcastApi
-	ipGroup := Router.Group("ipcast")
+	ipGroup := priRouter.Group("ipcast")
 	{
 		ipGroup.GET("list", ipApi.List)
 		ipGroup.POST("play", ipApi.Play)
 		ipGroup.DELETE("stop", ipApi.Stop)
 		ipGroup.GET("status", ipApi.Status)
 		ipGroup.GET("ping", ipApi.Ping)
-		ipGroup.PATCH("volume", ipApi.Volume)
+		ipGroup.POST("volume", ipApi.Volume)
+		ipGroup.POST("playAudio", ipApi.PlayAudio)
+	}
+	pub := pubRouter.Group("ipcast")
+	{
+		pub.GET("AudioSource/:id", ipApi.AudioSource)
 	}
 }