Java实现调用海康威视SDK接口抓图

日常开发过程中,会遇到对接视频服务商的需求,一般我们所知的国内大型的视频硬件服务商一个是海康威视,一个是浙江大华,那如何使用java程序来调用对应的接口服务呢?那就是集成SDK

环境

  • java Jdk 1.8
  • Centos 7 64位

hikvision SDK 准备

可以在下面这个链接中下载对应的SDK包:
https://open.hikvision.com/downloadNew/5cda567cf47ae80dd41a54b3?type=10

海康威视下载sdk.jpg

如上图所示:我们可以根据不同的开发环境去下载不同的sdk版本(都选用64位),因为我这边是部署到linux环境所以需要下载linux版本。

SDK 包简介

当我们下载下来后,解压会看到如下的文件夹:


开发文件.jpg

Demo 代码修改

代码中会有这么一个接口文件HCNetSDK 这个是你调用sdk的入口,需要引入so文件
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("/home/adore/hkws/lib/libhcnetsdk.so", HCNetSDK.class);

  • 建议 /home/adore/hkws/lib/libhcnetsdk.so 这个地址就用绝对路径。
  • 部署的话请参考Linux下JavaDemo使用说明

代码编写

代码的调用可以查看接口文档:设备网络SDK使用手册

  • 实现截图功能
/**
     * 抓拍图片
     *
     * @param imgPath     图片路径
     * @param cate        是否走内存
     * @param dvr         用户信息
     * @param channelList 通道
     */
    public void getDVRPic(Device dvr, String imgPath, boolean cate, List channelList) {
        log.info("-----------这里处理已经getDVRPic----------" + imgPath);

        if (!hCNetSDK.NET_DVR_Init()) {
            log.warn("hksdk(抓图)-海康sdk初始化失败!");
            return;
        }
        // 设备信息
        HCNetSDK.NET_DVR_DEVICEINFO_V30 devinfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
        //注册设备
        lUserID = hCNetSDK.NET_DVR_Login_V30(dvr.getIp(), Short.valueOf(dvr.getPort()), dvr.getAccount(), dvr.getPassword(), devinfo);
        // 返回一个用户编号,同时将设备信息写入devinfo
        if (lUserID.intValue() < 0) {
            log.error("hksdk(抓图)-设备注册失败,错误码:" + hCNetSDK.NET_DVR_GetLastError());
            return;
        }
        HCNetSDK.NET_DVR_WORKSTATE_V30 devwork = new HCNetSDK.NET_DVR_WORKSTATE_V30();
        if (!hCNetSDK.NET_DVR_GetDVRWorkState_V30(lUserID, devwork)) {
            // 返回Boolean值,判断是否获取设备能力
            log.error("hksdk(抓图)-返回设备状态失败" + hCNetSDK.NET_DVR_GetLastError());
        }
        if (CollectionUtils.isEmpty(channelList)) {
            log.error("通道数据为空" + dvr.getIp());
            return;
        }
        channelList.forEach(x -> {
            String path = "";
            path = imgPath + "-" + x + ".jpeg";
            NativeLong chanLong = new NativeLong(x);
            //内存
            if (cate) {
                picCutCate(lUserID, chanLong, path);
            } else {
                //非内存直接保存
                //图片质量
                HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA();
                //设置图片分辨率
                jpeg.wPicSize = 0;
                //设置图片质量
                jpeg.wPicQuality = 0;
                //需要加入通道
                log.info("-----------这里开始封装 NET_DVR_CaptureJPEGPicture---------");
                boolean is = hCNetSDK.NET_DVR_CaptureJPEGPicture(lUserID, chanLong, jpeg, path);
                log.info("-----------抓图工具返回结果----------" + is);
                if (!is) {
                    log.info("hksdk(抓图)-抓取失败,错误码:" + hCNetSDK.NET_DVR_GetLastError());
                }
            }
        });
        log.info("-----------处理完成截图数据----------");
        //退出登录
        hCNetSDK.NET_DVR_Logout(lUserID);
        //释放SDK资源
        hCNetSDK.NET_DVR_Cleanup();
    }


    private void picCutCate(NativeLong lUserID, NativeLong chanLong, String imgPath) {
        //图片质量
        HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA();
        //设置图片分辨率
        jpeg.wPicSize = 0;
        //设置图片质量
        jpeg.wPicQuality = 0;
        IntByReference a = new IntByReference();
        //设置图片大小
        ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
        File file = new File(imgPath);
        // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
        log.info("-----------这里开始封装 NET_DVR_CaptureJPEGPicture_NEW---------");
        boolean is = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(lUserID, chanLong, jpeg, jpegBuffer, 1024 * 1024, a);
        log.info("-----------这里开始图片存入内存----------" + is);
        if (is) {
            /**
             * 该方式使用内存获取 但是读取有问题无法预览
             * linux下 可能有问题
             * */
            log.info("hksdk(抓图)-结果状态值(0表示成功):" + hCNetSDK.NET_DVR_GetLastError());
            //存储到本地
            BufferedOutputStream outputStream = null;
            try {
                outputStream = new BufferedOutputStream(new FileOutputStream(file));
                outputStream.write(jpegBuffer.array(), 0, a.getValue());
                outputStream.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else {
            log.info("hksdk(抓图)-抓取失败,错误码:" + hCNetSDK.NET_DVR_GetLastError());
        }
    }

特别说明:
如果使用的是内存方式截图(linux)下则需要修改SDK接口如下:

    boolean NET_DVR_CaptureJPEGPicture_NEW(NativeLong lUserID, NativeLong lChannel, NET_DVR_JPEGPARA lpJpegPara, ByteBuffer jpegBuffer, int dwPicSize, IntByReference lpSizeReturned);

将String buffer 改为 ByteBuffer jpegBuffer,

Device 对象说明

/**
     * device.getAccount() 获取设备的访问账号
     * device.getPassword() 获取设备的访问密码
     * device.getIp() 获取设备所在内网的IP地址
     * device.getPort() 获取设备的访问端口 rtsp默认554
     */

    private String account;
    private String password;
    private String ip;
    private String port;
    private Long channel;

注意工具类需要使用是用静态调用HCNetSDK

private static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;

以上就是在linux下调用海康威视SDK实现抓图功能

主要的难点可能就是如何部署查看sdk中的部署文档就可以

你可能感兴趣的:(Java实现调用海康威视SDK接口抓图)