一、背景
有一批AI摄像头需要部署到客户方,需要实现的功能:1、摄像头实时预览,摄像头安装在不同地点的内网环境,因此需要通过frpc服务器做内网摄像头的代理;2、摄像头smart事件,进入区域、离开区域、区域入侵、抓拍等数据的获取,目前海康的摄像头一般都支持smart事件主动上报(通过配置网络->高级设置->告警服务器,配置接收主动上报数据的http监听接口)。
坑点:
1、摄像头安装在内网环境,实时预览需要打通外网,需要摄像头提供外网能访问的地址,
2、实现事件监听,摄像头在没有外网地址的情况下无法通过官方提供的SDK部署登录和布防监听内网摄像头的数据;
3、了解清楚,目前获取海康摄像头事件数据有三种方式,一种是海康摄像头的主动上报,在摄像头后台可以配置(配置路径:网络->高级设置->告警服务器,配置告警服务器,也就是我们项目接收数据的接口);另一种是通过官方提供的SDK,通过布防告警监听的方式监听摄像头事件触发的接口,布防告警监听需要通过jna包,将SDK的c语言的文件加载成Java类,不是很友好;第三种是在海康的开放平台申请入驻,比如海康云曜,通过海康提供的平台管理设备,平台有提供消息消费接口获取上报的数据,更直观,但是要收费的。目前我们采用的是设备告警服务器主动上报。其中遇到了狠多坑。
4、告警服务器上报的数据没有文档,刚开始通过区域入侵,配置后没有触发报警,而后通过越界侦测和进入区域这两个是可以触发报警的。触发报警主动上传数据到告警服务器的数据是未知的,没有文档,各种文档都看了一遍都没有,后来通过抓包工具、http数据解析等方式拿到了上报过来的报文。
二、通过官方SDK实现抓图和布防监听、及摄像头控制等
1、走捷径,研究了对海康SDK做了封装的一些开源项目
2、项目地址:
找了一个开源的项目研究了一下:https://gitee.com/fuhaoxiaoshenke/hikvision git clone https://gitee.com/fuhaoxiaoshenke/hikvision.git
告警布防监听
抓拍
推流
三、告警服务器接收设备事件主动上传和配置
1、配置smart事件-越界侦测
配置事项:
1-1、选中启用、警戒面、方向、灵敏度;
1-2、配置布防时间
1-3、配置联动方式:
1-4、配置存储:存储-计划配置-抓图-启用事件抓图,配置事件抓图的数量和分辨率等信息
具体配置方面的问题可以直接咨询海康的人工客服和官网的技术支持或者设备供应商。
1-5、配置告警服务器:服务器地址、接口地址、端口,告警服务器就是你要接受海康设备上传数据的接口。这里的坑点上传的数据没有文档描述,技术支持也不清楚。所以要通过告警服务器抓包或者socket监听或者解析流来获取
2、告警服务器接口
越界侦测的监听接口:
2-1、越界侦测数据接收:数据接受方式,刚开始不清楚上报的数据,事件也没有调试好,没有触发,耽误了很多时间,首先摄像头事件要调试好,事件触发了才能上报数据。上报的数据可先通过断点的方式,接受http请求,断点看下传过来request里面的数据,然后确定接口中需要接受的参数;也可以通过抓包工具抓取接口的数据。
/**
* 越界侦测
* @param lineCrossImage
* @param request
*/
@SneakyThrows
@PostMapping("/httpPush")
public void testWarn(@RequestParam("lineCrossImage") MultipartFile lineCrossImage,HttpServletRequest request){
SysOss sysOss = iSysOssService.upload(lineCrossImage);
log.info("越界侦测-文件:"+sysOss);
Enumeration enumeration = request.getParameterNames();
while(enumeration.hasMoreElements()){
String paraName=(String)enumeration.nextElement();
String abc = request.getParameter(paraName);
System.out.println("参数名:"+paraName+",参数值 :"+abc);
System.out.println("xml转json:" +XML.toJSONObject(abc));
EventNotificationAlertIn eventNotificationAlertIn = objectMapper.readValue(XML.toJSONObject(abc).getStr("EventNotificationAlert"),EventNotificationAlertIn.class);
System.out.println("JSON对象:"+XML.toJSONObject(abc).get("EventNotificationAlert"));
TWarnEventNotification tWarnEventNotification = BeanUtil.copyProperties(eventNotificationAlertIn,TWarnEventNotification.class);
tWarnEventNotification.setDateTime(new Date());
tWarnEventNotification.setUri(sysOss.getUrl());
int count = warnEventNotificationMapper.insert(tWarnEventNotification);
}
RedisUtils.setCacheObject(RedisKeyConstant.WARN_PUSH_NEW_KAY_PERDIX,true);
}
/**
* 越界报警上传数据
*/
@Data
@NoArgsConstructor
@TableName("t_warn_event_notification")
public class EventNotificationAlertIn {
private String ipAddress;
private Integer portNo;
private String protocol;
private String macAddress;
private Integer channelID;
private String dateTime;
private Integer activePostCount;
private String eventType;
private String eventState;
private String eventDescription;
private String channelName;
private Boolean isDataRetransmission;
private String detectionPictureTransType;
}
/**
{
"EventNotificationAlert": {
"dateTime": "2022-05-14T21:44:00+08:00",
"ipAddress": "192.168.18.230",
"eventType": "linedetection",
"detectionPicturesNumber": 1,
"version": 2,
"xmlns": "http://www.hikvision.com/ver20/XMLSchema",
"portNo": 80,
"protocol": "HTTP",
"macAddress": "40:ac:bf:93:05:2c",
"eventState": "active",
"DetectionRegionList": {
"DetectionRegionEntry": {
"RegionCoordinatesList": {
"RegionCoordinates": [
{
"positionX": 550,
"positionY": 998
},
{
"positionX": 695,
"positionY": 12
}
]
},
"TargetRect": {
"X": 629,
"width": 101,
"Y": 195,
"height": 440
},
"sensitivityLevel": 100,
"regionID": 1,
"detectionTarget": "human"
}
},
"eventDescription": "linedetection alarm",
"activePostCount": 1,
"channelName": "taihun_Camera 01",
"isDataRetransmission": false,
"channelID": 1,
"detectionPictureTransType": "binary"
}
}
*/
/**
String alterEnvent = "<EventNotificationAlert version=\"2.0\" xmlns=\"http://www.hikvision.com/ver20/XMLSchema\">\n" +
"<ipAddress>192.168.18.230</ipAddress>\n" +
"<portNo>80</portNo>\n" +
"<protocol>HTTP</protocol>\n" +
"<macAddress>40:c:b:93:5:2c</macAddress>\n" +
"<channelID>1</channelID>\n" +
"<dateTime>2022-05-14T21:44:00+08:00</dateTime>\n" +
"<activePostCount>1</activePostCount>\n" +
"<eventType>linedetection</eventType>\n" +
"<eventState>active</eventState>\n" +
"<eventDescription>linedetection alarm</eventDescription>\n" +
"<DetectionRegionList>\n" +
"<DetectionRegionEntry>\n" +
"<regionID>1</regionID>\n" +
"<sensitivityLevel>100</sensitivityLevel>\n" +
"<RegionCoordinatesList>\n" +
"<RegionCoordinates>\n" +
"<positionX>550</positionX>\n" +
"<positionY>998</positionY>\n" +
"</RegionCoordinates>\n" +
"<RegionCoordinates>\n" +
"<positionX>695</positionX>\n" +
"<positionY>12</positionY>\n" +
"</RegionCoordinates>\n" +
"</RegionCoordinatesList>\n" +
"<detectionTarget>human</detectionTarget>\n" +
"<TargetRect>\n" +
"<X>629</X>\n" +
"<Y>195</Y>\n" +
"<width>101</width>\n" +
"<height>440</height>\n" +
"</TargetRect>\n" +
"</DetectionRegionEntry>\n" +
"</DetectionRegionList>\n" +
"<channelName>taihun_Camera 01</channelName>\n" +
"<detectionPictureTransType>binary</detectionPictureTransType>\n" +
"<detectionPicturesNumber>1</detectionPicturesNumber>\n" +
"<isDataRetransmission>false</isDataRetransmission>\n" +
"</EventNotificationAlert>\n";
*/
2-2、告警服务器http接受数据的接口断点获取上报数据
参数名:linedetection,参数值 :<?xml version="1.0" encoding="UTF-8"?>
<EventNotificationAlert version="2.0" xmlns="http://www.hikvision.com/ver20/XMLSchema">
<ipAddress>192.168.1.230</ipAddress>
<portNo>80</portNo>
<protocol>HTTP</protocol>
<macAddress>40:ac:bf:93:05:7c</macAddress>
<channelID>1</channelID>
<dateTime>2022-05-14T12:29:50+08:00</dateTime>
<activePostCount>1</activePostCount>
<eventType>linedetection</eventType>
<eventState>active</eventState>
<eventDescription>linedetection alarm</eventDescription>
<DetectionRegionList>
<DetectionRegionEntry>
<regionID>1</regionID>
<sensitivityLevel>100</sensitivityLevel>
<RegionCoordinatesList>
<RegionCoordinates>
<positionX>550</positionX>
<positionY>998</positionY>
</RegionCoordinates>
<RegionCoordinates>
<positionX>695</positionX>
<positionY>12</positionY>
</RegionCoordinates>
</RegionCoordinatesList>
<detectionTarget>human</detectionTarget>
<TargetRect>
<X>548</X>
<Y>222</Y>
<width>96</width>
<height>386</height>
</TargetRect>
</DetectionRegionEntry>
</DetectionRegionList>
<channelName>taihun_Camera 01</channelName>
<detectionPictureTransType>binary</detectionPictureTransType>
<detectionPicturesNumber>1</detectionPicturesNumber>
<isDataRetransmission>false</isDataRetransmission>
</EventNotificationAlert>
2-3、通过抓包工具抓起数据WireShark筛选数据,抓取上传告警服务器的接口数据
wireshark抓包工具直接抓取经过网卡的所有网络请求。安装wireshark
选择网卡,双击或者选择捕获分组
筛选post请求:http.request.methodPOST
筛选告警服务器上报接口请求:http.request.uri"/warn/warnAddr/httpPush"
筛选完整路径的请求:http.request.full_uri==“htpp://www.baidu.com/gethikpush”
三、摄像头视频推送和解析
**开箱即用的28181协议视频平台:**https://github.com/648540858/wvp-GB28181-pro
gitee: https://gitee.com/pan648540858/wvp-GB28181-pro
部署文档:https://doc.wvp-pro.cn/#/_content/introduction/deployment
一个基于C++11的高性能运营级流媒体服务框架:
https://github.com/ZLMediaKit/ZLMediaKit