houzhongjian
2024-11-14 08b6a55a3a111aaee9842999b85afa60b6d61dc3
iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/video/hikvision/utils/HIKDevice.java
@@ -1,5 +1,9 @@
package com.iailab.module.data.video.hikvision.utils;
import com.alibaba.fastjson.JSONException;
import com.iailab.module.data.video.config.VideoConfiguration;
import com.iailab.module.data.video.dto.CameraDTO;
import com.iailab.module.data.video.enums.CameraStatusEnum;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
@@ -8,41 +12,43 @@
import javax.annotation.PreDestroy;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Component
public class HIKDevice {
   // 接口的实例,通过接口实例调用外部dll/so的函数
   public static HCNetSDK hCNetSDK = null;
    // 接口的实例,通过接口实例调用外部dll/so的函数
    public static HCNetSDK hCNetSDK = null;
    // 用户登录返回句柄
    public static int lUserID;
    public static int lUserID;
    //构造函数
    public HIKDevice(){
       if (hCNetSDK == null) {
    public HIKDevice() {
        if (hCNetSDK == null) {
            synchronized (HCNetSDK.class) {
                try {
                   if (Platform.isWindows()) {
                     hCNetSDK = (HCNetSDK) Native.loadLibrary(MessageCode.HIK_WIN_PATH, HCNetSDK.class);
                  }
                  if (Platform.isLinux()) {
                     hCNetSDK = (HCNetSDK) Native.loadLibrary(MessageCode.HIK_LINUX_PATH, HCNetSDK.class);
                  }
                    if (Platform.isWindows()) {
                        hCNetSDK = (HCNetSDK) Native.loadLibrary(MessageCode.HIK_WIN_PATH, HCNetSDK.class);
                    }
                    if (Platform.isLinux()) {
                        hCNetSDK = (HCNetSDK) Native.loadLibrary(MessageCode.HIK_LINUX_PATH, HCNetSDK.class);
                    }
                } catch (Exception ex) {
                    log.error("SdkInitService-init-hCNetSDK-error");
                }
            }
        }
    }
   /**
    * 初始化资源配置
    */
   public int initDevices(){
      System.out.println("进入构造函数");
    /**
     * 初始化资源配置
     */
    public int initDevices() {
        System.out.println("进入构造函数");
        // 初始化SDK
        boolean initSuc = hCNetSDK.NET_DVR_Init();
        if (initSuc != true) {
@@ -52,180 +58,154 @@
        // 设置连接时间与重连时间
        hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
        System.out.println("初始化SDK资源完成");
      return 0;
   }
        return 0;
    }
    //销毁函数
    @PreDestroy
    public void destroy() throws Exception {
        hCNetSDK.NET_DVR_Cleanup();
    }
    /*
       * 功能:登录设备
       * 参数:
       *      deviceIP-设备局域网IP地址
       *      devicePort-设备SDK服务端口
       *      userName-用户名
       *      passWord-密码
       * */
//   public String loginDevice() throws JSONException {
//      if (!getDeviceStatus()) {
//         int init = initDevices();
//         if (init == 1) {
//            return "初始化失败";
//         }
//         ArrayList<String> list = mZnfxCodeService.getDriverInfo("driverinfo");
//         if (list != null && list.size() > 0) {
//            String driverip = list.get(0);
//            String driverport = list.get(1);
//            String username = list.get(2);
//            String password = list.get(3);
//            String returnVal = Login_V40(driverip, Short.parseShort(driverport), username, password);
//            System.out.println(returnVal);
//            return returnVal;
//         } else {
//            return "获取设备信息失败!";
//         }
//      }
//      else
//      {
//         String result = captureJPEGPicture();
//         System.out.println(result);
//         return result;
//      }
//
//   }
     * 功能:登录设备
     * 参数:
     *      deviceIP-设备局域网IP地址
     *      devicePort-设备SDK服务端口
     *      userName-用户名
     *      passWord-密码
     * */
    public String loginDevice(CameraDTO camera) throws JSONException {
        if (!getDeviceStatus(camera.getId())) {
            int init = initDevices();
            if (init == 1) {
                return "初始化失败";
            }
            String driverip = camera.getIp();
            String driverport = camera.getPort();
            String username = camera.getUsername();
            String password = camera.getPassword();
            String returnVal = Login_V40(driverip, Short.parseShort(driverport), username, password, camera);
            System.out.println(returnVal);
            return returnVal;
        } else {
            String result = captureJPEGPicture(camera);
            System.out.println(result);
            return result;
        }
    }
    /**
    *
    * @param m_sDeviceIP 设备ip地址
    * @param wPort       端口号,设备网络SDK登录默认端口8000
    * @param m_sUsername 用户名
    * @param m_sPassword 密码
    */
   public String Login_V40(String m_sDeviceIP,short wPort,String m_sUsername,String m_sPassword) {
       /* 注册 */
       // 设备登录信息
       HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
     * @param m_sDeviceIP 设备ip地址
     * @param wPort       端口号,设备网络SDK登录默认端口8000
     * @param m_sUsername 用户名
     * @param m_sPassword 密码
     */
    public String Login_V40(String m_sDeviceIP, short wPort, String m_sUsername, String m_sPassword, CameraDTO camera) {
        /* 注册 */
        // 设备登录信息
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
       // 设备信息
       HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
       m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
       System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
       m_strLoginInfo.wPort =wPort ;
       m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
       System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
       m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
       System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
       // 是否异步登录:false- 否,true- 是
       m_strLoginInfo.bUseAsynLogin = false;
       // write()调用后数据才写入到内存中
       m_strLoginInfo.write();
        // 设备信息
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
        m_strLoginInfo.wPort = wPort;
        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
        // 是否异步登录:false- 否,true- 是
        m_strLoginInfo.bUseAsynLogin = false;
        // write()调用后数据才写入到内存中
        m_strLoginInfo.write();
       lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
       if (lUserID == -1) {
//          updateZnfxPostalStatus(PostalStatus.ABNORMAL.value());
//          mZnfxPostalStatusService.changeStatus(MessageCode.POSTAL_STATUS_TYPE_CAMERA, PostalStatus.ABNORMAL.value());
           System.out.println("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
           return "登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError();
       } else {
           System.out.println("登录成功!");
           // read()后,结构体中才有对应的数据
           m_strDeviceInfo.read();
//           updateZnfxPostalStatus(PostalStatus.NORMAL.value());
//           mZnfxPostalStatusService.changeStatus(MessageCode.POSTAL_STATUS_TYPE_CAMERA, PostalStatus.NORMAL.value());
            String result = captureJPEGPicture();
           return result;
       }
   }
   //注销设备
    public String logoutDevice()
    {
        NativeLong nlUserID = new NativeLong(lUserID);
        if (!hCNetSDK.NET_DVR_Logout(nlUserID))
        {
            System.out.println("注销失败,设备ID:"+ nlUserID.intValue() + "错误码:"+hCNetSDK.NET_DVR_GetLastError());
            return "{\"result\":\"loginDevice Fail\",\"userID\":"+nlUserID.intValue()+",\"errorCode\":"+hCNetSDK.NET_DVR_GetLastError()+"}";
        }else{
            System.out.println("注销成功,设备ID:"+ nlUserID.intValue());
            return "{\"result\":\"logoutDevice Success\",\"userID\":"+nlUserID.intValue()+",\"errorCode\":0}";
        lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        if (lUserID == -1) {
            VideoConfiguration.staticCameraService.setStatus(camera.getId(), CameraStatusEnum.OFFLINE.getCode());
            System.out.println("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
            return "登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError();
        } else {
            System.out.println("登录成功!");
            // read()后,结构体中才有对应的数据
            m_strDeviceInfo.read();
            VideoConfiguration.staticCameraService.setStatus(camera.getId(), CameraStatusEnum.ONLIEN.getCode());
            String result = captureJPEGPicture(camera);
            return result;
        }
    }
   /**
    * 设备抓图(无预览)
    * 单帧设备抓取保存的图片为JPG,具体注意问题需要详细查看【设备网络sdk使用手册】
    * @return
    */
   public String captureJPEGPicture()
   {
//         ArrayList<String> list = mZnfxCodeService.getDriverInfo("driverpic");
         List<String> list = new ArrayList<>();
         list.add("tlChannel");
         list.add("tlPicSize");
         list.add("tlPicQuality");
             if (list != null && list.size() > 0) {
               int tlChannel = Integer.parseInt(list.get(0));
               int tlPicSize = Integer.parseInt(list.get(1));
               int tlPicQuality = Integer.parseInt(list.get(2));
               NativeLong nlUserID = new NativeLong(lUserID);
               NativeLong nChannel = new NativeLong(tlChannel);
               HCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new HCNetSDK.NET_DVR_JPEGPARA();
               lpJpegPara.wPicSize = (short)tlPicSize;
               lpJpegPara.wPicQuality = (short)tlPicQuality;
               // 参数必须写入到结构体,否则在保存图片的时候异常图片
               lpJpegPara.write();
               String tFiledirName = CommonUtils.getCurrDate();//yyyyMMdd
               // 创建文件名称
               String tDatePath = MessageCode.DvrPicSavePath+"/"+tFiledirName;
               // 判断文件夹是否创建
               File tFile = new File(tDatePath);
               if (!tFile.exists()){
                  tFile.mkdirs();
               }
               String tDate = CommonUtils.getCurrDate2();//yyyyMMddHHmmss
               // 文件名称
               String tImageName = tDate  +".png";
               // 全路径
               String tPath = tDatePath+"/"+tImageName;
               // 开始抓图
               if (!hCNetSDK.NET_DVR_CaptureJPEGPicture(nlUserID, nChannel, lpJpegPara, tPath))
               {
                  return "失败编码:"+hCNetSDK.NET_DVR_GetLastError() ;
               }else {
                  Long tImageId = CommonUtils.Getnum();//生成流水号
//                  saveZnfxImageInfo(tFiledirName,tImageName,tPath,tImageId);
    //注销设备
    public String logoutDevice() {
        NativeLong nlUserID = new NativeLong(lUserID);
        if (!hCNetSDK.NET_DVR_Logout(nlUserID)) {
            System.out.println("注销失败,设备ID:" + nlUserID.intValue() + "错误码:" + hCNetSDK.NET_DVR_GetLastError());
            return "{\"result\":\"loginDevice Fail\",\"userID\":" + nlUserID.intValue() + ",\"errorCode\":" + hCNetSDK.NET_DVR_GetLastError() + "}";
        } else {
            System.out.println("注销成功,设备ID:" + nlUserID.intValue());
            return "{\"result\":\"logoutDevice Success\",\"userID\":" + nlUserID.intValue() + ",\"errorCode\":0}";
        }
    }
                  return "success>>>>>>>>>>>" + tImageName;
               }
             }
             else
             {
                return "login fail>>>>>>>>>>>";
             }
   }
   /**
     * 检查设备是否在线
    /**
     * 设备抓图(无预览)
     * 单帧设备抓取保存的图片为JPG,具体注意问题需要详细查看【设备网络sdk使用手册】
     *
     * @return
     */
   private boolean getDeviceStatus() {
      boolean isOnLine = hCNetSDK.NET_DVR_RemoteControl(lUserID, 20005, null, 0);
//      if (!isOnLine) {
////         updateZnfxPostalStatus(PostalStatus.ABNORMAL.value()); //离线
////         insertZnfxPostalStatusLog(PostalStatus.ABNORMAL.value());
//         mZnfxPostalStatusService.changeStatus(MessageCode.POSTAL_STATUS_TYPE_CAMERA, PostalStatus.ABNORMAL.value());
//         return false;
//      } else {
//         mZnfxPostalStatusService.changeStatus(MessageCode.POSTAL_STATUS_TYPE_CAMERA, PostalStatus.NORMAL.value());
////         updateZnfxPostalStatus(PostalStatus.NORMAL.value());//在线
//      }
      return true;
   }
    public String captureJPEGPicture(CameraDTO camera) {
        int tlChannel = camera.getChannel();
        String tlPicSize = VideoConfiguration.staticPicSize;
        String tlPicQuality = VideoConfiguration.staticPicQuality;
        NativeLong nlUserID = new NativeLong(lUserID);
        NativeLong nChannel = new NativeLong(tlChannel);
        HCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new HCNetSDK.NET_DVR_JPEGPARA();
        lpJpegPara.wPicSize = Short.parseShort(tlPicSize);
        lpJpegPara.wPicQuality = Short.parseShort(tlPicQuality);
        // 参数必须写入到结构体,否则在保存图片的时候异常图片
        lpJpegPara.write();
        String tFilename = CommonUtils.getCurrDate();//yyyyMMdd
        // 创建文件名称
        String tDatePath = VideoConfiguration.staticHkCapturePath + tFilename;
        // 判断文件夹是否创建
        File tFile = new File(tDatePath);
        if (!tFile.exists()) {
            tFile.mkdirs();
        }
        String tDate = CommonUtils.getCurrDate2();//yyyyMMddHHmmss
        // 文件名称
        String tImageName = tDate + ".png";
        // 全路径
        String tPath = tDatePath + "/" + tImageName;
        // 开始抓图
        if (!hCNetSDK.NET_DVR_CaptureJPEGPicture(nlUserID, nChannel, lpJpegPara, tPath)) {
            return "失败编码:" + hCNetSDK.NET_DVR_GetLastError();
        } else {
            Map<String, String> params = new HashMap<>();
            params.put("strFileName", tPath);
            params.put("cmdSerial", camera.getCode());
            params.put("brand", "HK");
            VideoConfiguration.staticCameraService.dealCapture(params);
            return "success>>>>>>>>>>>" + tImageName;
        }
    }
    /**
     * 检查设备是否在线
     *
     * @return
     */
    private boolean getDeviceStatus(String id) {
        boolean isOnLine = hCNetSDK.NET_DVR_RemoteControl(lUserID, 20005, null, 0);
      if (!isOnLine) {
            VideoConfiguration.staticCameraService.setStatus(id, CameraStatusEnum.OFFLINE.getCode());
         return false;
      } else {
            VideoConfiguration.staticCameraService.setStatus(id, CameraStatusEnum.ONLIEN.getCode());
      }
        return true;
    }
//   /**
//    * 更新摄像头通讯状态
//    * @param status