使用分离方式,修改视频流返回方式

This commit is contained in:
lijun 2025-01-18 19:59:32 +08:00
parent 69f81addeb
commit d69e02115f
3 changed files with 49 additions and 57 deletions

View File

@ -135,21 +135,29 @@ func GetVideoStream(c *gin.Context) {
func GetRealTimeImage(c *gin.Context) { func GetRealTimeImage(c *gin.Context) {
id, _ := c.Get("id") id, _ := c.Get("id")
id1 := id.(int) id1 := id.(int)
device_id := c.Query("device_id") deviceId := c.Query("device_id")
device_id_int, _ := strconv.Atoi(device_id) deviceIdInt, _ := strconv.Atoi(deviceId)
device := service.GetDevice(device_id_int, id1) device := service.GetDevice(deviceIdInt, id1)
if device.ID == 0 { if device.ID == 0 {
c.JSON(http.StatusOK, gin.H{"code": 4, "message": "device not found"}) c.JSON(http.StatusOK, gin.H{"code": 4, "message": "device not found"})
return return
} }
//查看设备是否在获取
is_get, ok := service.DeviceIsGettingFrame.Load(device.ID)
if !ok || is_get == false {
//直接返回
c.JSON(http.StatusOK, gin.H{"code": 4, "message": "device not getting frame or not exist"})
log.Printf("device:%d not found", device.ID)
return
}
ws, err := upgrader.Upgrade(c.Writer, c.Request, nil) ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil { if err != nil {
log.Printf("connect wss err:%v", err) log.Printf("connect wss err:%v", err)
return return
} }
worker.SetRedisWithExpire(strconv.Itoa(int(device.ID))+"_is_play", "1", time.Minute*5) worker.SetRedisWithExpire(strconv.Itoa(int(device.ID))+"_is_play", "1", time.Minute*5)
log.Printf("device_id:%d has set is_play to 1", device_id_int) log.Printf("device_id:%d has set is_play to 1", deviceIdInt)
go subscribeAndHandleMessagesV3(ws, device_id_int) go subscribeAndHandleMessagesV3(ws, deviceIdInt)
} }
func subscribeAndHandleMessagesV3(ws *websocket.Conn, device_id int) { func subscribeAndHandleMessagesV3(ws *websocket.Conn, device_id int) {

View File

@ -71,13 +71,14 @@ func init() {
if err != nil { if err != nil {
panic("failed to read config file:" + err.Error()) panic("failed to read config file:" + err.Error())
} }
service.DeviceFrameCount = make(map[int]int)
for _, device := range proto.Config.DeviceInfo { for _, device := range proto.Config.DeviceInfo {
//service.DeviceRWMap[device.ID] = sync.RWMutex{} //service.DeviceRWMap[device.ID] = sync.RWMutex{}
//service.DeviceCurrentFrameMap[device.ID] = gocv.NewMat() //service.DeviceCurrentFrameMap[device.ID] = gocv.NewMat()
//service.DeviceIsGettingFrame[device.ID] = false //service.DeviceIsGettingFrame[device.ID] = false
service.DeviceRWMap.Store(device.ID, &sync.RWMutex{}) service.DeviceRWMap.Store(device.ID, &sync.RWMutex{})
service.DeviceCurrentFrameMap.Store(device.ID, gocv.NewMat()) service.DeviceCurrentFrameMap.Store(device.ID, gocv.NewMat())
service.DeviceFrameCount.Store(device.ID, 0) service.DeviceFrameCount[device.ID] = 0
service.DeviceIsGettingFrame.Store(device.ID, false) service.DeviceIsGettingFrame.Store(device.ID, false)
} }
} }
@ -100,7 +101,7 @@ func ReadConfigAndSetSystem() {
//说明没有这个设备,需初始化添加 //说明没有这个设备,需初始化添加
service.DeviceRWMap.Store(device.ID, &sync.RWMutex{}) service.DeviceRWMap.Store(device.ID, &sync.RWMutex{})
service.DeviceCurrentFrameMap.Store(device.ID, gocv.NewMat()) service.DeviceCurrentFrameMap.Store(device.ID, gocv.NewMat())
service.DeviceFrameCount.Store(device.ID, 0) service.DeviceFrameCount[device.ID] = 0
service.DeviceIsGettingFrame.Store(device.ID, false) service.DeviceIsGettingFrame.Store(device.ID, false)
} }
if is_get == false && device.NextStop == false { //如果设备流已经停止且不暂停,则开启 if is_get == false && device.NextStop == false { //如果设备流已经停止且不暂停,则开启

View File

@ -16,83 +16,77 @@ import (
var DeviceRWMap = &sync.Map{} var DeviceRWMap = &sync.Map{}
var DeviceCurrentFrameMap = &sync.Map{} var DeviceCurrentFrameMap = &sync.Map{}
var DeviceFrameCount = &sync.Map{} var DeviceFrameCount map[int]int
var DeviceIsGettingFrame = &sync.Map{} var DeviceIsGettingFrame = &sync.Map{}
var Device1CurrentFrame gocv.Mat var Device1CurrentFrame gocv.Mat
var Device50CurrentFrame gocv.Mat var Device50CurrentFrame gocv.Mat
var Device73CurrentFrame gocv.Mat
func SetDeviceCurrentFrame(frame gocv.Mat, device_id int) error { func SetDeviceCurrentFrame(frame gocv.Mat, deviceId int) error {
//获取读写锁 //获取读写锁
mutex_, ok := DeviceRWMap.Load(device_id) mutex_, ok := DeviceRWMap.Load(deviceId)
if !ok { if !ok {
return fmt.Errorf("设备:%s 读写锁不存在", device_id) return fmt.Errorf("设备:%s 读写锁不存在", deviceId)
} }
mutex := mutex_.(*sync.RWMutex) mutex := mutex_.(*sync.RWMutex)
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
//获取前一帧,将前一帧释放 //获取前一帧,将前一帧释放
framePrev, ok := DeviceCurrentFrameMap.Load(device_id) framePrev, ok := DeviceCurrentFrameMap.Load(deviceId)
if ok { if ok {
frame_, ok2 := framePrev.(gocv.Mat) frame_, ok2 := framePrev.(gocv.Mat)
if ok2 { if ok2 {
err2 := frame_.Close() err2 := frame_.Close()
if err2 != nil { if err2 != nil {
log.Printf("设备:%d, 错误: 无法关闭帧\n", device_id) log.Printf("设备:%d, 错误: 无法关闭帧\n", deviceId)
} }
} }
} }
//设置当前帧 //设置当前帧
DeviceCurrentFrameMap.Store(device_id, frame) DeviceCurrentFrameMap.Store(deviceId, frame)
frame_count, ok := DeviceFrameCount.Load(device_id) frameCount, ok := DeviceFrameCount[deviceId]
if !ok { if !ok {
return fmt.Errorf("设备:%s 当前帧计数不存在", device_id) return fmt.Errorf("设备:%s 当前帧计数不存在", deviceId)
} }
frame_count_ := frame_count.(int) frameCount++
frame_count_++ DeviceFrameCount[deviceId] = frameCount
DeviceFrameCount.Store(device_id, frame_count_)
return nil return nil
} }
func SetDeviceCurrentFrameV2(frame *gocv.Mat, device_id int) error { func SetDeviceCurrentFrameV2(frame *gocv.Mat, deviceId int) error {
//获取读写锁 //获取读写锁
mutex_, ok := DeviceRWMap.Load(device_id) mutex_, ok := DeviceRWMap.Load(deviceId)
if !ok { if !ok {
return fmt.Errorf("设备:%s 读写锁不存在", device_id) return fmt.Errorf("设备:%s 读写锁不存在", deviceId)
} }
mutex := mutex_.(*sync.RWMutex) mutex := mutex_.(*sync.RWMutex)
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
//设置当前帧 //设置当前帧
switch device_id { switch deviceId {
case 1: case 1:
//err := Device1CurrentFrame.Close()
//if err != nil {
// log.Printf("设备:%d, 错误: 无法关闭帧\n", device_id)
//}
if Device1CurrentFrame.Empty() { if Device1CurrentFrame.Empty() {
Device1CurrentFrame = gocv.NewMatWithSize((*frame).Rows(), (*frame).Cols(), (*frame).Type()) Device1CurrentFrame = gocv.NewMatWithSize((*frame).Rows(), (*frame).Cols(), (*frame).Type())
} }
(*frame).CopyTo(&Device1CurrentFrame) (*frame).CopyTo(&Device1CurrentFrame)
//err := deepcopier.Copy(*frame).To(&Device1CurrentFrame)
//if err != nil {
// log.Printf("设备:%d, 错误: 无法设置帧,err: %s \n", device_id, err.Error())
//}
//查看帧状态
//log.Printf("frame:%v,Device1CurrentFrame:%v \n", (*frame).Empty(), Device1CurrentFrame.Empty())
//Device1CurrentFrame = *frame
case 50: case 50:
if Device50CurrentFrame.Empty() { if Device50CurrentFrame.Empty() {
Device50CurrentFrame = gocv.NewMatWithSize((*frame).Rows(), (*frame).Cols(), (*frame).Type()) Device50CurrentFrame = gocv.NewMatWithSize((*frame).Rows(), (*frame).Cols(), (*frame).Type())
} }
(*frame).CopyTo(&Device50CurrentFrame) (*frame).CopyTo(&Device50CurrentFrame)
case 73:
if Device73CurrentFrame.Empty() {
Device73CurrentFrame = gocv.NewMatWithSize((*frame).Rows(), (*frame).Cols(), (*frame).Type())
} }
frame_count, ok := DeviceFrameCount.Load(device_id) (*frame).CopyTo(&Device73CurrentFrame)
}
frameCount, ok := DeviceFrameCount[deviceId]
if !ok { if !ok {
return fmt.Errorf("设备:%s 当前帧计数不存在", device_id) return fmt.Errorf("设备:%s 当前帧计数不存在", deviceId)
} }
frame_count_ := frame_count.(int) frameCount++
frame_count_++ DeviceFrameCount[deviceId] = frameCount
DeviceFrameCount.Store(device_id, frame_count_)
return nil return nil
} }
@ -126,15 +120,11 @@ func GetDeviceCurrentFrameV2(frame *gocv.Mat, deviceId int) int {
log.Printf("DeviceCurrentFrameMap 存储的不是 gocv.Mat 类型device_id: %d \n", deviceId) log.Printf("DeviceCurrentFrameMap 存储的不是 gocv.Mat 类型device_id: %d \n", deviceId)
} }
*frame = frame_ *frame = frame_
frame_countIface, ok := DeviceFrameCount.Load(deviceId) frameCount, ok := DeviceFrameCount[deviceId]
if !ok { if !ok {
return -1 return -1
} }
frame_count, ok := frame_countIface.(int) return frameCount
if !ok {
log.Printf("DeviceFrameCount 存储的不是 int 类型device_id: %d", deviceId)
}
return frame_count
} }
func GetDeviceCurrentFrameV3(deviceId int) (gocv.Mat, int) { func GetDeviceCurrentFrameV3(deviceId int) (gocv.Mat, int) {
@ -174,17 +164,14 @@ func GetDeviceCurrentFrameV3(deviceId int) (gocv.Mat, int) {
} }
frame_countIface, ok := DeviceFrameCount.Load(deviceId) frameCount, ok := DeviceFrameCount[deviceId]
if !ok { if !ok {
return gocv.NewMat(), -1 return gocv.NewMat(), -1
} }
frame_count, ok := frame_countIface.(int)
if !ok {
log.Printf("DeviceFrameCount 存储的不是 int 类型device_id: %d", deviceId)
}
//查看地址 //查看地址
//log.Printf("frame:%p,Device1CurrentFrame:%p,Device50CurrentFrame:%p\n", &frame, &Device1CurrentFrame, &Device50CurrentFrame) //log.Printf("frame:%p,Device1CurrentFrame:%p,Device50CurrentFrame:%p\n", &frame, &Device1CurrentFrame, &Device50CurrentFrame)
return frame, frame_count return frame, frameCount
} }
func GetDeviceCurrentFrame(deviceId int) (gocv.Mat, int) { func GetDeviceCurrentFrame(deviceId int) (gocv.Mat, int) {
defer func() { defer func() {
@ -215,15 +202,11 @@ func GetDeviceCurrentFrame(deviceId int) (gocv.Mat, int) {
if !ok { if !ok {
log.Printf("DeviceCurrentFrameMap 存储的不是 gocv.Mat 类型device_id: %d \n", deviceId) log.Printf("DeviceCurrentFrameMap 存储的不是 gocv.Mat 类型device_id: %d \n", deviceId)
} }
frame_countIface, ok := DeviceFrameCount.Load(deviceId) frameCount, ok := DeviceFrameCount[deviceId]
if !ok { if !ok {
return gocv.NewMat(), -1 return gocv.NewMat(), -1
} }
frame_count, ok := frame_countIface.(int) return frame, frameCount
if !ok {
log.Printf("DeviceFrameCount 存储的不是 int 类型device_id: %d", deviceId)
}
return frame, frame_count
} }
func getVideoFrame(device proto.DeviceInfo) { func getVideoFrame(device proto.DeviceInfo) {