欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

国标GB28181协议视频平台EasyGBS实现告警功能,自动截取快照

程序员文章站 2022-07-06 12:34:02
...

大家千呼万唤的告警功能终于在EasyGBS里面开发实现了。之前我们在做项目的时候,就接到了很多团队告警功能的需求,在TSINGSEE研发团队一段时间的努力之后,终于实现了识别告警功能,具体效果如下所示:

国标GB28181协议视频平台EasyGBS实现告警功能,自动截取快照

当监测有异常情况时,系统就会自动截取快照并记录时间。

但是我们发现在摄像头发送告警信息过来时,系统同时也会对未开启视频推流的摄像头发送推流请求,以下为推流请求代码。

func doAlarmSnap(c *sip.Context, channels models.Channel, serial string) (err error) {
	_sipDev, _ := c.Server.DevCache.Get(serial)
	locker := channels.Lock()
	if locker == nil {
		err = fmt.Errorf("alarm snap channel[%s:%s] is busy", channels.DeviceID, channels.ID)
		return
	}
	if sipDev, ok := _sipDev.(*sip.Device); ok {
		SnapStart(sipDev, channels.ToSIPChannel(), 10*time.Second)
	}
	defer locker.Unlock()
	return
}
 
reqInviteMS, err := Server.MakeRequest("INVITE", toMS, "")
	if err != nil {
		return
	}

只要这个请求一发出去,系统推流请求就会卡住不再返回信息流。

国标GB28181协议视频平台EasyGBS实现告警功能,自动截取快照

经过我们的排查,发现是调用快照的方法给摄像头发送推流请求时,系统没有进行多线程操作,导致同时发送请求给多个摄像头调取快照,而未推流的摄像头由于没有快照,系统收不到返回信息流,就会卡住。

我们需要在go中进行多线程操作,及添加关键字go(启用go关键字后程序会新开一个goroutine 创建一个并发任务进行执行)

db.SQLite.Create(&models.Alarm{
			DeviceID:      serial,
			ChannelID:     deviceId,
			DeviceName:    device.Name,
			ChannelName:   channels.Name,
			AlarmPriority: alarmPriority,
			AlarmTime:     aTime,
			AlarmMethod:   alarmMethod,
			AlarmType:     alarmType,
			AlarmSnap:     "",
		})
		go doAlarmSnap(c, *channels, serial)

再次播放和运动检测截图显示正常。

国标GB28181协议视频平台EasyGBS实现告警功能,自动截取快照