‘liusuyi’
2023-07-05 1fd64b07ddb99c2d9cc8a358b71aceb6a2c81492
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
package com.ard.utils.hiksdk.service.impl;
 
import com.alibaba.fastjson2.JSON;
import com.ard.alarm.camera.domain.ArdCameras;
import com.ard.alarm.camera.domain.CameraCmd;
import com.ard.alarm.camera.service.impl.ArdCamerasServiceImpl;
import com.ard.config.MinioClientSingleton;
import com.ard.utils.hiksdk.common.GlobalVariable;
import com.ard.utils.hiksdk.domain.alarmEventInfo;
import com.ard.utils.hiksdk.util.hikSdkUtil.HCNetSDK;
import com.ard.utils.hiksdk.util.minio.MinioUtils;
import com.ard.utils.DateUtils;
import com.ard.utils.SpringTool;
import com.ard.utils.mqtt.MqttConsumer;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
 
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
 
/**
 * @ClassName: FMSGCallBack
 * @Description:
 * @Author: Administrator
 * @Date: 2023年02月15日 12:16
 * @Version: 1.0
 **/
@Slf4j(topic = "hiksdk")
public class FMSGCallBack implements HCNetSDK.FMSGCallBack_V31 {
 
    /**
     * 报警信息回调函数
     *
     * @param lCommand   上传消息类型
     * @param pAlarmer   报警设备信息
     * @param pAlarmInfo 报警信息
     * @param dwBufLen   报警信息缓存大小
     * @param pUser      用户数据
     */
    @Override
    public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        ArdCamerasServiceImpl ardCamerasService = SpringTool.getApplicationContext().getBean(ArdCamerasServiceImpl.class);
 
        String sTime;//事件时间
        String url;//事件图片
        alarmEventInfo info;//事件信息
        //lCommand是传的报警类型
        switch (lCommand) {
            case HCNetSDK.COMM_ALARM_RULE:
                //region 行为分析信息
                log.info("报警事件类型:lCommand:" + Integer.toHexString(lCommand));
                HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm = new HCNetSDK.NET_VCA_RULE_ALARM();
                strVcaAlarm.write();
                Pointer pVCAInfo = strVcaAlarm.getPointer();
                pVCAInfo.write(0, pAlarmInfo.getByteArray(0, strVcaAlarm.size()), 0, strVcaAlarm.size());
                strVcaAlarm.read();
                Integer ruleID =  Integer.valueOf(strVcaAlarm.struRuleInfo.byRuleID);
                sTime = DateUtils.parseTime(strVcaAlarm.dwAbsTime);//事件时间
                String ipaddr = new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4).trim();//设备ip
                Integer channel = Integer.valueOf(strVcaAlarm.struDevInfo.byChannel);//通道
                ArdCameras ardCameras = new ArdCameras();
                ardCameras.setIp(ipaddr);
                ArdCameras ardcamere = ardCamerasService.selectArdCamerasList(ardCameras).get(0);
                info = new alarmEventInfo();
                info.setAlarmName("人员行为分析");
                info.setAlarmTime(sTime);
                info.setCameraName(ardcamere.getName());
                info.setCameraId(ardcamere.getId());
                info.setCameraIp(ipaddr);
                info.setCameraType(ardcamere.getGdtype());
                info.setCameraChannel(channel);
                info.setLongitude(ardcamere.getLongitude());
                info.setLatitude(ardcamere.getLatitude());
                info.setAlarmType(ardcamere.getGdtype());
                info.setRuleId(ruleID);
                switch (strVcaAlarm.struRuleInfo.wEventTypeEx) {
                    case 1: //region穿越警戒面 (越界侦测)
                        info.setAlarmType("越界侦测报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_TRAVERSE_PLANE.class);
                        //endregion
                        break;
                    case 2: //region 目标进入区域
                        info.setAlarmType("目标进入区域报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
                        //endregion
                        break;
                    case 3: //region 目标离开区域
                        info.setAlarmType("目标离开区域报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
                        //endregion
                        break;
                    case 4: //region 周界入侵
                        info.setAlarmType("周界入侵报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_INTRUSION.class);
                        //endregion
                        break;
                    case 5: //region 徘徊
                        info.setAlarmType("徘徊事件报警");
                        //endregion
                        break;
                    case 8: //region 快速移动(奔跑)
                        info.setAlarmType("快速移动(奔跑)事件报警");
                        //endregion
                        break;
                    case 13: //region 物品遗留事件
                        info.setAlarmType("物品遗留事件报警");
                        //endregion
                        break;
                    case 14: //region 物品拿取事件
                        info.setAlarmType("物品拿取事件事件报警");
                        //endregion
                        break;
                    case 20: //region 倒地检测
                        info.setAlarmType("倒地事件触发");
                        //endregion
                        break;
                    case 44: //region 玩手机
                        info.setAlarmType("玩手机报警事件");
                        //endregion
                        break;
                    default:
                        log.info("未知行为事件类型:" + strVcaAlarm.struRuleInfo.wEventTypeEx);
                        printLog(info);
                        break;
                }
                //endregion
                //图片存入minio
                url = savePicture(info);
                info.setPicUrl(url);
                publishMqtt(info);
                break;
            case HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT:
                log.info("人脸检测事件上报");
                break;
            case HCNetSDK.COMM_GISINFO_UPLOAD:
                log.info("GPS报警信息上报");
                break;
            default:
                log.info("未知报警事件类型:lCommand:" + Integer.toHexString(lCommand));
                break;
 
        }
        return true;
    }
 
    /**
     * @描述 保存图片封装方法
     * @参数 [strVcaAlarm, eventName, eventNameEng]
     * @返回值 java.lang.String
     * @创建人 刘苏义
     * @创建时间 2023/2/17 15:05
     * @修改人和其它信息
     */
    private String savePicture(HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm, String eventName, String eventNameEng) {
        String url = "";
        if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
            String currentTime = new SimpleDateFormat("yyyyMMdd").format(new Date());
            try {
                //存入minio
                long offset = 0;
                ByteBuffer buffers = strVcaAlarm.pImage.getByteBuffer(offset, strVcaAlarm.dwPicDataLen);
                byte[] bytes = new byte[strVcaAlarm.dwPicDataLen];
                buffers.rewind();
                buffers.get(bytes);
                InputStream inputStream = new ByteArrayInputStream(bytes);
                String ipaddr = new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4).trim();//设备ip
                String UUID = java.util.UUID.randomUUID().toString().replace("-", "");
                String filename = ipaddr + "/" + currentTime + "/" + eventNameEng + "/" + UUID + ".jpg";
                boolean uploadRes = MinioUtils.uploadObject("pic", filename, inputStream, inputStream.available(), "image/jpeg");
                if (uploadRes) {
                    url = MinioClientSingleton.domainUrl + filename;
                    log.info("写入minio图片地址:" + url);
                }
            } catch (Exception ex) {
                log.error(eventName + "处理图片异常:" + ex.getMessage());
            }
        }
        return url;
    }
 
    /**
     * 打保存图片
     */
    private String savePicture(alarmEventInfo info) {
        CameraCmd cmd = new CameraCmd();
        ArdCameras Cameras = GlobalVariable.cameraMap.get(info.getCameraIp());
        cmd.setCameraId(Cameras.getId());
        cmd.setChannelNum(info.getCameraChannel());
        cmd.setBucketName("pic");
        String UUID = java.util.UUID.randomUUID().toString().replace("-", "");
        String filename = info.getCameraName() + "/" + info.getAlarmType() + "/" + UUID + ".jpg";
        cmd.setObjectName(filename);
        String url = HikClientUtil.picCutCate(cmd);
        return url;
    }
 
    /**
     * 打印日志
     */
    private void printLog(alarmEventInfo info) {
        log.info("【规则】" + info.getAlarmName() +"【规则id】" + info.getRuleId() + "【类型】" + info.getAlarmType() +
                "【时间】" + info.getAlarmTime() + "【相机id】" + info.getCameraId() + "【相机】" + info.getCameraName() +
                "【IP】" + info.getCameraIp() + "【通道】" + info.getCameraChannel() +"【型号】" + info.getCameraType() +
                "【图片】" + info.getPicUrl() + "【坐标】" + info.getLongitude() + "," + info.getLatitude());
    }
    /**
     * 推送mqtt
     */
    private void publishMqtt(alarmEventInfo info) {
       // printLog(info);
        MqttConsumer.publish(2, false, "camera", JSON.toJSONString(info));
    }
}