上篇连接:海康威视SDK告警上传功能整合到springboot(一)

上篇的只是兼容Windows系统,此篇写兼容windos和Linux的一个整合

还是下载好sdk,将所需的so文件或者dll文件放在一个确定的目录会在代码和配置文件中用到

比如我,代码同级目录创建了library目录再创建子文件夹 linux 和win

还需创建config文件夹放置application.yml 配置文件 (主要考虑到springboot文件加载顺序)

话不多说直接上代码吧:

接口 IHkSdkInterface

import com.sun.jna.Library;
import com.sun.jna.Structure;
import com.tdt.hiki.service.IMSGCallBackInterface;

/**
 * 为了海康win、Linux的整合写的接口类
 */
public interface IHkSdkInterface extends Library {

    // 初始化sdk
    boolean NET_DVR_Init();

    // 设置连接时间与重连时间
    boolean NET_DVR_SetConnectTime(int i, int i1);

    boolean NET_DVR_SetReconnect(int i, boolean b);

    // 登录接口
    int NET_DVR_Login_V40(HkSdkLinux.NET_DVR_USER_LOGIN_INFO m_strLoginInfo, HkSdkLinux.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo);

    // 获取错误号
    int NET_DVR_GetLastError();

    // 回调服务
    boolean NET_DVR_SetDVRMessageCallBack_V31(IMSGCallBackInterface msgCallBack, Object o);

    // 布防监控
    int NET_DVR_SetupAlarmChan_V41(int lUserID, ISetupAlarmInterface struAlarmParam);

    // 布防撤销
    boolean NET_DVR_CloseAlarmChan_V30(int handle);

    // 退出
    boolean NET_DVR_Logout(int userId);

    // 释放sdk
    boolean NET_DVR_Cleanup();

    //报警设备信息
    public static class NET_DVR_ALARMER extends Structure {
        public byte byUserIDValid;                 /* userid是否有效 0-无效,1-有效 */
        public byte bySerialValid;                 /* 序列号是否有效 0-无效,1-有效 */
        public byte byVersionValid;                /* 版本号是否有效 0-无效,1-有效 */
        public byte byDeviceNameValid;             /* 设备名字是否有效 0-无效,1-有效 */
        public byte byMacAddrValid;                /* MAC地址是否有效 0-无效,1-有效 */
        public byte byLinkPortValid;               /* login端口是否有效 0-无效,1-有效 */
        public byte byDeviceIPValid;               /* 设备IP是否有效 0-无效,1-有效 */
        public byte bySocketIPValid;               /* socket ip是否有效 0-无效,1-有效 */
        public int lUserID;                       /* NET_DVR_Login()返回值, 布防时有效 */
        public byte[] sSerialNumber = new byte[48];    /* 序列号 */
        public int dwDeviceVersion;                /* 版本信息 高16位表示主版本,低16位表示次版本*/
        public byte[] sDeviceName = new byte[32];            /* 设备名字 */
        public byte[] byMacAddr = new byte[6];        /* MAC地址 */
        public short wLinkPort;                     /* link port */
        public byte[] sDeviceIP = new byte[128];                /* IP地址 */
        public byte[] sSocketIP = new byte[128];                /* 报警主动上传时的socket IP地址 */
        public byte byIpProtocol;                  /* Ip协议 0-IPV4, 1-IPV6 */
        public byte[] byRes2 = new byte[11];
    }

    /**
     * 布防参数
     */
    public static class ISetupAlarmInterface extends Structure {

        public int dwSize;
        public byte byLevel; //布防优先级,0-一等级(高),1-二等级(中),2-三等级(低)
        public byte byAlarmInfoType; //上传报警信息类型(抓拍机支持),0-老报警信息(NET_DVR_PLATE_RESULT),1-新报警信息(NET_ITS_PLATE_RESULT)2012-9-28
        public byte byRetAlarmTypeV40; //0--返回NET_DVR_ALARMINFO_V30或NET_DVR_ALARMINFO, 1--设备支持NET_DVR_ALARMINFO_V40则返回NET_DVR_ALARMINFO_V40,不支持则返回NET_DVR_ALARMINFO_V30或NET_DVR_ALARMINFO
        public byte byRetDevInfoVersion; //CVR上传报警信息回调结构体版本号 0-COMM_ALARM_DEVICE, 1-COMM_ALARM_DEVICE_V40
        public byte byRetVQDAlarmType; //VQD报警上传类型,0-上传报报警NET_DVR_VQD_DIAGNOSE_INFO,1-上传报警NET_DVR_VQD_ALARM
        public byte byFaceAlarmDetection;
        public byte bySupport;
        public byte byBrokenNetHttp;
        public short wTaskNo;    //任务处理号 和 (上传数据NET_DVR_VEHICLE_RECOG_RESULT中的字段dwTaskNo对应 同时 下发任务结构 NET_DVR_VEHICLE_RECOG_COND中的字段dwTaskNo对应)
        public byte byDeployType;    //布防类型:0-客户端布防,1-实时布防
        public byte[] byRes1 = new byte[3];
        public byte byAlarmTypeURL;//bit0-表示人脸抓拍报警上传(INTER_FACESNAP_RESULT);0-表示二进制传输,1-表示URL传输(设备支持的情况下,设备支持能力根据具体报警能力集判断,同时设备需要支持URL的相关服务,当前是”云存储“)
        public byte byCustomCtrl;//Bit0- 表示支持副驾驶人脸子图上传: 0-不上传,1-上传,(注:只在公司内部8600/8200等平台开放)

    }
}

Windows sdk 

public interface HCNetSDKI extends IHkSdkInterface, StdCallLibrary {


HCNetSDKI INSTANCE = (HCNetSDKI) Native.loadLibrary(PropertyUtil.getPath() + "HCNetSDK.dll", HCNetSDKI.class);
          ............... 自行复制源sdk代码
}

Linux sdk

public interface HkSdkLinux extends IHkSdkInterface {


    HkSdkLinux INSTANCE = (HkSdkLinux) Native.loadLibrary(PropertyUtil.getPath() + 
"libhcnetsdk.so", HkSdkLinux.class);

    ...... 与windos一样自行复制,类名结构体要区分好
}

 项目启动的时候 要注册摄像头设备信息,登录布放等

InitDevice.java
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
import com.tdt.hiki.service.impl.MSGCallBack;
import com.tdt.hiki.device.Device;
import com.tdt.hiki.device.DeviceAttribute;
import com.tdt.hiki.sdk.HCNetSDKI;
import com.tdt.hiki.sdk.HkSdkLinux;
import com.tdt.hiki.sdk.IHkSdkInterface;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class InitDevice implements CommandLineRunner {


    //private IHkSdkInterface hCNetSDK;// 海康sdk
//    private IMSGCallBackInterface msgCallBack;// 布防监控回调函数

//    @Autowired
//    public MSGCallBack msgCallBack;//报警回调函数实现


    //private static HCNetSDKI hCNetSDK = HCNetSDKI.INSTANCE;
    private static IHkSdkInterface hCNetSDK;

    @Value("${sdkpath}")
    private String sdkpath;
    @Autowired
    private Device devices;


    @Override
    public void run(String... args) throws Exception {


        //在服务启动时注册登录设备

        log.info("-----------服务启动开始-----------");

        //1、初始化sdk
        int sdk = initSdk();
        if(sdk!=0){
            return;
        }
        //2  注册、布防、监听
        List<DeviceAttribute> lists = devices.getLists();
        for (DeviceAttribute device : lists) {
            int logId = deviceRegister(device.getIp(), device.getUsername(), device.getPassword(), device.getPort());
            if (logId < 0) {
                //注册失败
                //hCNetSDK.NET_DVR_Cleanup();
                continue;
            }
            setupAlarmChan(logId,device.getIp());
        }
        log.info("-----------服务启动成功-----------");
    }


    // linux环境下加载组件
    public  void tryLoad() {
        String strPathCom = sdkpath;
        HkSdkLinux.NET_DVR_LOCAL_SDK_PATH struComPath = new HkSdkLinux.NET_DVR_LOCAL_SDK_PATH();
        System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
        struComPath.write();
        HkSdkLinux.INSTANCE.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());

    }

    /**
     * 资源初始化
     *
     * @return
     */
    public int initSdk() {

        if (Platform.isWindows()) {
            log.info("isWindows");
            // windows 注册登录、布防撤防
            hCNetSDK = HCNetSDKI.INSTANCE;

        } else {
            //tryLoad();
            log.info("isLinux");
            // Linux 版本 海康sdk布防
            hCNetSDK = HkSdkLinux.INSTANCE;
        }
        if (!hCNetSDK.NET_DVR_Init()) {
            //初始化失败
            log.info("-----------SDK初始化失败-----------");
            //设置连接时间与重连时间
            hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
            hCNetSDK.NET_DVR_SetReconnect(100000, true);
            return 1;
        } else {
            log.info("-----------SDK初始化成功-----------");
            return 0;
        }
    }

    /**
     * 注销
     *
     * @param lUserID
     */
    public void logout(int lUserID) {
        //注销
        hCNetSDK.NET_DVR_Logout(lUserID);
        //释放SDK资源
        hCNetSDK.NET_DVR_Cleanup();
    }


    /**
     * 设备注册
     *
     * @param ip
     * @param name
     * @param password
     * @return
     */
    public int deviceRegister(String ip, String name, String password, String port) {

        HkSdkLinux.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HkSdkLinux.NET_DVR_USER_LOGIN_INFO();//设备登录信息

        HkSdkLinux.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HkSdkLinux.NET_DVR_DEVICEINFO_V40();//设备信息


        Map<String, Object> map = new HashMap<>();
        //注册之前先注销已注册的用户
//        if (lUserID > -1) {
//            //先注销
//            hCNetSDK.NET_DVR_Logout(lUserID);
//            lUserID = -1;
//        }
        //ip地址

        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDKI.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(ip.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, ip.length());
        //设备用户名

        m_strLoginInfo.sUserName = new byte[HCNetSDKI.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(name.getBytes(), 0, m_strLoginInfo.sUserName, 0, name.length());
        //设备密码

        m_strLoginInfo.sPassword = new byte[HCNetSDKI.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(password.getBytes(), 0, m_strLoginInfo.sPassword, 0, password.length());
        m_strLoginInfo.wPort = (short) Integer.parseInt(port);
        //是否异步登录:0- 否,1- 是
        //m_strLoginInfo.bUseAsynLogin = false;
        m_strLoginInfo.bUseAsynLogin = 1;

        m_strLoginInfo.write();

        //登录
        int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);


        if (lUserID == -1) {
            log.info("-----------[{}] :注册失败,错误号:[{}]-----------", ip, hCNetSDK.NET_DVR_GetLastError());
            return -1;
        } else {
            log.info("-----------[{}] :注册成功-----------", ip);
            map.put(ip, lUserID);
            return lUserID;
        }
    }




    /**
     * 布防
     */
    public void setupAlarmChan(int userId,String ip) {


        Pointer pUser = null;
        //尚未布防,需要布防
        boolean flag = hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(new MSGCallBack(), pUser);


        if (!flag) {
            log.info("-----------设置回调函数失败![{}]-----------", hCNetSDK.NET_DVR_GetLastError());
        }
        //建立报警上传通道(启用布防)
        //布防参数
        IHkSdkInterface.ISetupAlarmInterface m_strAlarmInfo = new HCNetSDKI.ISetupAlarmInterface();
        m_strAlarmInfo.dwSize = m_strAlarmInfo.size();
        //智能交通布防优先级:0- 一等级(高),1- 二等级(中),2- 三等级(低)
        m_strAlarmInfo.byLevel = 1;
        //智能交通报警信息上传类型:0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)
        m_strAlarmInfo.byAlarmInfoType = 1;
        //布防类型(仅针对门禁主机、人证设备):0-客户端布防(会断网续传),1-实时布防(只上传实时数据)
        m_strAlarmInfo.byDeployType = 1;
        m_strAlarmInfo.write();

        int lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(userId, m_strAlarmInfo);
        if (lAlarmHandle == -1) {
            log.info("-----------[{}] :布防失败,错误码[{}]-----------", ip, hCNetSDK.NET_DVR_GetLastError());
            //注销 释放sdk资源
            logout(userId);
        } else {
            log.info("-----------[{}] :布防成功-----------", ip);
        }
    }

}

获取dll或者so文件路径 

import com.sun.jna.Platform;
import lombok.extern.slf4j.Slf4j;
import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

@Slf4j
public class PropertyUtil {


    // private static InputStream isp = PropertyUtil.class.getClassLoader().getResourceAsStream("application.yml");


    public static String getPath() {
        try {
            String outpath = System.getProperty("user.dir") + File.separator + "config" + File.separator;//先读取config目录的,没有再加载classpath的
            Yaml yaml = new Yaml();
            InputStream in = new FileInputStream(new File(outpath + "application.yml"));
            Map map = yaml.load(in);
            String path = (String) map.get("jnapath");
            log.info("path: {}",path);
            return path;
        } catch (IOException e) {
            System.out.println(e.getMessage());
            Yaml yaml = new Yaml();
            InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("application.yml");//默认加载classpath的
            Map map = yaml.load(in);
            String path = (String) map.get("jnapath");
            log.info("defultpath: {}",path);
            return path;
        }
    }

配置文件

server:
  port: 9000

device:
  #添加设备信息 依照以下格式
  lists:
    -
      ip: 192.168.0.64
      username: admin
      password: ******
      port: 8000
#    -
#      ip: 10.22.33.84
#      username: admin
#      password: ad123456
#      port: 8001

#sdk路径
jnapath: D:\library\win\
sdkpath: D:\library\win\

附上一张 成功部署的截图

 

Logo

更多推荐