人脸识别视频智能安防系统EasyCVR v1.1.12开启定时快照导致视频按需播放时画面卡顿的优化

TSINGSEE青犀视频开发的人脸识别视频智能安防系统EasyCVR的V1.1.12版本修改了实时快照和定时快照的处理逻辑。目前的版本可以通过调用接口的方式返回实时快照,返回形式为快照地址或者base64快照数据两种。

此次更新过后虽解决了原本的问题,但引入了其他的问题。如果用户采用按需播放的情况并且开启了快照,快照间隔时间1分钟,则会出现按需播放1-2分钟的时候,画面卡顿1-2s然后恢复正常播放的情况。

测试人员反馈该问题,通过复现,发现现象很有规律,进一步定位和快照有关,因此检查相关代码,代码显示没有对正在按需播放的情况进行处理,没有判断当前拉流状态。

因此我们添加判断逻辑即可解决该bug,参考代码如下:

			if dataType == DATA_TYPE_VIDEO_FRAME {
				//[v1.0.25] 解决265 级联播放花屏
				client.PtsMs += 40

				if avFrame.u32VFrameType == C.EASY_SDK_VIDEO_FRAME_I {
					flag := true
					thisTime := time.Now()
					snapInterval := utils.Conf().Section("base_config").Key("channel_snap_interval").MustInt(-1)
					if snapInterval > 0 {
						//保存快照
						if thisTime.After(client.SnapTime.Add(client.SnapDuration)) || client.GetSourceBase().Snaping {
							client.SnapTime = thisTime
							jpg, _ := h264.GetJPG(C.GoBytes(unsafe.Pointer(avFrame.pBuffer), C.int(avFrame.u32AVFrameLen)))
							channelDB, err := cvrdao.GetChannelDao().Get(client.channelID)
							if err == nil {
								if err := ioutil.WriteFile(channelDB.SnapPath(), jpg, 0644); err != nil {
									log.Println(err.Error())
									//break
								}
								if channelDB.Online == 0 {
									channelDB.Online = 1
									cvrdao.GetChannelDao().Update(channelDB)
								}
							}
							if utils.Debug {
								log.Println("快照生成成功")
								log.Println(client.GetSourceBase().Snaping)
							}

							flag = false

							if client.GetSourceBase().Snaping {
								client.GetSourceBase().Snaping = false
								if channelDB.OnDemand != 0 {
									if utils.Debug {
										log.Println("快照临时拉流,关闭流")
									}
									if client.GetSourceBase().AfterSnapCloseSource {
										go client.Close()
									}
								}
							}
						}
					}

					if flag && client.GetSourceBase().RealSnaping {
						client.SnapTime = thisTime
						jpg, _ := h264.GetJPG(C.GoBytes(unsafe.Pointer(avFrame.pBuffer), C.int(avFrame.u32AVFrameLen)))
						channelDB, err := cvrdao.GetChannelDao().Get(client.channelID)
						if err == nil {
							if err := ioutil.WriteFile(channelDB.SnapPath(), jpg, 0644); err != nil {
								log.Println(err.Error())
								//break
							}
							if channelDB.Online == 0 {
								channelDB.Online = 1
								cvrdao.GetChannelDao().Update(channelDB)
							}
						}
						log.Println("快照生成成功")
						client.GetSourceBase().RealSnaping = false
					}
				}
			} else if dataType == DATA_TYPE_AUDIO_FRAME {
				channelDB, err := cvrdao.GetChannelDao().Get(client.channelID)
				if err == nil {
					if channelDB.EnableAudio == 0 {
						return
					}
				}
			}

			sinks := client.Base.GetSinks()
			for _, value := range sinks {
				if value.GetSinkID() == 0 && !client.Base.Record { //录像计划
					continue
				}

				if err := value.SendRTMPEx(uintptr(unsafe.Pointer(avFrame)), int(client.MediaInfo.u32VideoCodec), client.PtsMs); err != nil {
					log.Println(err.Error())
				}
			}
		}

原文地址:https://www.cnblogs.com/TSINGSEE/p/14498915.html