当前位置:   article > 正文

海康摄像头二次开发详解,包含海康摄像头登录、海康云台控制、视频下载等功能_海康视频录像机截取开发

海康视频录像机截取开发

准备

海康摄像头SDK开发下载路径:

https://www.hikvision.com/cn/download_61.html
  • 1

在这里插入图片描述

下载解压之后的目录结构:
1 中为需要加载的库文件;2中有所需的jar包及HCNetSDK.java文件在这里插入图片描述

开发过程中遇到的问题记录:

  • 一定要记得开启日志打印与及时获取最后一次的错误状态码
  • 一个ip下面会有多个摄像头
  • 如果返回的错误状态码为10:有可能是端口不对,改用8000试试
  • 如果可以登陆却无法控制,有可能是通道错误,有的摄像机通道从1开始,有的从33开始【可通过NET_DVR_GetDVRConfig/NET_DVR_SetDVRConfig来查询和修改相关配置】
  • 查询保存的历史视频的起始时间时:NET_DVR_RECORD_TIME_SPAN_INQUIRY结构体占用内存的大小是68个字节

添加maven依赖

<!--海康录像机二次开发依赖jar包-->
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>3.0.9</version>
</dependency>
<!--海康录像机sdk官方提供jar包-->
<dependency>
    <groupId>com.qy</groupId>
    <artifactId>examples</artifactId><!--需要在maven自行安装这个jar包-->
    <version>1.0.0</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

下面代码中会出现的实体类

CameraManage实体类:

private String deviceIp;
private Integer devicePort;
private String username;
private String password;
  • 1
  • 2
  • 3
  • 4

ControlDto实体类:

private Long controlUserId;//用户id
private Long channel;//通道【有的类型通道从1开始,有的则从33开始,具体看摄像头配置】
private Integer command;//命令
private Integer motionSpeed;//运动速度
private Integer runOrStop;//0启动/1停止
  • 1
  • 2
  • 3
  • 4
  • 5

HCNetSDK.java文件中缺失的部分类/方法

//加载库文件时使用
public static class BYTE_ARRAY extends Structure
    {
        public byte[] byValue;

        public BYTE_ARRAY(int iLen) {
            byValue = new byte[iLen];
        }

        @Override
        protected List<String> getFieldOrder() {
            // TODO Auto-generated method stub
            return Arrays.asList("byValue");
        }
    }

 public static class NET_DVR_RECORD_TIME_SPAN_INQUIRY extends Structure
    {
        public int    dwSize;    //结构体大小
        public byte    byType;    //0 正常音视频录像, 1图片通道录像, 2ANR通道录像, 3抽帧通道录像
        public byte[]     byRes = new byte[63]; //保留
    }
    public static class NET_DVR_RECORD_TIME_SPAN extends Structure
    {
        public int          dwSize;        //结构体大小
        public NET_DVR_TIME  strBeginTime;  //开始时间
        public NET_DVR_TIME  strEndTime;    //结束时间
        public byte          byType;        //0 正常音视频录像, 1图片通道录像, 2ANR通道录像, 3抽帧通道录像
        public byte[]           byRes = new byte[35];     //保留

        @Override
        public String toString() {
            return "NET_DVR_RECORD_TIME_SPAN{" +
                    "dwSize=" + dwSize +
                    ", strBeginTime=" + strBeginTime +
                    ", strEndTime=" + strEndTime +
                    ", byType=" + byType +
                    ", byRes=" + Arrays.toString(byRes) +
                    '}';
        }
    }

    boolean NET_DVR_InquiryRecordTimeSpan(NativeLong lUserID, int dwChannel,  NET_DVR_RECORD_TIME_SPAN_INQUIRY lpInquiry, NET_DVR_RECORD_TIME_SPAN lpResult);

  • 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

加载库文件:

	//修改HCNetSDK.java文件中的加载路径
	//如果是jar包可能找不到jar包中的文件,所以需要单独存放
	HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("此处为linux存放库文件libhcnetsdk.so的路径",HCNetSDK.class);
	hcNetSDK = HCNetSDK.INSTANCE;
	
	//如果某些文件加载不到需要手动加载,加载过程如下
	//设置HCNetSDKCom组件库所在路径
	String strPathCom = "/opt/project/yc/yc-video/HCNetLib";
	HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
	System.out.println(strPathCom.getBytes());
	System.out.println(struComPath.sPath);
	System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
	struComPath.write();
	hcNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
	
	//设置libcrypto.so所在路径
	HCNetSDK.BYTE_ARRAY ptrByteArrayCrypto = new HCNetSDK.BYTE_ARRAY(256);
	String strPathCrypto = "/opt/project/yc/yc-video/HCNetLib/libcrypto.so";
	System.arraycopy(strPathCrypto.getBytes(), 0, ptrByteArrayCrypto.byValue, 0, strPathCrypto.length());
	ptrByteArrayCrypto.write();
	hcNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArrayCrypto.getPointer());
	
	//设置libssl.so所在路径
	HCNetSDK.BYTE_ARRAY ptrByteArraySsl = new HCNetSDK.BYTE_ARRAY(256);
	String strPathSsl = "/opt/project/yc/yc-video/HCNetLib/libssl.so";
	System.arraycopy(strPathSsl.getBytes(), 0, ptrByteArraySsl.byValue, 0, strPathSsl.length());
	ptrByteArraySsl.write();
	hcNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArraySsl.getPointer());
  • 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

初始化:

	//设置连接超时时间及尝试次数
	if (!StringUtils.isEmpty(dwWaitTime) && !StringUtils.isEmpty(dwTryTimes)){
	    boolean b1 = hcNetSDK.NET_DVR_SetConnectTime(Integer.parseInt(dwWaitTime), Integer.parseInt(dwTryTimes));
	}
	
	//开启日志
	hcNetSDK.NET_DVR_SetLogToFile(true,"/logs-video/",true);
	
	//初始化
	boolean initFlag = hcNetSDK.NET_DVR_Init();
	
	if(!initFlag) {
	    return new ResultMoudel(ResultMoudel.ERROR_FLAG,"初始化失败NET_DVR_Init,状态码为"+hcNetSDK.NET_DVR_GetLastError());
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

登录

	//登陆
	HCNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
	NativeLong userId = hcNetSDK.NET_DVR_Login_V30(cameraManage.getDeviceIp(), (short) cameraManage.getDevicePort().shortValue(), cameraManage.getUsername(), cameraManage.getPassword(), deviceInfo);
	
	long lUserId = userId.intValue();
	if(lUserId !=-1 || 4294967295L != lUserId) {
	    Map<String, Long> hashMap = new HashMap<>();
	    hashMap.put("controlUserId",lUserId);
	    hashMap.put("channel",Long.parseLong(cameraManage.getDeviceNumber()) + 32);
	    MAP_USERID_AND_CHANNEL.put(cameraManage.getDeviceIp(), hashMap);
	    return new ResultMoudel(ResultMoudel.SUCCESS_FLAG,hashMap);
	}
	return new ResultMoudel(ResultMoudel.ERROR_FLAG,"登陆失败,状态码为"+hcNetSDK.NET_DVR_GetLastError());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

控制:

	NativeLong channel = new NativeLong(controlDto.getChannel());
	NativeLong controlUserId = new NativeLong(controlDto.getControlUserId());
	boolean b = hcNetSDK.NET_DVR_PTZControlWithSpeed_Other(controlUserId, channel, controlDto.getCommand(), controlDto.getRunOrStop(), controlDto.getMotionSpeed());
	if (b){
	    return new ResultMoudel(ResultMoudel.SUCCESS_FLAG,"正在控制,状态码为"+hcNetSDK.NET_DVR_GetLastError());
	}
	return new ResultMoudel(ResultMoudel.ERROR_FLAG,"控制失败,状态码为"+hcNetSDK.NET_DVR_GetLastError());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

查询历史视频保存时间:

	NativeLong userIdn = new NativeLong(controlUserId);
	HCNetSDK.NET_DVR_RECORD_TIME_SPAN_INQUIRY ipInquiry = new  HCNetSDK.NET_DVR_RECORD_TIME_SPAN_INQUIRY();
	ipInquiry.dwSize = 68;//68为结构体大小
	ipInquiry.byType = 0;
	HCNetSDK.NET_DVR_RECORD_TIME_SPAN ipResult = new HCNetSDK.NET_DVR_RECORD_TIME_SPAN();
	boolean b = hcNetSDK.NET_DVR_InquiryRecordTimeSpan(userIdn, channel, ipInquiry, ipResult);
	//获取开始时间
	HCNetSDK.NET_DVR_TIME strBeginTime = ipResult.strBeginTime;
	//获取结束时间
	HCNetSDK.NET_DVR_TIME strEndTime = ipResult.strEndTime;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

退出登陆释放资源:

//退出登陆
boolean b = hcNetSDK.NET_DVR_Logout(new NativeLong(manageUserId));

//释放资源
boolean b1 = hcNetSDK.NET_DVR_Cleanup();
  • 1
  • 2
  • 3
  • 4
  • 5

完整代码:

public class VideoUtils {

    private static HCNetSDK hcNetSDK;
   // 用于缓存登陆信息,以防止短时间内重复登陆
    private static final Map<String,Map<String,Long>> MAP_USERID_AND_CHANNEL = new HashMap<>();

    //登陆
    public static ResultMoudel login(CameraManage cameraManage){
        //加载所需文件
        ResultMoudel resultMoudel = initHCNetSDK();
        if (ResultMoudel.ERROR_FLAG.equals(resultMoudel.getResultFlag())){
            return resultMoudel;
        }

        if (!StringUtils.isEmpty(cameraManage.getDeviceIp()) && MAP_USERID_AND_CHANNEL.containsKey(cameraManage.getDeviceIp())){
            Map<String, Long> stringLongMap = MAP_USERID_AND_CHANNEL.get(cameraManage.getDeviceIp());
            stringLongMap.put("channel",Long.parseLong(cameraManage.getDeviceNumber()) + 32);
            return  new ResultMoudel(ResultMoudel.SUCCESS_FLAG, stringLongMap);
        }

        //登陆
        HCNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
        NativeLong userId = hcNetSDK.NET_DVR_Login_V30(cameraManage.getDeviceIp(), (short) cameraManage.getDevicePort().shortValue(), cameraManage.getUsername(), cameraManage.getPassword(), deviceInfo);

        long lUserId = userId.intValue();
        if(lUserId !=-1 || 4294967295L != lUserId) {
            Map<String, Long> hashMap = new HashMap<>();
            hashMap.put("controlUserId",lUserId);
            hashMap.put("channel",Long.parseLong(cameraManage.getDeviceNumber()) + 32);
            MAP_USERID_AND_CHANNEL.put(cameraManage.getDeviceIp(), hashMap);
            return new ResultMoudel(ResultMoudel.SUCCESS_FLAG,hashMap);
        }
        return new ResultMoudel(ResultMoudel.ERROR_FLAG,"登陆失败,状态码为"+hcNetSDK.NET_DVR_GetLastError());
    }

    //控制
    public static ResultMoudel commandControl(ControlDto controlDto) {

        NativeLong channel = new NativeLong(controlDto.getChannel());
        NativeLong controlUserId = new NativeLong(controlDto.getControlUserId());
        boolean b = hcNetSDK.NET_DVR_PTZControlWithSpeed_Other(controlUserId, channel, controlDto.getCommand(), controlDto.getRunOrStop(), controlDto.getMotionSpeed());
        if (b){
            return new ResultMoudel(ResultMoudel.SUCCESS_FLAG,"正在控制,状态码为"+hcNetSDK.NET_DVR_GetLastError());
        }
        return new ResultMoudel(ResultMoudel.ERROR_FLAG,"控制失败,状态码为"+hcNetSDK.NET_DVR_GetLastError());
    }

    //退出登陆
    public static ResultMoudel logout(Long manageUserId) {
        //退出登陆
        boolean b = hcNetSDK.NET_DVR_Logout(new NativeLong(manageUserId));

        return null;
    }

    //释放资源
    public static ResultMoudel release() {

        boolean b1 = hcNetSDK.NET_DVR_Cleanup();
        hcNetSDK = null;
        return null;
    }

    //初始化
    private static ResultMoudel initHCNetSDK() {

        if (hcNetSDK == null){
            System.out.println(HCNetSDK.MAX_NAMELEN);
            hcNetSDK = HCNetSDK.INSTANCE;
            //设置HCNetSDKCom组件库所在路径
            String strPathCom = File.separator +"opt"+ File.separator +"project"+ File.separator +"yc-other" + File.separator + "HCNetLib";
            HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
            System.out.println(strPathCom.getBytes());
            System.out.println(struComPath.sPath);
            System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
            struComPath.write();
            hcNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());

            //设置libcrypto.so所在路径
            HCNetSDK.BYTE_ARRAY ptrByteArrayCrypto = new HCNetSDK.BYTE_ARRAY(256);
            String strPathCrypto = File.separator +"opt"+ File.separator +"project"+ File.separator +"yc-other" + File.separator + "HCNetLib" + File.separator+"libcrypto.so";
            System.arraycopy(strPathCrypto.getBytes(), 0, ptrByteArrayCrypto.byValue, 0, strPathCrypto.length());
            ptrByteArrayCrypto.write();
            hcNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArrayCrypto.getPointer());

            //设置libssl.so所在路径
            HCNetSDK.BYTE_ARRAY ptrByteArraySsl = new HCNetSDK.BYTE_ARRAY(256);
            String strPathSsl = File.separator +"opt"+ File.separator +"project"+ File.separator +"yc-other" + File.separator + "HCNetLib" + File.separator+"libssl.so";
            System.arraycopy(strPathSsl.getBytes(), 0, ptrByteArraySsl.byValue, 0, strPathSsl.length());
            ptrByteArraySsl.write();
            hcNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArraySsl.getPointer());


            //开启日志
            hcNetSDK.NET_DVR_SetLogToFile(true,"/logs-video/",true);

            //初始化
            boolean initFlag = hcNetSDK.NET_DVR_Init();

            if(!initFlag) {
                return new ResultMoudel(ResultMoudel.ERROR_FLAG,"初始化失败NET_DVR_Init,状态码为"+hcNetSDK.NET_DVR_GetLastError());
            }

        }
        return new ResultMoudel(ResultMoudel.SUCCESS_FLAG,"初始化成功,状态码为:"+hcNetSDK.NET_DVR_GetLastError());
    }

    //获取历史视频起始时间
    public static List<String> getHistoryVideoMonthlyCalendar(Long controlUserId, Integer channel) {
        NativeLong userIdn = new NativeLong(controlUserId);
        HCNetSDK.NET_DVR_RECORD_TIME_SPAN_INQUIRY ipInquiry = new  HCNetSDK.NET_DVR_RECORD_TIME_SPAN_INQUIRY();
        ipInquiry.dwSize = 68;
        ipInquiry.byType = 0;
        HCNetSDK.NET_DVR_RECORD_TIME_SPAN ipResult = new HCNetSDK.NET_DVR_RECORD_TIME_SPAN();
        boolean b = hcNetSDK.NET_DVR_InquiryRecordTimeSpan(userIdn, channel, ipInquiry, ipResult);
        //获取开始时间
        HCNetSDK.NET_DVR_TIME strBeginTime = ipResult.strBeginTime;
        //获取结束时间
        HCNetSDK.NET_DVR_TIME strEndTime = ipResult.strEndTime;
        //获取起始时间和结束时间
        List<String> strings = bingMonthlyCalendar(strBeginTime, strEndTime);

        return dateList;
    }

    private static List<String> bingMonthlyCalendar(HCNetSDK.NET_DVR_TIME strBeginTime, HCNetSDK.NET_DVR_TIME strEndTime) {
        int yearStart = strBeginTime.dwYear;
        int monthStart = strBeginTime.dwMonth;
        int dayStart = strBeginTime.dwDay;
        int yearEnd = strEndTime.dwYear;
        int monthEnd = strEndTime.dwMonth;
        int dayEnd = strEndTime.dwDay;
        String start = yearStart+"-"+monthStart+"-"+dayStart;
        String end = yearEnd+"-"+monthEnd+"-"+dayEnd;
        List<String> list1 = new ArrayList<>();
        list1.add(start);
        list1.add(end);
        return list1;
    }
}
  • 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

视频下载、回放、视频直播、抓图等功能

视频下载、回放、视频直播、抓图等功能可以参考上述方法并按照开发文档的描述进行开发

如果开发遇到什么问题请留言评论呀。

▄█▀█●各位同仁,如果我的代码对你有帮助,请给我一个赞吧!

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/383175
推荐阅读
相关标签
  

闽ICP备14008679号