package handler import ( "VideoStream/proto" "VideoStream/service" "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 { frame, cnt := service.GetDeviceCurrentFrame(req.ID) 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帧,可按实际调整 } }) } }