springboot 对接海康设备

1 篇文章 0 订阅

springboot 对接海康设备

  1. 新建接口HCNetSDK
import com.stian.util.ClientDemoUtil;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;

import com.sun.jna.examples.win32.W32API;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;

import java.nio.ByteBuffer;

public interface HCNetSDK extends StdCallLibrary {

   HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(ClientDemoUtil.DLL_PATH+"HCNetSDK.dll", HCNetSDK.class);

    public static final int SERIALNO_LEN = 48;   //序列号长度
    public static final int NAME_LEN = 32;    //用户名长度
    public static final int PASSWD_LEN = 16;    //密码长度
    public static final int MAX_DISKNUM_V30 = 33;		//9000设备最大硬盘数/* 最多33个硬盘(包括16个内置SATA硬盘、1个eSATA硬盘和16个NFS盘) */
    public static final int MAX_AUDIO_V30 = 2;   //9000语音对讲通道数
    public static final int MAX_LINK = 6;    //8000设备单通道最大视频流连接数

    //9000 IPC接入
    public static final int MAX_ANALOG_CHANNUM = 32;    //最大32个模拟通道
    public static final int MAX_ANALOG_ALARMOUT = 32;    //最大32路模拟报警输出
    public static final int MAX_ANALOG_ALARMIN = 32;    //最大32路模拟报警输入
    public static final int MAX_IP_DEVICE = 32;    //允许接入的最大IP设备数
    public static final int MAX_IP_CHANNEL = 32;   //允许加入的最多IP通道数
    public static final int MAX_IP_ALARMIN = 128;   //允许加入的最多报警输入数
    public static final int MAX_IP_ALARMOUT = 64; //允许加入的最多报警输出数
    /* 最大支持的通道数 最大模拟加上最大IP支持 */
    public static final int MAX_CHANNUM_V30 = (MAX_ANALOG_CHANNUM + MAX_IP_CHANNEL);//64
    public static final int MAX_ALARMOUT_V30 = (MAX_ANALOG_ALARMOUT + MAX_IP_ALARMOUT);//96
    public static final int MAX_ALARMIN_V30 = (MAX_ANALOG_ALARMIN + MAX_IP_ALARMIN);//160

    //IP接入配置参数 (NET_DVR_IPPARACFG结构)
    public static final int NET_DVR_GET_IPPARACFG = 1048;    //获取IP接入配置信息
    public static final int NET_DVR_SET_IPPARACFG = 1049;    //设置IP接入配置信息

    /********************预览回调函数*********************/
    public static final int NET_DVR_SYSHEAD = 1;//系统头数据
    public static final int NET_DVR_STREAMDATA = 2;//视频流数据(包括复合流和音视频分开的视频流数据)
    public static final int NET_DVR_AUDIOSTREAMDATA = 3;//音频流数据
    public static final int NET_DVR_STD_VIDEODATA = 4;//标准视频流数据
    public static final int NET_DVR_STD_AUDIODATA = 5;//标准音频流数据



    //NET_DVR_Login_V30()参数结构
    public static class NET_DVR_DEVICEINFO_V30 extends Structure{
        public  byte[] sSerialNumber = new byte[SERIALNO_LEN];  //序列号
        public  byte byAlarmInPortNum;		        //报警输入个数
        public  byte byAlarmOutPortNum;		        //报警输出个数
        public  byte byDiskNum;				    //硬盘个数
        public  byte byDVRType;				    //设备类型, 1:DVR 2:ATM DVR 3:DVS ......
        public  byte byChanNum;				    //模拟通道个数
        public  byte byStartChan;			        //起始通道号,例如DVS-1,DVR - 1
        public  byte byAudioChanNum;                //语音通道数
        public  byte byIPChanNum;					//最大数字通道个数
        public  byte[] byRes1 = new byte[24];					//保留
    }

    boolean  NET_DVR_Logout_V30(NativeLong lUserID);




    public static class NET_DVR_IPPARACFG extends Structure {/* IP接入配置结构 */
        public  int dwSize;			                            /* 结构大小 */
        public  NET_DVR_IPDEVINFO[]  struIPDevInfo = new NET_DVR_IPDEVINFO[MAX_IP_DEVICE];    /* IP设备 */
        public   byte[] byAnalogChanEnable = new byte[MAX_ANALOG_CHANNUM];        /* 模拟通道是否启用,从低到高表示1-32通道,0表示无效 1有效 */
        public NET_DVR_IPCHANINFO[] struIPChanInfo = new NET_DVR_IPCHANINFO[MAX_IP_CHANNEL];	/* IP通道 */
    }

    //IPC接入参数配置
    public static class NET_DVR_IPDEVINFO extends Structure {/* IP设备结构 */
        public   int dwEnable;				    /* 该IP设备是否启用 */
        public   byte[] sUserName = new byte[NAME_LEN];		/* 用户名 */
        public   byte[] sPassword = new byte[PASSWD_LEN];	    /* 密码 */
        public   NET_DVR_IPADDR struIP = new NET_DVR_IPADDR();			/* IP地址 */
        public   short wDVRPort;			 	    /* 端口号 */
        public   byte[] byres = new byte[34];				/* 保留 */
    }

    public static class NET_DVR_IPCHANINFO extends Structure {/* IP通道匹配参数 */
        public   byte byEnable;					/* 该通道是否启用 */
        public  byte byIPID;					/* IP设备ID 取值1- MAX_IP_DEVICE */
        public  byte byChannel;					/* 通道号 */
        public   byte[] byres = new byte[33];					/* 保留 */
    }

    public static class NET_DVR_IPADDR extends Structure {
        public byte[] sIpV4 = new byte[16];
        public byte[] byRes = new byte[128];

        public String toString() {
            return "NET_DVR_IPADDR.sIpV4: " + new String(sIpV4) + "\n" + "NET_DVR_IPADDR.byRes: " + new String(byRes) + "\n";
        }
    }



    //初始化SDK,调用其他SDK函数的前提。
    boolean NET_DVR_Init();

    //设置连接时间与重连时间
    boolean  NET_DVR_SetConnectTime(int dwWaitTime, int dwTryTimes );
    boolean  NET_DVR_SetReconnect(int dwInterval, boolean bEnableRecon );

    int  NET_DVR_GetLastError();

    NativeLong  NET_DVR_Login_V30(String sDVRIP, short wDVRPort, String sUserName, String sPassword, NET_DVR_DEVICEINFO_V30 lpDeviceInfo);


    public static class NET_DVR_WORKSTATE_V30 extends Structure {//DVR工作状态(9000扩展)
        public int dwDeviceStatic; 	//设备的状态,0-正常,1-CPU占用率太高,超过85%,2-硬件错误,例如串口死掉
        public NET_DVR_DISKSTATE[]  struHardDiskStatic = new NET_DVR_DISKSTATE[MAX_DISKNUM_V30];
        public NET_DVR_CHANNELSTATE_V30[] struChanStatic = new NET_DVR_CHANNELSTATE_V30[MAX_CHANNUM_V30];//通道的状态
        public byte[]  byAlarmInStatic = new byte[MAX_ALARMIN_V30]; //报警端口的状态,0-没有报警,1-有报警
        public byte[]  byAlarmOutStatic = new byte[MAX_ALARMOUT_V30]; //报警输出端口的状态,0-没有输出,1-有报警输出
        public int  dwLocalDisplay;//本地显示状态,0-正常,1-不正常
        public  byte [] byAudioChanStatus = new byte[MAX_AUDIO_V30];//表示语音通道的状态 0-未使用,1-使用中, 0xff无效
        public  byte[]  byRes = new byte[10];
    }

    public static class NET_DVR_DISKSTATE extends Structure {//硬盘状态
        public int dwVolume;//硬盘的容量
        public int dwFreeSpace;//硬盘的剩余空间
        public int dwHardDiskStatic; //硬盘的状态,按位:1-休眠,2-不正常,3-休眠硬盘出错
    }

    public static class NET_DVR_CHANNELSTATE_V30 extends Structure {//通道状态(9000扩展)
        public byte byRecordStatic; //通道是否在录像,0-不录像,1-录像
        public byte bySignalStatic; //连接的信号状态,0-正常,1-信号丢失
        public byte byHardwareStatic;//通道硬件状态,0-正常,1-异常,例如DSP死掉
        public byte reservedData;		//保留
        public int dwBitRate;//实际码率
        public int dwLinkNum;//客户端连接的个数
        public NET_DVR_IPADDR[] struClientIP = new NET_DVR_IPADDR[MAX_LINK];//客户端的IP地址
        public  int dwIPLinkNum;//如果该通道为IP接入,那么表示IP接入当前的连接数
        public  byte[] byRes = new byte[12];
    }

    boolean  NET_DVR_GetDVRWorkState_V30(NativeLong lUserID, NET_DVR_WORKSTATE_V30 lpWorkState);
    boolean  NET_DVR_GetDVRConfig(NativeLong lUserID, int dwCommand, NativeLong lChannel, Pointer lpOutBuffer, int dwOutBufferSize, IntByReference lpBytesReturned);

    boolean  NET_DVR_Logout(NativeLong lUserID);
    boolean  NET_DVR_Cleanup();


    //软解码预览参数
    public static class NET_DVR_CLIENTINFO extends Structure {
        public NativeLong lChannel;
        public NativeLong lLinkMode;
        public W32API.HWND hPlayWnd;
        public String sMultiCastIP;
    }

    /***API函数声明,详细说明见API手册***/
    public static interface FRealDataCallBack_V30 extends StdCallCallback {
        public void invoke(NativeLong lRealHandle, int dwDataType,
                           ByteByReference pBuffer, int dwBufSize, Pointer pUser);
    }

    NativeLong  NET_DVR_RealPlay_V30(NativeLong lUserID, NET_DVR_CLIENTINFO lpClientInfo, FRealDataCallBack_V30 fRealDataCallBack_V30, Pointer pUser , boolean bBlocked );

    boolean  NET_DVR_SaveRealData(NativeLong lRealHandle,String sFileName);
    boolean  NET_DVR_StopRealPlay(NativeLong lRealHandle);



    //--------------------
//图片质量
    public static class NET_DVR_JPEGPARA extends Structure {
        /*注意:当图像压缩分辨率为VGA时,支持0=CIF, 1=QCIF, 2=D1抓图,
        当分辨率为3=UXGA(1600x1200), 4=SVGA(800x600), 5=HD720p(1280x720),6=VGA,7=XVGA, 8=HD900p
        仅支持当前分辨率的抓图*/
        public short	wPicSize;				/* 0=CIF, 1=QCIF, 2=D1 3=UXGA(1600x1200), 4=SVGA(800x600), 5=HD720p(1280x720),6=VGA*/
        public short	wPicQuality;			/* 图片质量系数 0-最好 1-较好 2-一般 */
    }

    //JPEG抓图到内存
    boolean  NET_DVR_CaptureJPEGPicture_NEW(NativeLong lUserID, NativeLong lChannel, NET_DVR_JPEGPARA lpJpegPara, ByteBuffer sJpegPicBuffer, int dwPicSize, IntByReference lpSizeReturned);

    //NET_DVR_SetDVRMessage的扩展
    boolean  NET_DVR_SetExceptionCallBack_V30(int nMessage, int hWnd, FExceptionCallBack fExceptionCallBack, Pointer pUser);
    public static interface FExceptionCallBack extends StdCallCallback {
        public void invoke(int dwType, NativeLong lUserID, NativeLong lHandle, Pointer pUser);
    }
}
  1. 工具类ClientDemoUtil
import com.stian.sdks.ClientDemo;

import java.io.UnsupportedEncodingException;

public class ClientDemoUtil {

    public static String DLL_PATH;

    static{
        String path=(ClientDemo.class.getResource("/sdk/").getPath()).replaceAll("%20", " ").substring(1).replace("/", "\\");
        try {
            DLL_PATH= java.net.URLDecoder.decode(path,"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

}
  1. 新建类TestHikvision
@Configuration
public class TestHikvision {

    static HCNetSDK sdk = HCNetSDK.INSTANCE;


    /**
     *  注册设备并返回参数
     *  目的:   注册设备并返回key    :Nativelong
     * @param cameraInfo
     * @return
     */
    private Camera getParameter(Camera cameraInfo) {
        //设置设备通道号   查看Demo代码  通道号为1
        NativeLong channel = new NativeLong(1);
        cameraInfo.setChannel(channel);
        if (!sdk.NET_DVR_Init()) {
            System.out.println("初始化失败..................");
        }

        //创建设备
        HCNetSDK.NET_DVR_DEVICEINFO_V30 deInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();

        //注册用户设备
        NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getPort(),
                cameraInfo.getUserName(), cameraInfo.getUserPwd(), deInfo);
        cameraInfo.setUserId(id);
        return cameraInfo;
    }


    /**
     * 获取当前相机的信息 传入连接信息对象
     * 目的:获取到实时视频存入指定文件中 保存为.jpg格式文件
     * @param cameraInfo
     */
    public void getDVRConfig(Camera cameraInfo) {
        //判断摄像头是否开启
        if (!sdk.NET_DVR_Init()) {
            return;
        }
        //创建设备  设备信息
        HCNetSDK.NET_DVR_DEVICEINFO_V30 deInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();

        //登录信息
        NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getPort(),
                cameraInfo.getUserName(), cameraInfo.getUserPwd(), deInfo);
        cameraInfo.setUserId(id);// 返回一个用户编号,同时将设备信息写入devinfo

        //输出int数据
        if (cameraInfo.getUserId().intValue() < 0) {
            System.out.println("设备注册失败"+sdk.NET_DVR_GetLastError());
            return;
        }
        //DVR工作状态
        HCNetSDK.NET_DVR_WORKSTATE_V30 devwork = new HCNetSDK.NET_DVR_WORKSTATE_V30();
        if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devwork)) {
            // 返回Boolean值,判断是否获取设备能力
            System.out.println("返回设备状态失败");
        }

        IntByReference ibrBytesReturned = new IntByReference(0);// 获取IP接入配置参数
        HCNetSDK.NET_DVR_IPPARACFG ipcfg = new HCNetSDK.NET_DVR_IPPARACFG();//IP接入配置结构
        ipcfg.write();
        Pointer lpIpParaConfig = ipcfg.getPointer();
        //获取相关参数配置
        sdk.NET_DVR_GetDVRConfig(cameraInfo.getUserId(), HCNetSDK.NET_DVR_GET_IPPARACFG, new NativeLong(0),
                lpIpParaConfig, ipcfg.size(), ibrBytesReturned);
        ipcfg.read();
        System.out.print("IP地址:" + cameraInfo.getCameraIp());
        System.out.println("|设备状态:" + devwork.dwDeviceStatic);// 0正常,1CPU占用率过高,2硬件错误,3未知
        // 显示模拟通道
        for (int i = 0; i < deInfo.byChanNum; i++) {
            System.out.print("Camera" + i + 1);// 模拟通道号名称
            System.out.print("|是否录像:" + devwork.struChanStatic[i].byRecordStatic);// 0不录像,不录像
            System.out.print("|信号状态:" + devwork.struChanStatic[i].bySignalStatic);// 0正常,1信号丢失
            System.out.println("|硬件状态:" + devwork.struChanStatic[i].byHardwareStatic);// 0正常,1异常
        }
        //注销用户
        sdk.NET_DVR_Logout(cameraInfo.getUserId());//释放SDK资源
        sdk.NET_DVR_Cleanup();
    }

    //抓拍图片
    public void getDVRPic(Camera cameraInfo){
        Camera parameter = getParameter(cameraInfo);
        if (parameter.getUserId().intValue() < 0) {
            System.out.println("设备注册失败"+sdk.NET_DVR_GetLastError());
            return;
        } else {
            System.out.println("id:" + parameter.getUserId().intValue());
        }
        //判断是否获取到设备能力    //设备工作状态信息结构体。
        HCNetSDK.NET_DVR_WORKSTATE_V30 devwork = new HCNetSDK.NET_DVR_WORKSTATE_V30();
        if (!sdk.NET_DVR_GetDVRWorkState_V30(parameter.getUserId(), devwork)) {
            // 返回Boolean值,判断是否获取设备能力
            System.out.println("返回设备状态失败");
        }
        //图片质量
        HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA();
        // 设置图片的分辨率
        jpeg.wPicSize = 2;
        // 设置图片质量
        jpeg.wPicQuality = 2;

        IntByReference a = new IntByReference();
        //设置图片大小
        ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
        //创建文件目录和文件
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date();
        //按照每天设置一个目录
        String fileName = parameter.getPath();
        File files = new File(fileName);
        if(!files.exists()){
            files.mkdirs();
        }
        if (files.isDirectory()){
            String[] imgNumber = files.list();
            if (imgNumber.length == 50){
                A:for (int i = 0; i < imgNumber.length; i++) {
                    try {
                        Path path = Paths.get(fileName+imgNumber[i]);
                        BasicFileAttributeView basicview= Files.getFileAttributeView(path, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS );
                        BasicFileAttributes attr = basicview.readAttributes();
                        Date createDate = new Date(attr.creationTime().toMillis()); //文件创建时间
                        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        deleteFile(fileName+imgNumber[0]); //删除该文件夹下的第一个文件
                        System.out.println(imgNumber[i]+"--------"+sdf1.format(createDate));
                        break A;
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        }
        //按照日期文件夹放入图片
        String fileNameString = fileName+"/"+sdf.format(date)+".jpg";
        File file = new File(fileNameString);
        // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
        //需要加入通道   //NET_DVR_CaptureJPEGPicture_NEW
        boolean is = sdk.NET_DVR_CaptureJPEGPicture_NEW(parameter.getUserId(), parameter.getChannel(), jpeg,
                jpegBuffer, 1024 * 1024, a);  //1024*1024  当前抓拍的分辨率

        if (is) {
            System.out.println("抓取成功,返回长度:" + a.getValue());
        } else {
            System.out.println("抓取失败:"+sdk.NET_DVR_GetLastError());
        }
        BufferedOutputStream outputStream = null;
        try {
            outputStream = new BufferedOutputStream(new FileOutputStream(file));
            outputStream.write(jpegBuffer.array(), 0, a.getValue());
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //单个图片路径:fileNameString
       //做自己的操作

        sdk.NET_DVR_Logout(parameter.getUserId());
        sdk.NET_DVR_Cleanup();
    }


    public void getImages() throws IOException {
        ICameraService cameraService = (ICameraService) ApplicationContextUtil.getBean("cameraService");
        QueryWrapper<Camera> queryWrapper = new QueryWrapper<>();
 queryWrapper.select("id","camera_ip","port","user_name","user_pwd","path","create_time");
        List<Camera> cameraList = cameraService.list(queryWrapper);
        TestHikvision testHikvision = new TestHikvision();
        if (cameraList != null){
            for (Camera c : cameraList) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        testHikvision.getDVRConfig(c);
                        testHikvision.getDVRPic(c);
                    }
                }).start();

            }
        }
    }

    /**
     * 每隔500毫秒执行一次
     */
    @Scheduled(fixedRate = 500)
    public void test1(){
        try {
            this.getImages();
        }catch (IOException e){
            e.printStackTrace();
        }

    }


    /**
     * 删除单个文件
     *
     * @param fileName
     *            要删除的文件的文件名
     * @return 单个文件删除成功返回true,否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                System.out.println("删除单个文件" + fileName + "成功!");
                return true;
            } else {
                System.out.println("删除单个文件" + fileName + "失败!");
                return false;
            }
        } else {
            System.out.println("删除单个文件失败:" + fileName + "不存在!");
            return false;
        }
    }


}
  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SpringBoot海康SDK的结合可以实现对海康设备的操作,包括控制摄像头转动、抓取图像等功能。在使用SpringBoot操作海康SDK时,需要引入对应版本的海康SDK和JNA库,并在项目中进行初始化设置。 具体步骤如下: 1. 新建SpringBoot项目,并设置版本为2.5.3。 2. 在项目的pom.xml文件中添加依赖,包括jna和fastjson2。例如: ```xml <dependency> <groupId>com.sun.jna</groupId> <artifactId>jna</artifactId> <version>3.0.9</version> </dependency> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.20</version> </dependency> ``` 3. 将下载的海康SDK放到项目目录中,并根据操作系统的不同创建相应的文件夹。 4. 如果在项目中出现HCNetSDK.NET_DVR_PREVIEWINFO.HWND找不到引用的问题,可以进行如下处理: - 在Project Structure中引入官方示例代码中的examples.jar。 - 将HWND类型修改为int类型。 接下来,根据需要调用海康SDK提供的业务接口来实现对海康设备的控制。可以参考SDK提供的示例代码和文档进行开发和集成。 总结起来,使用SpringBoot操作海康SDK需要在项目中引入对应的依赖,将海康SDK文件放置在项目目录中,并进行初始化设置。然后,根据SDK提供的文档和示例代码进行开发和集成。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [springboot操作海康SDK windows](https://download.csdn.net/download/bohuashan/12917326)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [SpringBoot集成海康网络设备SDK](https://blog.csdn.net/u014655403/article/details/131675985)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值