• 国标GB28181协议视频人脸识别/车牌识别平台EasyCVR设定好录像计划重启后通道不录像原因排查


    TSINGSEE青犀视频开发的视频智能分析平台EasyCVR支持像国标EasyGBS平台一样开启录像计划进行录像。正常情况下不同通道同时开启录像计划的话,通道之间的录像计划不会被影响或者混乱,但是我们测试时却发现了异常。

    当我们测试EasyCVR的两路设备同时开启设备录像时,随后重启EasyCVR服务后,会发现设备录像只有一路在录像,另外一路不录像。

    因此我们先排查程序启动时候云端录像相关代码:

    var channel []models.Channel
    db.SQLite.Where("Ondemand=?", false).Find(&channel)
    for _, v := range channel {
           AutoTouchStream(&v, true)
           if v.Record > 0 && v.RecordPlanSwitch {
                  go v.DoTicker()
           }
    }
    
    func (channel *Channel) DoTicker() {
           defer func() {
                  if err := recover(); err != nil {
                         err_logger.Error(fmt.Sprintf("%s
    ", err))
                         err_logger.Error(fmt.Sprintln(string(debug.Stack())))
                  }
           }()
           if channel.quit == nil {
                  channel.quit = make(chan bool)
           } else {
                  return
           }
           channel.cleanRecordTime = time.Now()
           ticker := time.NewTicker(10 * time.Second)
           defer ticker.Stop()
           for {
                  select {
                  case <-ticker.C:
                         //发送通知更新云端录像状态
                         //uax.ChannelDispatcher.Dispatch(fmt.Sprintf("cloud_record_%s_%s", channel.DeviceID, channel.ID), uint(channel.Record))
                         if CheckChannelRecordPlan(channel.DeviceID, channel.ID) {
                                uax.ChannelDispatcher.Dispatch(fmt.Sprintf("cloud_record_%s_%s", channel.DeviceID, channel.ID), uint(channel.Record))
    
    

    通过排查代码发现,在程序启动时,会自动初始化开启录像计划的设备,让其继续录像,但是在doticker方法中使用的是*channel指针类型的通道数据,犹豫指针类型的特性(指向值的内存地址,当修改指针值时,底层的数据也会发生变化),导致在循环遍历所有开启录像计划的设备中,指针指向的数值永远都是最后一个设备的数据。

    这就能够理解为什么两台设备开启录像计划,却在程序重启后只有一台在录像了。

    我们将代码做如下修改:

    func (channel Channel) DoTicker() {
           defer func() {
                  if err := recover(); err != nil {
                         err_logger.Error(fmt.Sprintf("%s
    ", err))
                         err_logger.Error(fmt.Sprintln(string(debug.Stack())))
                  }
           }()
           //if channel.quit == nil {
           //     channel.quit = make(chan bool)
           //} else {
           //     return
           //}
           key := fmt.Sprintf("%s_%s", channel.DeviceID, channel.ID)
           fmt.Println("======", key)
           if _, ok := atsMap.Load(key); !ok {
                  atsMap.Store(key, true)
           } else {
                  return
           }
           channel.cleanRecordTime = time.Now()
           ticker := time.NewTicker(10 * time.Second)
           defer ticker.Stop()
    
    

    再次重启程序测试,可以看到两台设备都在正常录像。

    对于录像计划的开发,TSINGSEE青犀视频团队首先是从EasyNVR开始的,如果对录像计划的开发有兴趣,可以阅读我们之前写过的博客:EasyNVR录像计划模块开发过程。如果想对EasyCVR进行测试,欢迎联系我们了解。

  • 相关阅读:
    10个好用的 HTML5 特性
    数字营销2.0时代已到来
    云原生时代,.NET5必将称王!
    为什么需要堡垒机
    从SOA和微服务到云原生解决方案实践
    阿里云资深技术专家李克畅谈边缘云计算趋势与实践
    OpenKruise v0.9.0 版本发布:新增 Pod 重启、删除防护等重磅功能
    浅谈分布式一致性:Raft 与 SOFAJRaft
    数仓架构的持续演进与发展 — 云原生、湖仓一体、离线实时一体、SaaS模式
    如何基于MaxCompute快速打通数据仓库和数据湖的湖仓一体实践
  • 原文地址:https://www.cnblogs.com/TSINGSEE/p/14217864.html
Copyright © 2020-2023  润新知