使用海康威视SDK在Java中截取录像机回放片段的具体步骤(Windows64位)

引言

在项目推进过程中,我们团队深入客户现场进行开发作业,其中一项关键任务是与海康威视录像机进行数据交互,精准获取其内部的片段数据,以此为基石推动后续业务的顺利开展。接下来,就和大家分享一下这一实操过程中的宝贵经验,希望能为同行们提供有益的参考。

环境准备

1.确保您有最新版本的海康威视网络SDK

访问海康威视官方网站下载:

前往 https://www.hikvision.com/cn/ (中国大陆用户)或 https://www.hikvision.com/ (国际用户)

2.需要将以下DLL文件复制到项目根目录

HCNetSDK.dll
HCCore.dll
整个HCNetSDKCom文件夹(保持原名)
libssl-1_1.dll
libcrypto-1_1.dll
hlog.dll
hpr.dll
zlib1.dll
PlayCtrl.dll
SuperRender.dll
AudioRender.dll
GdiPlus.dll
HmMerge.dll
HXVA.dll
libmmd.dll
MP_Render.dll
NPQos.dll
OpenAL32.dll
YUVProcess.dll

2.1 DLL文件的工作原理

  • 在程序运行时,当需要调用 DLL 文件中的功能时,操作系统会将 DLL 文件加载到内存中。多个应用程序可以共享同一个 DLL 文件,这使得内存的利用更加高效。例如,有多个软件都需要进行图像解码操作,它们就可以共享一个包含图像解码功能的 DLL 文件,而不是每个软件都自带一份解码代码。

  • DLL 文件采用模块化的设计。开发人员可以将程序的不同功能部分分别编写成不同的 DLL 文件。这样,在程序更新或维护时,只需要更新对应的 DLL 文件,而不用重新编译整个程序,大大提高了软件维护的效率。

3.添加JNA依赖

在您的Java项目中添加JNA的依赖。这可以通过以下几种方式实现:

  • 如果您使用Maven,可以在pom.xml文件中添加以下依赖:
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.6.0</version>
</dependency>
  • 如果您使用Gradle,可以在build.gradle文件中添加:
dependencies {
    implementation 'net.java.dev.jna:jna:5.6.0'
}
  • ·如果您不使用构建工具,您可以手动下载jna.jar文件并添加到项目的classpath中。您可以从Maven中央仓库下载: https://repo1.maven.org/maven2/net/java/dev/jna/jna/

代码案例

1.导入CommonUtil工具类

这个工具类的主要作用是将海康威视SDK中使用的特殊时间日期格式解析为可读的字符串格式

public class CommonUtil {
    //SDK时间解析
    public static String parseTime(int time)
    {
        int dwYear=(time>>26)+2000;
        int dwMonth=(time>>22)&15;
        int dwDay=(time>>17)&31;
        int dwHour=(time>>12)&31;
        int dwMinute=(time>>6)&63;
        int dwSecond=(time>>0)&63;
        
        String sTime = String.format("%04d", dwYear) +
                String.format("%02d", dwMonth) +
                String.format("%02d", dwDay) +
                String.format("%02d", dwHour) +
                String.format("%02d", dwMinute) +
                String.format("%02d", dwSecond);
        return sTime;
    }
}

2.导入NCNetSDK.java

HCNetSDK是一个用于与海康威视设备进行通信的开发包,提供了一组API接口,开发者可以通过这些接口实现与设备的连接、视频预览、视频录制、报警处理等功能

点击链接即可下载HCNetSDK.java

3.截取录像机回放片段的具体代码

主要功能和流程
  1. 初始化SDK和播放控制实例

  2. 设置异常回调和SDK日志

  3. 登录设备

  4. 执行特定操作(在这个例子中是按时间下载录像)

  5. 注销设备并清理SDK资源

需要修改的地方

1.DLL文件路径: 修改 strDllPath strPlayPath 为您系统中实际的DLL文件路径。

2.设备登录信息: 在 main 方法中,修改 loginDevice 方法的参数

lUserID = loginDevice("192.168.xxx.xxx", (short) 8000, "xxxxxx", "xxxxxx");

将IP地址、端口、用户名和密码改为您实际设备的信息。

3.下载录像的通道号:

main 方法中,修改 dowmloadRecordByTime 方法的第二个参数(通道号):

new VideoDemo().dowmloadRecordByTime(lUserID, 33);

将IP地址、端口、用户名和密码改为您实际设备的信息。

import com.sun.jna.Native;
import com.sun.jna.Pointer;

import java.util.Scanner;
import java.util.Timer;

public class ClientDemo {

    int iErr = 0; // 用于存储错误代码
    static HCNetSDK hCNetSDK = null; // 海康威视SDK的实例
    static PlayCtrl playControl = null; // 播放控制实例
    static int lUserID = -1; // 用户句柄,初始化为-1表示未登录
    static int lDChannel;  // 预览通道号
    static int lPlayHandle = -1;  // 预览句柄,初始化为-1表示未开始预览
    static boolean bSaveHandle = false; // 保存句柄的标志
    Timer Playbacktimer; // 回放用定时器
    static FExceptionCallBack_Imp fExceptionCallBack; // 异常回调函数实例
    static int FlowHandle; // 流程句柄

    // 定义异常回调函数的实现类
    static class FExceptionCallBack_Imp implements HCNetSDK.FExceptionCallBack {
        public void invoke(int dwType, int lUserID, int lHandle, Pointer pUser) {
            System.out.println("异常事件类型:" + dwType);
            return;
        }
    }

    // 创建SDK实例的方法
    private static boolean createSDKInstance() {
        if (hCNetSDK == null) {
            synchronized (HCNetSDK.class) {
                String strDllPath = "";
                try {
                    // 指定DLL文件的路径
                    strDllPath = "C:\\Users\\xiongwenhao\\CientDemo\\HCNetSDK.dll";
                    try {
                        // 加载DLL文件
                        hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
                    } catch (Exception ex) {
                        System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
                    }
                } catch (Exception ex) {
                    System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
                    return false;
                }
            }
        }
        return true;
    }

    // 创建播放控制实例的方法
    private static boolean createPlayInstance() {
        if (playControl == null) {
            synchronized (PlayCtrl.class) {
                String strPlayPath = "";
                try {
                    // 指定播放控制DLL文件的路径
                    strPlayPath = "C:\\Users\\xiongwenhao\\CientDemo\\HCNetSDK.dll";
                    try {
                        // 加载播放控制DLL文件
                        hCNetSDK = (HCNetSDK) Native.loadLibrary(strPlayPath, HCNetSDK.class);
                    } catch (Exception ex) {
                        System.out.println("loadLibrary: " + strPlayPath + " Error: " + ex.getMessage());
                    }
                } catch (Exception ex) {
                    System.out.println("loadLibrary: " + strPlayPath + " Error: " + ex.getMessage());
                    return false;
                }
            }
        }
        return true;
    }

    public static void main(String[] args) throws InterruptedException {
        // 检查并创建SDK和播放控制实例
        if (hCNetSDK == null && playControl == null) {
            if (!createSDKInstance()) {
                System.out.println("Load SDK fail");
                return;
            }
            if (!createPlayInstance()) {
                System.out.println("Load PlayCtrl fail");
                return;
            }
        }

        // 初始化SDK
        boolean initSuc = hCNetSDK.NET_DVR_Init();

        // 设置异常回调
        if (fExceptionCallBack == null) {
            fExceptionCallBack = new FExceptionCallBack_Imp();
        }
        Pointer pUser = null;
        if (!hCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, 0, fExceptionCallBack, pUser)) {
            return;
        }
        System.out.println("设置异常消息回调成功");

        // 设置SDK日志
        hCNetSDK.NET_DVR_SetLogToFile(3, "./sdkLog", false);

        // 登录设备
        lUserID = loginDevice("192.168.xxx.xxx", (short) 8000, "xxxxxx", "xxxxxx");

        System.out.println("[Module]按时间下载录像");
        new VideoDemo().dowmloadRecordByTime(lUserID, 33);

        // 注销设备
        if (hCNetSDK.NET_DVR_Logout(lUserID)) {
            System.out.println("注销成功");
        }

        // 清理SDK资源
        hCNetSDK.NET_DVR_Cleanup();
    }

    // 登录设备的方法
    public static int loginDevice(String ip, short port, String user, String psw) {
        // 创建登录信息和设备信息对象
        HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
        HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();

        // 设置设备IP地址
        byte[] deviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        byte[] ipBytes = ip.getBytes();
        System.arraycopy(ipBytes, 0, deviceAddress, 0, Math.min(ipBytes.length, deviceAddress.length));
        loginInfo.sDeviceAddress = deviceAddress;

        // 设置用户名和密码
        byte[] userName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        byte[] password = psw.getBytes();
        System.arraycopy(user.getBytes(), 0, userName, 0, Math.min(user.length(), userName.length));
        System.arraycopy(password, 0, loginInfo.sPassword, 0, Math.min(password.length, loginInfo.sPassword.length));
        loginInfo.sUserName = userName;

        // 设置端口和登录模式
        loginInfo.wPort = port;
        loginInfo.bUseAsynLogin = false; // 同步登录
        loginInfo.byLoginMode = 0; // 使用SDK私有协议

        // 执行登录操作
        int userID = hCNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo);
        if (userID == -1) {
            System.err.println("登录失败,错误码为: " + hCNetSDK.NET_DVR_GetLastError());
        } else {
            System.out.println(ip + " 设备登录成功!");
            // 处理通道号逻辑
            int startDChan = deviceInfo.struDeviceV30.byStartDChan;
            System.out.println("预览起始通道号: " + startDChan);
        }
        return userID; // 返回登录结果
    }
}

海康威视SDK常见错误码

错误码宏定义描述
0NET_DVR_NOERROR没有错误
1NET_DVR_PASSWORD_ERROR用户名密码错误
2NET_DVR_NOENOUGHPRI权限不足
3NET_DVR_NOINITSDK未初始化
4NET_DVR_CHANNEL_ERROR通道号错误
5NET_DVR_OVER_MAXLINK连接到的设备端口超出最大数
6NET_DVR_VERSIONNOMATCH版本不匹配
7NET_DVR_NETWORK_FAIL_CONNECT连接服务器失败
8NET_DVR_NETWORK_SEND_ERROR向服务器发送失败
9NET_DVR_NETWORK_RECV_ERROR从服务器接收数据失败
10NET_DVR_NETWORK_RECV_TIMEOUT从服务器接收数据超时
11NET_DVR_NETWORK_ERRORDATA传送的数据有误
12NET_DVR_ORDER_ERROR调用次序错误
13NET_DVR_OPERNOPERMIT无此权限
14NET_DVR_COMMANDTIMEOUT设备命令执行超时
15NET_DVR_ERRORSERIALPORT串口号错误
16NET_DVR_ERRORALARMPORT报警端口错误
17NET_DVR_PARAMETER_ERROR参数错误
18NET_DVR_CHAN_EXCEPTION设备通道处于错误状态
19NET_DVR_NODISK设备无硬盘
20NET_DVR_ERRORDISKNUM硬盘号错误
21NET_DVR_DISK_FULL设备硬盘满
22NET_DVR_DISK_ERROR设备硬盘出错
23NET_DVR_NOSUPPORT设备不支持的操作
24NET_DVR_BUSY设备忙
25NET_DVR_MODIFY_FAIL设备修改不成功
26NET_DVR_PASSWORD_FORMAT_ERROR密码输入格式不正确
27NET_DVR_DISK_FORMATING硬盘正在格式化,不能启动操作
28NET_DVR_DVRNORESOURCE设备资源不足
29NET_DVR_DVROPRATEFAILED设备操作失败
30NET_DVR_OPENHOSTSOUND_FAIL打开PC声音失败
31NET_DVR_DVRVOICEOPENED设备语音对讲被占用
32NET_DVR_TIMEINPUTERROR时间输入不正确
33NET_DVR_NOSPECFILE回放时服务器没有指定的文件
34NET_DVR_CREATEFILE_ERROR创建文件出错
35NET_DVR_FILEOPENFAIL打开文件出错
36NET_DVR_OPERNOTFINISH上次的操作还没有完成
37NET_DVR_GETPLAYTIMEFAIL获取当前播放的时间出错
38NET_DVR_PLAYFAIL播放出错
39NET_DVR_FILEFORMAT_ERROR文件格式不正确
40NET_DVR_DIR_ERROR路径错误
41NET_DVR_ALLOC_RESOURCE_ERROR资源分配错误
42NET_DVR_AUDIO_MODE_ERROR声卡模式错误
43NET_DVR_NOENOUGH_BUF缓冲区太小
44NET_DVR_CREATESOCKET_ERROR创建SOCKET出错
45NET_DVR_SETSOCKET_ERROR设置SOCKET出错
46NET_DVR_MAX_NUM个数达到最大
47NET_DVR_USERNOTEXIST用户不存在
48NET_DVR_WRITEFLASHERROR写FLASH出错
49NET_DVR_UPGRADEFAIL设备升级失败
50NET_DVR_CARDHAVEINIT解码卡已经初始化过
51NET_DVR_PLAYERFAILED调用播放库中某个函数失败
52NET_DVR_MAX_USERNUM设备端用户数达到最大
53NET_DVR_GETLOCALIPANDMACFAIL获得客户端的IP地址或物理地址失败
54NET_DVR_NOENCODEING该通道没有编码
55NET_DVR_IPMISMATCHIP地址不匹配
56NET_DVR_MACMISMATCHMAC地址不匹配
57NET_DVR_UPGRADELANGMISMATCH升级文件语言不匹配
58NET_DVR_MAX_PLAYERPORT播放器路数达到最大
59NET_DVR_NOSPACEBACKUP备份设备中没有足够空间进行备份
60NET_DVR_NODEVICEBACKUP没有找到指定的备份设备
61NET_DVR_PICTURE_BITS_ERROR图像素位数不符,限24色
62NET_DVR_PICTURE_DIMENSION_ERROR图片高宽超限, 限128256
63NET_DVR_PICTURE_SIZ_ERROR图片大小超限,限100K
64NET_DVR_LOADPLAYERSDKFAILED载入当前目录下Player Sdk出错
65NET_DVR_LOADPLAYERSDKPROC_ERROR找不到Player Sdk中某个函数入口
66NET_DVR_LOADDSSDKFAILED载入当前目录下DSsdk出错
67NET_DVR_LOADDSSDKPROC_ERROR找不到DsSdk中某个函数入口
68NET_DVR_DSSDK_ERROR调用硬解码库DsSdk中某个函数失败
69NET_DVR_VOICEMONOPOLIZE声卡被独占
70NET_DVR_JOINMULTICASTFAILED加入多播组失败
71NET_DVR_CREATEDIR_ERROR建立日志文件目录失败
72NET_DVR_BINDSOCKET_ERROR绑定套接字失败
73NET_DVR_SOCKETCLOSE_ERRORsocket连接中断,此错误通常是由于连接中断或内存状态错误
74NET_DVR_USERID_ISUSING注销时用户ID正在进行某操作
75NET_DVR_SOCKETLISTEN_ERROR监听失败
76NET_DVR_PROGRAM_EXCEPTION程序异常
77NET_DVR_WRITEFILE_FAILED写文件失败
78NET_DVR_FORMAT_READONLY禁止格式化只读硬盘
79NET_DVR_WITHSAMEUSERNAME用户配置结构中存在相同的用户名
80NET_DVR_DEVICETYPE_ERROR导入参数时设备型号不匹配
81NET_DVR_LANGUAGE_ERROR导入参数时语言不匹配
82NET_DVR_PARAVERSION_ERROR导入参数时软件版本不匹配
83NET_DVR_IPCHAN_NOTALIVE预览时外接IP通道不在线
84NET_DVR_RTSP_SDK_ERROR加载高清IPC通讯库StreamTransClient.dll失败
85NET_DVR_CONVERT_SDK_ERROR加载转码库失败
86NET_DVR_IPC_COUNT_OVERFLOW超出最大的IP接入通道数
87NET_PLAYM4_NOERROR没有错误
88NET_PLAYM4_PARA_OVER输入参数非法
89NET_PLAYM4_ORDER_ERROR调用顺序不对
90NET_PLAYM4_TIMER_ERROR多媒体时钟设置失败
91NET_PLAYM4_DEC_VIDEO_ERROR视频解码失败
92NET_PLAYM4_DEC_AUDIO_ERROR音频解码失败
93NET_PLAYM4_ALLOC_MEMORY_ERROR分配内存失败
94NET_PLAYM4_OPEN_FILE_ERROR文件操作失败
95NET_PLAYM4_CREATE_OBJ_ERROR创建线程事件等失败
96NET_PLAYM4_CREATE_DDRAW_ERROR创建DirectDraw对象失败
97NET_PLAYM4_CREATE_OFFSCREEN_ERROR创建后备缓存失败
98NET_PLAYM4_BUF_OVER缓冲区满,输入流失败
99NET_PLAYM4_CREATE_SOUND_ERROR创建音频设备失败
100NET_PLAYM4_SET_VOLUME_ERROR设置音量失败
101NET_PLAYM4_SUPPORT_FILE_ONLY只能在播放文件时才能使用此函数
102NET_PLAYM4_SUPPORT_STREAM_ONLY只能在播放流时才能使用此函数
103NET_PLAYM4_SYS_NOT_SUPPORT系统不支持,解码器可能不支持
104NET_PLAYM4_FILEHEADER_UNKNOWN没有文件头
105NET_PLAYM4_VERSION_INCORRECT解码器和编码器版本不对应
106NET_PALYM4_INIT_DECODER_ERROR初始化解码器失败
107NET_PLAYM4_CHECK_FILE_ERROR文件太短或码流无法识别
108NET_PLAYM4_INIT_TIMER_ERROR初始化多媒体时钟失败
109NET_PLAYM4_BLT_ERROR位拷贝失败
110NET_PLAYM4_UPDATE_ERROR显示overlay失败
111NET_PLAYM4_OPEN_FILE_ERROR_MULTI打开文件错误,音视频数据不匹配
112NET_PLAYM4_OPEN_FILE_ERROR_VIDEO打开文件错误,脱音频数据不存在
113NET_PLAYM4_JPEG_COMPRESS_ERRORJPEG压缩错误
114NET_PLAYM4_EXTRACT_NOT_SUPPORT不支持该文件版本
115NET_PLAYM4_EXTRACT_DATA_ERROR提取文件数据失败
116NET_PLAYM4_SECRET_KEY_ERROR解密密钥错误
117NET_PLAYM4_DECRYPT_ERROR解密错误
118NET_PLAYM4_RENDER_LOCK_ERROR渲染库资源锁定失败
119NET_PLAYM4_DEC_REPORT_UNSUPPORT解码器不支持的功能
120NET_PLAYM4_DEC_VIDEO_ERROR_MULTI多路解码时,某路解码失败
121NET_PLAYM4_INVALID_PORT无效的端口号
122NET_PLAYM4_NOT_FIND查找失败
123NET_PLAYM4_NEED_MORE_DATA需要更多的数据才能解析
124NET_PLAYM4_INVALID_MAIN_HANDLE无效的句柄
125NET_PLAYM4_INVALID_HANDLE无效的句柄
126NET_PLAYM4_INVALID_PARA无效的参数
127NET_PLAYM4_INVALID_FORMAT无效的文件格式

结语

通过以上的详细介绍,相信大家对如何在项目中与海康威视录像机进行数据交互、精准截取回放片段有了较为清晰的认识。

从环境搭建的细致筹备,到代码编写的关键要点,每一步都凝聚着我们团队实践探索的心血。在实际操作过程中,大家可能还会遇到一些诸如兼容性问题、网络波动影响数据传输等小波折,但只要依据海康威视提供的官方文档,结合我们分享的这些实战经验,逐步排查、耐心调试,定能攻克难关。

希望这篇博客能成为您开启相关项目开发的得力助手,助力您的业务一路畅行。倘若后续您在实践中有任何新的疑问、心得或是优化建议,欢迎随时交流分享,让我们携手在技术探索的道路上不断前行,共同解锁更多项目开发的新技能。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊文豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值