From fab3bb77c6410c14748e2873de395b985495f5e2 Mon Sep 17 00:00:00 2001 From: lijun Date: Sun, 12 Jan 2025 15:18:58 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AE=9A=E6=97=B6=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E7=9B=AE?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler/tool.go | 3 +- main.go | 144 +++--------------------------------------------- service/tool.go | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 137 deletions(-) diff --git a/handler/tool.go b/handler/tool.go index 20a3d0b..d78b2f4 100644 --- a/handler/tool.go +++ b/handler/tool.go @@ -2,6 +2,7 @@ package handler import ( "VideoStream/proto" + "VideoStream/service" "fmt" "github.com/gin-gonic/gin" "gocv.io/x/gocv" @@ -46,7 +47,7 @@ func GetVideoStream(c *gin.Context) { c.Stream(func(w io.Writer) bool { var count int for { - frame, cnt := GetDeviceCurrentFrame(req.ID) + frame, cnt := service.GetDeviceCurrentFrame(req.ID) if cnt == count { time.Sleep(50 * time.Millisecond) continue diff --git a/main.go b/main.go index d58fd69..156b61a 100644 --- a/main.go +++ b/main.go @@ -3,24 +3,15 @@ package main import ( "VideoStream/handler" "VideoStream/proto" + "VideoStream/service" "VideoStream/worker" - "fmt" "github.com/gin-gonic/gin" "github.com/robfig/cron/v3" "gocv.io/x/gocv" - "image" - "image/color" "log" - "net/http" "sync" - "time" ) -var DeviceRWMap = make(map[int]sync.RWMutex) -var DeviceCurrentFrameMap = make(map[int]gocv.Mat) -var DeviceFrameCount = make(map[int]int) -var DeviceIsStop = make(map[int]bool) - func main() { gin.SetMode(gin.ReleaseMode) r := gin.Default() @@ -54,13 +45,14 @@ func init() { panic("failed to read config file:" + err.Error()) } for _, device := range proto.Config.DeviceInfo { - DeviceRWMap[device.ID] = sync.RWMutex{} - DeviceCurrentFrameMap[device.ID] = gocv.NewMat() + service.DeviceRWMap[device.ID] = sync.RWMutex{} + service.DeviceCurrentFrameMap[device.ID] = gocv.NewMat() } } func myTask() { log.Println("每10秒执行一次") + ReadConfigAndSetSystem() } func ReadConfigAndSetSystem() { @@ -70,130 +62,10 @@ func ReadConfigAndSetSystem() { if err != nil { panic("failed to read config file:" + err.Error()) } - //检测是否需要获取设备流 -} - -func SetDeviceCurrentFrame(frame gocv.Mat, device_id int) error { - //获取读写锁 - mutex, ok := DeviceRWMap[device_id] - if !ok { - return fmt.Errorf("设备:%s 读写锁不存在", device_id) - } - mutex.Lock() - defer mutex.Unlock() - //设置当前帧 - DeviceCurrentFrameMap[device_id] = frame - DeviceFrameCount[device_id]++ - return nil -} - -func GetDeviceCurrentFrame(device_id int) (gocv.Mat, int) { - //获取读写锁 - mutex, ok := DeviceRWMap[device_id] - if !ok { - return gocv.NewMat(), -1 - } - mutex.RLock() - defer mutex.RUnlock() - //获取当前帧 - return DeviceCurrentFrameMap[device_id], DeviceFrameCount[device_id] -} - -func getVideoFrame(device proto.DeviceInfo) { - webcam, err := gocv.OpenVideoCapture(device.Stream) - if err != nil { - fmt.Printf("设备:%s 错误: 无法打开视频流,err: %v\n", device.ID, err) - return - } - defer webcam.Close() - // 字体相关设置,对应OpenCV默认字体等,这里简化处理,实际可按需求调整 - font := gocv.FontHersheySimplex - fontScale := 0.5 - fontColor := color.RGBA{G: 255} - lineType := 2 - z := 0 - for { - if device.LogFrame > 0 && z%device.LogFrame == 0 { - fmt.Printf("设备:%s 当前帧: %d\n", device.ID, z) - } - if device.NextStop { - break - } - frame := gocv.NewMat() - ok := webcam.Read(&frame) - if !ok { - fmt.Printf("设备:%s 错误: 无法从视频流中读取帧\n", device) - break - } - if frame.Empty() { - fmt.Printf("设备:%s 错误: 无法从视频流中读取帧\n", device) - //等待50ms - time.Sleep(50 * time.Millisecond) - continue - } - height := frame.Rows() - width := frame.Cols() - if height < device.CheckFrameHeight || width < device.CheckFrameWidth { - fmt.Printf("设备:%s 帧尺寸已改变\n", device) - break - } - currentTime := time.Now().Format("2006-01-02 15:04:05") - gocv.PutText(&frame, currentTime, image.Point{10, 20}, font, fontScale, fontColor, lineType) - //需要将帧付给全局变量 - err := SetDeviceCurrentFrame(frame, device.ID) - if err != nil { - fmt.Printf("设备:%s 错误: 无法设置当前帧\n", device) - } - z++ - } -} - -// 发起get请求,返回响应状态码 -func Get(url string) int { - req, err := http.NewRequest("GET", url, nil) - var client = &http.Client{} - if err != nil { - return 500 - } - resp, err := client.Do(req) - if err != nil { - return 500 - } - return resp.StatusCode -} - -func GetVideoStream(id int) { - for { - var device proto.DeviceInfo - var index int - //获取设备信息 - for i, device1 := range proto.Config.DeviceInfo { - if device1.ID == id { - device = device1 - break - } - index = i - } - if index == len(proto.Config.DeviceInfo) { - //设备不存在 - log.Println("device:", id, " not found") - break - } - if device.NextStop { - DeviceIsStop[id] = true - break - } - //设置设备控制信息 - status := Get(device.Control) - DeviceIsStop[id] = false - log.Println("device:", device.ID, " set control info status:", status) - getVideoFrame(device) - } - -} - -func DoGetVideoStream() { + //检测是否需要获取设备流,如果需要则开启 for _, device := range proto.Config.DeviceInfo { - go GetVideoStream(device.ID) + if service.DeviceIsStop[device.ID] == false { + go service.GetVideoStream(device.ID) + } } } diff --git a/service/tool.go b/service/tool.go index 6d43c33..ce44354 100644 --- a/service/tool.go +++ b/service/tool.go @@ -1 +1,143 @@ package service + +import ( + "VideoStream/proto" + "fmt" + "gocv.io/x/gocv" + "image" + "image/color" + "log" + "net/http" + "sync" + "time" +) + +var DeviceRWMap = make(map[int]sync.RWMutex) +var DeviceCurrentFrameMap = make(map[int]gocv.Mat) +var DeviceFrameCount = make(map[int]int) +var DeviceIsStop = make(map[int]bool) + +func SetDeviceCurrentFrame(frame gocv.Mat, device_id int) error { + //获取读写锁 + mutex, ok := DeviceRWMap[device_id] + if !ok { + return fmt.Errorf("设备:%s 读写锁不存在", device_id) + } + mutex.Lock() + defer mutex.Unlock() + //设置当前帧 + DeviceCurrentFrameMap[device_id] = frame + DeviceFrameCount[device_id]++ + return nil +} + +func GetDeviceCurrentFrame(device_id int) (gocv.Mat, int) { + //获取读写锁 + mutex, ok := DeviceRWMap[device_id] + if !ok { + return gocv.NewMat(), -1 + } + mutex.RLock() + defer mutex.RUnlock() + //获取当前帧 + return DeviceCurrentFrameMap[device_id], DeviceFrameCount[device_id] +} + +func getVideoFrame(device proto.DeviceInfo) { + webcam, err := gocv.OpenVideoCapture(device.Stream) + if err != nil { + fmt.Printf("设备:%s 错误: 无法打开视频流,err: %v\n", device.ID, err) + return + } + defer webcam.Close() + // 字体相关设置,对应OpenCV默认字体等,这里简化处理,实际可按需求调整 + font := gocv.FontHersheySimplex + fontScale := 0.5 + fontColor := color.RGBA{G: 255} + lineType := 2 + z := 0 + for { + if device.LogFrame > 0 && z%device.LogFrame == 0 { + fmt.Printf("设备:%s 当前帧: %d\n", device.ID, z) + } + if device.NextStop { + break + } + frame := gocv.NewMat() + ok := webcam.Read(&frame) + if !ok { + fmt.Printf("设备:%s 错误: 无法从视频流中读取帧\n", device) + break + } + if frame.Empty() { + fmt.Printf("设备:%s 错误: 无法从视频流中读取帧\n", device) + //等待50ms + time.Sleep(50 * time.Millisecond) + continue + } + height := frame.Rows() + width := frame.Cols() + if height < device.CheckFrameHeight || width < device.CheckFrameWidth { + fmt.Printf("设备:%s 帧尺寸已改变\n", device) + break + } + currentTime := time.Now().Format("2006-01-02 15:04:05") + gocv.PutText(&frame, currentTime, image.Point{10, 20}, font, fontScale, fontColor, lineType) + //需要将帧付给全局变量 + err := SetDeviceCurrentFrame(frame, device.ID) + if err != nil { + fmt.Printf("设备:%s 错误: 无法设置当前帧\n", device) + } + z++ + } +} + +// 发起get请求,返回响应状态码 +func Get(url string) int { + req, err := http.NewRequest("GET", url, nil) + var client = &http.Client{} + if err != nil { + return 500 + } + resp, err := client.Do(req) + if err != nil { + return 500 + } + return resp.StatusCode +} + +func GetVideoStream(id int) { + for { + var device proto.DeviceInfo + var index int + //获取设备信息 + for i, device1 := range proto.Config.DeviceInfo { + if device1.ID == id { + device = device1 + break + } + index = i + } + if index == len(proto.Config.DeviceInfo) { + //设备不存在 + log.Println("device:", id, " not found") + break + } + if device.NextStop { + DeviceIsStop[id] = true + break + } + //设置设备控制信息 + status := Get(device.Control) + DeviceIsStop[id] = false + log.Println("device:", device.ID, " set control info status:", status) + getVideoFrame(device) + } + +} + +func DoGetVideoStream() { + for _, device := range proto.Config.DeviceInfo { + go GetVideoStream(device.ID) + } +}