SDK介紹
概述
設(shè)備網(wǎng)絡(luò)SDK是基于設(shè)備私有網(wǎng)絡(luò)通信協(xié)議開(kāi)發(fā)的,為嵌入式網(wǎng)絡(luò)硬盤(pán)錄像機(jī)茅郎、NVR际乘、網(wǎng)絡(luò)攝像機(jī)苍匆、網(wǎng)絡(luò)球機(jī)太抓、視頻服務(wù)器绢记、解碼器、報(bào)警主機(jī)毕谴、網(wǎng)絡(luò)存儲(chǔ)等產(chǎn)品服務(wù)的配套模塊成畦,用于遠(yuǎn)程訪問(wèn)和控制設(shè)備軟件的二次開(kāi)發(fā)。
功能
圖像預(yù)覽, 文件回放和下載, 云臺(tái)控制, 布防/撤防, 語(yǔ)音對(duì)講, 日志管理, 解碼卡, 遠(yuǎn)程升級(jí), 遠(yuǎn)程重啟/關(guān)閉, 格式化硬盤(pán), 參數(shù)配置(系統(tǒng)配置, 通道配置, 串口配置, 報(bào)警配置, 用戶配置), 多路解碼器, 智能設(shè)備功能和獲取設(shè)備能力集等涝开。
下載
https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type=10
對(duì)接指南
以java為例
由于我司提供的設(shè)備網(wǎng)絡(luò)SDK是封裝的動(dòng)態(tài)鏈接庫(kù)(Windows的dll或者Linux的so),各種開(kāi)發(fā)語(yǔ)言對(duì)接SDK框仔,都是通過(guò)加載動(dòng)態(tài)庫(kù)鏈接舀武,調(diào)用動(dòng)態(tài)庫(kù)中的接口實(shí)現(xiàn)功能模塊對(duì)接,因此离斩,設(shè)備網(wǎng)絡(luò)SDK的對(duì)接不區(qū)分開(kāi)發(fā)語(yǔ)言银舱,而且對(duì)接的流程和對(duì)應(yīng)的接口都是通用的,各種語(yǔ)言調(diào)用動(dòng)態(tài)庫(kù)的方式有所不同跛梗。本文重點(diǎn)介紹java開(kāi)發(fā)語(yǔ)言如何對(duì)接設(shè)備網(wǎng)絡(luò)SDK寻馏。目前我司提供的java語(yǔ)言開(kāi)發(fā)的demo是通過(guò)JNA的方式調(diào)用動(dòng)態(tài)鏈接庫(kù)中的接口,JNA(Java Native Access)框架是SUN公司主導(dǎo)開(kāi)發(fā)的開(kāi)源java框架核偿,是建立在JNI的基礎(chǔ)上的一個(gè)框架诚欠,JNA框架提供了一組java工具類(lèi)用于在運(yùn)行期間動(dòng)態(tài)訪問(wèn)動(dòng)態(tài)鏈接庫(kù)(native library:如Window的dll、Linux的so)漾岳,實(shí)現(xiàn)在java語(yǔ)言中調(diào)用C/C++語(yǔ)言封裝的接口轰绵,java開(kāi)發(fā)人員只需要在一個(gè)java接口中描述目標(biāo)native library的函數(shù)與結(jié)構(gòu),JNA將自動(dòng)實(shí)現(xiàn)Java接口到native function的映射尼荆,而不需要編寫(xiě)任何Native/JNI代碼左腔,大大降低了Java調(diào)用動(dòng)態(tài)鏈接庫(kù)的開(kāi)發(fā)難度。相比于JNI的方式捅儒,JNA大大簡(jiǎn)化了調(diào)用本地方法的過(guò)程液样,使用很方便振亮,基本上不需要脫離Java環(huán)境就可以完成。JNA調(diào)用C/C++的過(guò)程大致如下:
集成
以
SpringBoot
項(xiàng)目為例鞭莽,核唬康SDK版本為6.1.9.47,JNA版本為3.0.9撮抓,在windows環(huán)境使用Intellij IDEA 2022.2.3開(kāi)發(fā)
初始化項(xiàng)目
- 新建 SpringBoot 項(xiàng)目妇斤,版本 2.5.3
- 添加pom依賴:jna,fastjson2
<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>
- 將下載下來(lái)的旱ふ康sdk放到項(xiàng)目目錄站超,并根據(jù)操作系統(tǒng)不同分別創(chuàng)建相應(yīng)的文件夾
- 若出現(xiàn) HCNetSDK.NET_DVR_PREVIEWINFO.HWND找不到引用,可做如下處理:1:在ProjectStructure中引入官方示例代碼中的 examples.jar 乖酬;2:將 HWND 類(lèi)型修改為 int
- 設(shè)置一個(gè)喜歡的端口
server.port
初始化SDK
初始化SDK概述
一般的死相,我們希望在程序啟動(dòng)的時(shí)候就初始化sdk。
- 這里使用了
ApplicationRunner
作為初始化入口咬像,當(dāng)程序啟動(dòng)成功后算撮,將執(zhí)行 Runner 做初始化 - 為避免初始化sdk對(duì)主線程造成影響,所以
ApplicationRunner
需要放在線程池中ThreadPoolExecutor
县昂,并添加try-catch處理 - HCNetSDK是SDK示例代碼中提供的一個(gè)對(duì)象肮柜,此對(duì)象繼承Library,負(fù)責(zé)和更底層的C/C++庫(kù)(更底層也許是C寫(xiě)的倒彰,這里不確定)交互审洞,即執(zhí)行 Native 調(diào)用。通過(guò)實(shí)例化此對(duì)象完成sdk依賴庫(kù)的導(dǎo)入待讳,并在后續(xù)業(yè)務(wù)開(kāi)發(fā)中使用此對(duì)象向攝像機(jī)發(fā)布指令芒澜。
- 涉及多操作系統(tǒng)平臺(tái)的差異性,官方分別提供不同sdk依賴庫(kù)创淡,具體包含:win32痴晦,win64,linux32琳彩,linux64等誊酌,所以當(dāng)初始化SDK的時(shí)候需要根據(jù)當(dāng)前所處環(huán)境不同分別加載不同的依賴庫(kù)文件
- 上述提到的依賴庫(kù)文件,在windows下就是 dll 后綴文件 汁针, 在 linux 下就是 so 后綴文件
- 真正執(zhí)行初始化就是調(diào)用
hCNetSDK.NET_DVR_Init()
此方法术辐,并可通過(guò)返回值為true
或false
判斷初始化是否成功。
新建AppRunner
- AppRunner 需要實(shí)現(xiàn) ApplicationRunner 接口施无,并將
AppRunner作為組件放到Spring 容器中管理 - AppRunner 中注入SdkInitService 辉词,并在run 方法中調(diào)用 SdkInitService 的initSdk 方法實(shí)現(xiàn)SDK的初始化
package com.ramble.hikvisionsdkintegration;
import com.ramble.hikvisionsdkintegration.service.SdkInitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
private SdkInitService hksdkInitService;
@Override
public void run(ApplicationArguments args) throws Exception {
hksdkInitService.initSdk();
}
}
新建SdkInitService
- 定義一個(gè)公開(kāi)的 hCNetSDK 屬性,類(lèi)型為 HCNetSDK 猾骡,并在構(gòu)造函數(shù)中初始化 hCNetSDK 屬性的值瑞躺,此值需要全局唯一敷搪,這里參照官方代碼做了單例處理。HCNetSDK 是官方提供的一個(gè)接口幢哨,一般的都是直接copy到項(xiàng)目源代碼中赡勘,你會(huì)發(fā)現(xiàn),所有和設(shè)備交互的地方都是通過(guò)這個(gè)接口來(lái)完成的
- 內(nèi)部定義一個(gè)異忱塘回調(diào)類(lèi)闸与,用來(lái)處理和設(shè)備交互的時(shí)候全局異常的處理
- 注入 ThreadPoolExecutor 執(zhí)行器,真正的初始化將放到子線程中進(jìn)行
- 定義 initSdk 方法用來(lái)執(zhí)行初始化
- 需要注意的是岸售,構(gòu)造函數(shù)中為 hCNetSDK 屬性初始化值践樱,僅僅只是為了將 sdk 所需的
依賴庫(kù)文件
加載到運(yùn)行時(shí)中,并沒(méi)有真正的做初始化SDK的工作 - 需要重點(diǎn)關(guān)注OSUtils中的代碼凸丸,加載依賴庫(kù)文件的前提是找到對(duì)應(yīng)的庫(kù)文件拷邢,
找
的操作是在getLoadLibrary
方法中管理的,這里編寫(xiě)的代碼需要和部署時(shí)候選擇的部署方式對(duì)應(yīng)屎慢,否則可能會(huì)出現(xiàn)在windows中開(kāi)發(fā)正常瞭稼,部署到linux 中就報(bào)異常的問(wèn)題
SdkInitService:
package com.ramble.hikvisionsdkintegration.service;
import com.ramble.hikvisionsdkintegration.sdklib.HCNetSDK;
import com.ramble.hikvisionsdkintegration.task.InitSdkTask;
import com.ramble.hikvisionsdkintegration.util.OSUtils;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadPoolExecutor;
@Slf4j
@Component
public class SdkInitService {
public static HCNetSDK hCNetSDK = null;
static FExceptionCallBack_Imp fExceptionCallBack;
static class FExceptionCallBack_Imp implements HCNetSDK.FExceptionCallBack {
public void invoke(int dwType, int lUserID, int lHandle, Pointer pUser) {
System.out.println("異常事件類(lèi)型:" + dwType);
return;
}
}
public SdkInitService() {
if (hCNetSDK == null) {
synchronized (HCNetSDK.class) {
try {
hCNetSDK = (HCNetSDK) Native.loadLibrary(OSUtils.getLoadLibrary(), HCNetSDK.class);
} catch (Exception ex) {
log.error("SdkInitService-init-hCNetSDK-error");
}
}
}
}
@Autowired
private ThreadPoolExecutor executor;
public void initSdk() {
log.info("HKSDKInitService-init-coming");
executor.execute(new InitSdkTask());
}
}
OSUtils:
package com.ramble.hikvisionsdkintegration.util;
import com.sun.jna.Platform;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
@Slf4j
public class OSUtils {
// 獲取操作平臺(tái)信息
public static String getOsPrefix() {
String arch = System.getProperty("os.arch").toLowerCase();
final String name = System.getProperty("os.name");
String osPrefix;
if (Platform.isWindows()) {
if ("i386".equals(arch)) {
arch = "x86";
}
osPrefix = "win32-" + arch;
} else if (Platform.isLinux()) {
if ("x86".equals(arch)) {
arch = "i386";
} else if ("x86_64".equals(arch)) {
arch = "amd64";
}
osPrefix = "linux-" + arch;
} else {
osPrefix = name.toLowerCase();
if ("x86".equals(arch)) {
arch = "i386";
}
if ("x86_64".equals(arch)) {
arch = "amd64";
}
int space = osPrefix.indexOf(" ");
if (space != -1) {
osPrefix = osPrefix.substring(0, space);
}
osPrefix += "-" + arch;
}
return osPrefix;
}
public static String getOsName() {
String osName = "";
String osPrefix = getOsPrefix();
if (osPrefix.toLowerCase().startsWith("win32-x86")
|| osPrefix.toLowerCase().startsWith("win32-amd64")) {
osName = "win";
} else if (osPrefix.toLowerCase().startsWith("linux-i386")
|| osPrefix.toLowerCase().startsWith("linux-amd64")) {
osName = "linux";
}
return osName;
}
/**
* 獲取庫(kù)文件
* 區(qū)分win、linux
*
* @return
*/
public static String getLoadLibrary() {
if (isChecking()) {
return null;
}
String userDir = System.getProperty("user.dir");
log.info("getLoadLibrary-userDir={}", userDir);
String loadLibrary = "";
String library = "";
String osPrefix = getOsPrefix();
if (osPrefix.toLowerCase().startsWith("win32-x86")) {
loadLibrary = System.getProperty("user.dir") + File.separator + "sdk" + File.separator + "hklibwin32" + File.separator;
library = "HCNetSDK.dll";
} else if (osPrefix.toLowerCase().startsWith("win32-amd64")) {
loadLibrary = System.getProperty("user.dir") + File.separator + "sdk" + File.separator + "hklibwin64" + File.separator;
library = "HCNetSDK.dll";
} else if (osPrefix.toLowerCase().startsWith("linux-i386")) {
//同 linux-amd64
loadLibrary = "";
library = "libhcnetsdk.so";
} else if (osPrefix.toLowerCase().startsWith("linux-amd64")) {
//方式一:使用系統(tǒng)默認(rèn)的加載庫(kù)路徑腻惠,在系統(tǒng)的/usr/lib文件中加入你Java工程所需要使用的so文件环肘,然后將HCNetSDKCom文件夾下的組件庫(kù)也復(fù)制到/usr/lib目錄,HCNetSDKCom文件夾中的組件庫(kù)不要隨意更換路徑妖枚。CentOS 64位需拷貝到/usr/lib64下廷臼。
//針對(duì)方式一,前綴就是絕對(duì)路徑
//loadLibrary = "/usr/lib64/lib/hkliblinux64/";
//方式二:配置LD_LIBRARY_PATH環(huán)境變量加載庫(kù)文件绝页;配置/etc/ld.so.conf,加上你自己的Java工程所需要的so文件的路徑
//針對(duì)方式二寂恬,無(wú)需添加前綴续誉,程序會(huì)從linux系統(tǒng)的so共享庫(kù)中查找libhcnetsdk.so
loadLibrary = "";
library = "libhcnetsdk.so";
}
log.info("================= Load library Path :{} ==================", loadLibrary + library);
return loadLibrary + library;
}
private static boolean checking = false;
public static void setChecking() {
checking = true;
}
public static void clearChecking() {
checking = false;
}
public static boolean isChecking() {
return checking;
}
}
新建InitSdkTask
- 此類(lèi)實(shí)現(xiàn) Runnable 接口,并重寫(xiě)run方法初肉。
- 新建一個(gè)私有屬性 hCNetSDK 并賦值為 SdkInitService.hCNetSDK 酷鸦,因?yàn)槌跏蓟枰玫?HCNetSDK 這個(gè)對(duì)象和設(shè)備交互,所以初始化前必須確保此對(duì)象已經(jīng)創(chuàng)建牙咏,本例中臼隔,程序在執(zhí)行 SdkInitService 構(gòu)造函數(shù)的時(shí)候初始化了 HCNetSDK 對(duì)象,并放到一個(gè)全局靜態(tài)變量中
- 其實(shí)也可以不新建私有屬性 hCNetSDK 妄壶,在需要用到此對(duì)象的地方 使用 SdkInitService.hCNetSDK 的方式獲取也可以
- 通過(guò)調(diào)用 hCNetSDK.NET_DVR_Init 方法執(zhí)行初始化摔握,并可以通過(guò)返回值確定是否初始化成功,初始化成功后丁寄,將可以調(diào)用業(yè)務(wù)接口向設(shè)備發(fā)送指令氨淌。
- NET_DVR_SetConnectTime泊愧,NET_DVR_SetReconnect 是可選的,并不會(huì)對(duì)初始化SDK本身造成影響盛正。
- 為了避免對(duì)主程序造成影響删咱,初始化代碼將需要做 try - catch 處理
InitSdkTask:
package com.ramble.hikvisionsdkintegration.task;
import com.ramble.hikvisionsdkintegration.sdklib.HCNetSDK;
import com.ramble.hikvisionsdkintegration.service.SdkInitService;
import com.ramble.hikvisionsdkintegration.util.OSUtils;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
@Slf4j
public class InitSdkTask implements Runnable {
/**
* 裝配 sdk 所需依賴
*/
private static HCNetSDK hCNetSDK = SdkInitService.hCNetSDK;
@Override
public void run() {
try {
if (Objects.equals(OSUtils.getOsName(), "linux")) {
log.info("InitSdk-is-linux");
String userDir = System.getProperty("user.dir");
log.info("InitSdk-userDir={}", userDir);
String osPrefix = OSUtils.getOsPrefix();
if (osPrefix.toLowerCase().startsWith("linux-i386")) {
HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
//這里是庫(kù)的絕對(duì)路徑,請(qǐng)根據(jù)實(shí)際情況修改豪筝,注意改路徑必須有訪問(wèn)權(quán)限
//linux 下痰滋, 庫(kù)加載參考:OSUtils.getLoadLibrary()
String strPath1 = System.getProperty("user.dir") + "/hkliblinux32/libcrypto.so.1.1";
String strPath2 = System.getProperty("user.dir") + "/hkliblinux32/libssl.so.1.1";
System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
ptrByteArray1.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());
System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
ptrByteArray2.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());
//linux 下, 庫(kù)加載參考:OSUtils.getLoadLibrary()
String strPathCom = System.getProperty("user.dir") + "/hkliblinux32/HCNetSDKCom/";
HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
struComPath.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
} else if (osPrefix.toLowerCase().startsWith("linux-amd64")) {
HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
//這里是庫(kù)的絕對(duì)路徑续崖,請(qǐng)根據(jù)實(shí)際情況修改敲街,注意改路徑必須有訪問(wèn)權(quán)限
//linux 下, 庫(kù)加載參考:OSUtils.getLoadLibrary()
String strPath1 = System.getProperty("user.dir") + "/hkliblinux64/libcrypto.so.1.1";
String strPath2 = System.getProperty("user.dir") + "/hkliblinux64/libssl.so.1.1";
System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
ptrByteArray1.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());
System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
ptrByteArray2.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());
String strPathCom = System.getProperty("user.dir") + "/hkliblinux64/HCNetSDKCom/";
//linux 下袜刷, 庫(kù)加載參考:OSUtils.getLoadLibrary()
HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
struComPath.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
} else {
log.info("osPrefix={}", osPrefix);
}
}
//初始化sdk
boolean isOk = hCNetSDK.NET_DVR_Init();
hCNetSDK.NET_DVR_SetConnectTime(10, 1);
hCNetSDK.NET_DVR_SetReconnect(100, true);
if (!isOk) {
log.error("=================== InitSDK init fail ===================");
} else {
log.info("============== InitSDK init success ====================");
}
} catch (Exception e) {
log.error("InitSDK-error,e={}", e.getMessage());
e.printStackTrace();
}
}
}
新建 HCNetSDK
直接從官方示例代碼中copy過(guò)來(lái)即可
調(diào)用業(yè)務(wù)接口
- 新建一個(gè)controller 聪富,嘗試調(diào)用 獲取SDK狀態(tài) 的接口。
- 調(diào)用所有的業(yè)務(wù)接口之前都需要先登錄
package com.ramble.hikvisionsdkintegration.controller;
import com.alibaba.fastjson2.JSON;
import com.ramble.hikvisionsdkintegration.dto.GlobalResponseEntity;
import com.ramble.hikvisionsdkintegration.sdklib.HCNetSDK;
import com.ramble.hikvisionsdkintegration.service.SdkInitService;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/test")
public class TestController {
private static String m_sDeviceIP = "192.168.1.142";
private static String m_sUsername = "xxx";
private static String m_sPassword = "xxx";
/**
* 獲取sdk狀態(tài)
*
* @return {@link GlobalResponseEntity}<{@link String}>
* 返回值舉例:{"success":true,"code":"000000","message":"request successfully",
* "data":"{\"dwRes\":[0,0,0,0,0,0,0,0,0,0],\"dwTotalAlarmChanNum\":0,\"dwTotalBroadCastNum\":0,\"dwTotalFileSearchNum\":0,\"dwTotalFormatNum\":0,
* \"dwTotalLogSearchNum\":0,\"dwTotalLoginNum\":1,\"dwTotalPlayBackNum\":0,\"dwTotalRealPlayNum\":0,\"dwTotalSerialNum\":0,\"dwTotalUpgradeNum\":0,
* \"dwTotalVoiceComNum\":0,\"autoRead\":true,\"autoWrite\":true,\"pointer\":{\"size\":84,\"valid\":true}}"}
*/
@GetMapping("/state")
public GlobalResponseEntity<String> getSdkState() {
//登錄
Integer userId = login();
log.info("userId={}", userId);
HCNetSDK.NET_DVR_SDKSTATE sdkState = new HCNetSDK.NET_DVR_SDKSTATE();
//獲取當(dāng)前SDK狀態(tài)信息
boolean result = SdkInitService.hCNetSDK.NET_DVR_GetSDKState(sdkState);
if (result) {
sdkState.read();
String s = JSON.toJSONString(sdkState);
return GlobalResponseEntity.success(s);
} else {
int error = SdkInitService.hCNetSDK.NET_DVR_GetLastError();
return GlobalResponseEntity.error("獲取失敗著蟹,錯(cuò)誤碼為:" + error);
}
}
private Integer login() {
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//設(shè)備登錄信息
m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
m_strLoginInfo.wPort = Short.valueOf("8000");
m_strLoginInfo.bUseAsynLogin = false; //是否異步登錄:0- 否墩蔓,1- 是
m_strLoginInfo.write();
HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//設(shè)備信息
int loginHandler = SdkInitService.hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (loginHandler == -1) {
int errorCode = SdkInitService.hCNetSDK.NET_DVR_GetLastError();
IntByReference errorInt = new IntByReference(errorCode);
log.error("[HK] login fail errorCode:{}, errMsg:{}", errorCode, SdkInitService.hCNetSDK.NET_DVR_GetErrorMsg(errorInt));
return null;
} else {
return loginHandler;
}
}
}
部署
拷貝so庫(kù)文件到部署目錄
所有廠家的所有版本sdk庫(kù)文件均維護(hù)在項(xiàng)目源代碼中,需要將linux庫(kù)文件so文件拷貝到部署根目錄萧豆,和jar文件同級(jí)
追加環(huán)境變量
通過(guò)配置 LD_LIBRARY_PATH
環(huán)境變量加載庫(kù)文件奸披,打開(kāi)系統(tǒng)的 /etc/profile
配置文件,在最后追加so庫(kù)文件所在目錄:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/app/jars/hkliblinux64:/home/app/jars/hkliblinux64/HCNetSDKCom
如上所示:
● 32位就追加 hkliblinux32 目錄涮雷,64位就追加 hkliblinux64 目錄
● 不要忘記 HCNetSDKCom 目錄也需要配置阵面,因?yàn)槔锩嬉灿衧o庫(kù)文件。
執(zhí)行source 命令洪鸭,讓配置生效:
source /etc/profile
追加so庫(kù)加載路徑
打開(kāi) /etc/ld.so.conf
配置文件样刷,追加so庫(kù)文件所在目錄
/home/app/jars/hkliblinux64
/home/app/jars/hkliblinux64/HCNetSDKCom
如上所示:
● 32位就追加 hkliblinux32 目錄,64位就追加 hkliblinux64 目錄览爵。
● 不要忘記 HCNetSDKCom 目錄也需要配置置鼻,因?yàn)槔锩嬉灿衧o庫(kù)文件。
執(zhí)行 ldconfig 命令蜓竹,讓配置生效:
ldconfig
驗(yàn)證SDK初始化是否成功
一般來(lái)說(shuō)箕母,可以在程序初始化SDK的時(shí)候添加日志,通過(guò)日志輸出判斷是否初始化成功俱济。
代碼
https://gitee.com/naylor_personal/ramble-spring-boot/tree/master/hikvision-sdk-integration