2025-01-11 22:34:36 +08:00
|
|
|
|
package handler
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"VideoStream/proto"
|
2025-01-12 15:18:58 +08:00
|
|
|
|
"VideoStream/service"
|
2025-01-11 22:34:36 +08:00
|
|
|
|
"fmt"
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
|
"gocv.io/x/gocv"
|
|
|
|
|
|
"io"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func SetUpToolGroup(router *gin.Engine) {
|
|
|
|
|
|
toolGroup := router.Group("/tool")
|
|
|
|
|
|
toolGroup.GET("/video_stream", GetVideoStream)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type videoStreamReq struct {
|
|
|
|
|
|
ID int `json:"id" form:"id"`
|
|
|
|
|
|
Key string `json:"key" form:"key"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func GetVideoStream(c *gin.Context) {
|
|
|
|
|
|
var req videoStreamReq
|
|
|
|
|
|
if err := c.ShouldBind(&req); err != nil {
|
|
|
|
|
|
c.JSON(400, gin.H{"error": err.Error()})
|
|
|
|
|
|
return
|
|
|
|
|
|
} else {
|
|
|
|
|
|
//查看id是否存在
|
|
|
|
|
|
index := -1
|
|
|
|
|
|
for _, device := range proto.Config.DeviceInfo {
|
|
|
|
|
|
if device.ID == req.ID {
|
|
|
|
|
|
index = req.ID
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if index == -1 {
|
|
|
|
|
|
c.JSON(400, gin.H{"error": "id not exist"})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
//查看key是否正确
|
|
|
|
|
|
if req.Key != "123456" {
|
|
|
|
|
|
c.JSON(400, gin.H{"error": "key error"})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
//设备流
|
|
|
|
|
|
c.Stream(func(w io.Writer) bool {
|
|
|
|
|
|
var count int
|
|
|
|
|
|
for {
|
2025-01-12 15:18:58 +08:00
|
|
|
|
frame, cnt := service.GetDeviceCurrentFrame(req.ID)
|
2025-01-11 22:34:36 +08:00
|
|
|
|
if cnt == count {
|
|
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
//gocv.Matrix转为jpeg
|
|
|
|
|
|
img, err := gocv.IMEncode(".jpg", frame)
|
|
|
|
|
|
frame_ := img.GetBytes()
|
|
|
|
|
|
|
|
|
|
|
|
_, err = w.Write([]byte("--frame\r\nContent-Type: image/jpeg\r\n\r\n"))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Printf("写入头部信息错误: %v\n", err)
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
_, err = w.Write(frame_)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Printf("写入帧数据错误: %v\n", err)
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
_, err = w.Write([]byte("\r\n"))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Printf("写入帧结束标记错误: %v\n", err)
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
time.Sleep(50 * time.Millisecond) // 控制帧率,模拟每秒约20帧,可按实际调整
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|