package com.whyc.hik;
|
|
import com.sun.jna.Native;
|
import com.sun.jna.Pointer;
|
import com.whyc.dto.Point;
|
import com.whyc.dto.TempPoint;
|
import com.whyc.hik.Commom.osSelect;
|
import com.whyc.hik.NetSDKDemo.HCNetSDK;
|
|
import java.io.FileOutputStream;
|
import java.io.IOException;
|
import java.io.RandomAccessFile;
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Scanner;
|
|
/**
|
* @create 2020-07-27-10:42
|
*/
|
public class TestDemo {
|
static HCNetSDK hCNetSDK = null;
|
static int lUserID = -1; //用户句柄
|
public 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("异常事件类型:" + dwType);
|
return;
|
}
|
}
|
|
/**
|
* 动态库加载
|
*
|
* @return
|
*/
|
private static boolean createSDKInstance() {
|
if (hCNetSDK == null) {
|
synchronized (HCNetSDK.class) {
|
String strDllPath = "";
|
try {
|
if (osSelect.isWindows()) {
|
//win系统加载SDK库路径
|
strDllPath = System.getProperty("user.dir") + "\\src\\main\\resources\\lib\\Hik\\HCNetSDK.dll";
|
}
|
else if (osSelect.isLinux()) {
|
//Linux系统加载SDK库路径
|
strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so";
|
}
|
hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
|
} catch (Exception ex) {
|
System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public static void main(String[] args) throws IOException, InterruptedException {
|
if (hCNetSDK == null) {
|
if (!createSDKInstance()) {
|
System.out.println("Load SDK fail");
|
return;
|
}
|
}
|
//linux系统建议调用以下接口加载组件库
|
if (osSelect.isLinux()) {
|
HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
|
HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
|
//这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
|
String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
|
String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";
|
System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
|
ptrByteArray1.write();
|
hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_LIBEAY_PATH, ptrByteArray1.getPointer());
|
System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
|
ptrByteArray2.write();
|
hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SSLEAY_PATH, ptrByteArray2.getPointer());
|
String strPathCom = System.getProperty("user.dir") + "/lib/";
|
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(HCNetSDK.NET_SDK_INIT_CFG_SDK_PATH, struComPath.getPointer());
|
}
|
|
//SDK初始化,一个程序进程只需要调用一次
|
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 = TestDemo.loginDevice("10.9.137.21", (short) 8000, "admin", "Cpfwb518+");
|
lUserID = TestDemo.loginDevice("192.168.10.16", (short) 8000, "admin", "fg001@hdw");
|
//hCNetSDK.NET_DVR_STDXMLConfig(lUserID, "<?xml version=\"1.0\" encoding=\"GB2312\"?><GetDeviceInfo><dwSize>0</dwSize></GetDeviceInfo>", "GetDeviceInfo", 1000);
|
|
/*========== 红外 抓图测温 Start==========*/
|
//抓热图
|
HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA m_strJpegWithAppendData = new HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA();
|
m_strJpegWithAppendData.dwSize = m_strJpegWithAppendData.size();
|
HCNetSDK.BYTE_ARRAY ptrJpegByte = new HCNetSDK.BYTE_ARRAY(2*1024*1024);
|
HCNetSDK.BYTE_ARRAY ptrP2PDataByte = new HCNetSDK.BYTE_ARRAY(2*1024*1024);
|
m_strJpegWithAppendData.pJpegPicBuff = ptrJpegByte.getPointer();
|
m_strJpegWithAppendData.pP2PDataBuff = ptrP2PDataByte.getPointer();
|
m_strJpegWithAppendData.dwJpegPicLen = 2*1024*1024;
|
m_strJpegWithAppendData.dwP2PDataLen = 2*1024*1024;
|
m_strJpegWithAppendData.write();
|
|
boolean resBoolean = hCNetSDK.NET_DVR_CaptureJPEGPicture_WithAppendData(lUserID, 2, m_strJpegWithAppendData);
|
if (resBoolean) {
|
System.out.println("抓图成功");
|
//m_strJpegWithAppendData.read();
|
// 定义文件名
|
String cFilename = "Jpegwithappend_1.data";
|
String cFilename2 = "Jpegwithappend_1.csv";
|
|
// 创建文件输出流
|
try (FileOutputStream fos = new FileOutputStream(cFilename)) {
|
// 将数据写入文件
|
//fos.write(m_strJpegWithAppendData.pP2PDataBuff, 0, m_strJpegWithAppendData.dwP2PDataLen);
|
Pointer pP2PDataBuff = m_strJpegWithAppendData.pP2PDataBuff;
|
fos.write(pP2PDataBuff.getByteArray(0, m_strJpegWithAppendData.dwP2PDataLen), 0, m_strJpegWithAppendData.dwP2PDataLen);
|
} catch (IOException e) {
|
e.printStackTrace(); // 捕获并处理异常
|
}
|
|
analyzeData(m_strJpegWithAppendData.dwP2PDataLen, cFilename, cFilename2);
|
|
|
//获取红外结果并解析
|
}else {
|
System.out.printf("抓热图失败:%s",hCNetSDK.NET_DVR_GetLastError());
|
}
|
/*========== 红外 抓图测温 End==========*/
|
|
hCNetSDK.NET_DVR_CaptureJPEGPicture_WithAppendData(lUserID,1,null);
|
for (boolean exit = false; !exit; ) {
|
System.out.println("请输入您想要执行的demo实例! (退出请输入yes)");
|
Scanner input = new Scanner(System.in);
|
String str = input.next();
|
// 转换为标准输入
|
str = str.toLowerCase();
|
if (str.equals("yes")) {
|
// 退出程序
|
exit = true;
|
break;
|
}
|
switch (str) {
|
case "1":
|
{
|
System.out.println("\n[Module]手动获取设备在线状态");
|
DevManager.getDeviceStatus(lUserID);
|
break;
|
}
|
case "2":
|
{
|
System.out.println("\n[Module]获取设备工作状态代码");
|
DevManager.getWorkS(lUserID);
|
break;
|
}
|
case "3":
|
{
|
System.out.println("\n[Module]获取设备基本信息");
|
DevManager.getDeviceInfo(lUserID);
|
break;
|
}
|
|
case "4":
|
{
|
|
System.out.println("\n[Module]设备抓图代码");
|
ChannelParamCfg.CaptureJPEGPicture(lUserID);
|
break;
|
}
|
case "5":
|
{
|
//适用NVR等硬盘录像机设备
|
System.out.println("\n[Module]查询设备通道状态代码");
|
ChannelParamCfg.GetIPChannelInfo(lUserID);
|
break;
|
}
|
case "6":
|
{
|
//获取和设置前端扩展参数
|
System.out.println("\n[Module]获取和设置前端扩展参数");
|
ChannelParamCfg.GetCameraPara(lUserID);
|
break;
|
}
|
case "7":
|
{
|
//获取和设置网络参数
|
System.out.println("\n[Module]获取和设置网络参数");
|
ChannelParamCfg.GetNetCfg(lUserID);
|
break;
|
}
|
case "8":
|
{
|
//获取和设置录像参数
|
System.out.println("\n[Module]获取和设置录像参数");
|
ChannelParamCfg.GetRecordCfg(lUserID);
|
break;
|
}
|
case "9":
|
{
|
//获取和设置图像参数
|
System.out.println("\n[Module]获取和设置图像参数");
|
ChannelParamCfg.GetandSetPicCfg(lUserID);
|
break;
|
}
|
case "10":
|
{
|
//获取和设置时间参数
|
System.out.println("\n[Module]获取和设置时间参数");
|
SdkSysCfg.GetandSetDevTime(lUserID);
|
break;
|
}
|
case "11":
|
{
|
//获取设备软硬件能力信息
|
System.out.println("\n[Module]获取设备软硬件能力");
|
DevManager.GetSofthardware_Ability(lUserID);
|
break;
|
}
|
case "12":
|
{
|
//获取设备JPEG抓图能力
|
System.out.println("\n[Module]获取设备JPEG抓图能力");
|
DevManager.GetJPEG_Cap_Ability(lUserID);
|
break;
|
}
|
case "13":
|
{
|
//日志查找
|
System.out.println("\n[Module]日志查找");
|
DevManager.FindLog(lUserID);
|
break;
|
}
|
default:
|
{
|
System.out.println("\n未知的指令操作!请重新输入!\n");
|
}
|
}
|
}
|
|
|
Thread.sleep(2000);
|
//程序退出的时候调用注销登录接口,每一台设备分别调用一次
|
if (hCNetSDK.NET_DVR_Logout(lUserID)) {
|
System.out.println("注销成功");
|
}
|
|
//释放SDK资源,程序退出时调用,只需要调用一次
|
hCNetSDK.NET_DVR_Cleanup();
|
return;
|
}
|
|
public static void analyzeData(int dwP2PDataLen, String cFilename, String cFilename2) throws IOException {
|
// 打开本地保存的文件
|
String inputFilename = cFilename;
|
String outputFilename = cFilename2;
|
|
int m_AnalysisHotPic_W = 384; // 根据抓热图接口返回的图像宽dwJpegPicWidth进行赋值
|
int m_AnalysisHotPic_H = 288; // 根据抓热图接口返回的图像高dwJpegPicHeight进行赋值
|
int bufSize = m_AnalysisHotPic_H * m_AnalysisHotPic_W * 4;
|
|
try (RandomAccessFile datafilefp = new RandomAccessFile(inputFilename, "r");
|
FileOutputStream fp = new FileOutputStream(outputFilename)) {
|
|
// 读取文件里面所有数据
|
byte[] pDataBuf = new byte[bufSize];
|
int bytesRead = datafilefp.read(pDataBuf);
|
if (bytesRead != bufSize) {
|
System.out.println("Failed to read the entire file");
|
return;
|
}
|
|
float minTemp = 10000.0f;
|
float maxTemp = -10000.0f;
|
//存储极值温度的坐标,如果是相同的极值温度,就也同步添加坐标点
|
TempPoint minTempPoint = new TempPoint();
|
TempPoint maxTempPoint = new TempPoint();
|
|
ByteBuffer buffer = ByteBuffer.wrap(pDataBuf);
|
buffer.order(ByteOrder.LITTLE_ENDIAN); // 根据实际情况调整字节序
|
|
for (int iWriteHeight = 0; iWriteHeight < m_AnalysisHotPic_H; ++iWriteHeight) {
|
for (int iWriteWidth = 0; iWriteWidth < m_AnalysisHotPic_W; ++iWriteWidth) {
|
float fTemp = buffer.getFloat();
|
// 判断fTemp是否是一个正常值,不是则赋值最大或最小,防止设备崩溃
|
fTemp = (9999 < fTemp) ? 9999 : ((-9999 > fTemp) ? -9999 : fTemp);
|
//只保留以为小数
|
fTemp = BigDecimal.valueOf(fTemp).setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
|
|
//minTemp = (minTemp > fTemp) ? fTemp : minTemp;
|
if(minTemp >= fTemp){
|
minTemp = fTemp;
|
//查看存的最低温度是不是当前温度,不是的话,要清空最低温度map,
|
//同时把最新的最低温度和坐标保存
|
Float minTempOld = minTempPoint.getTemp();
|
if(minTempOld == null || minTempOld!=minTemp){ //首次赋值 或者 需要重置最低温度
|
minTempPoint.setTemp(minTemp);
|
List<Point> points = new ArrayList<>();
|
Point point = new Point(iWriteWidth,iWriteHeight);
|
points.add(point);
|
minTempPoint.setPoints(points);
|
}else { //存在最低温度相同的另外一个点,保存下来进入最低温度列表
|
List<Point> points = minTempPoint.getPoints();
|
points.add(new Point(iWriteWidth,iWriteHeight));
|
}
|
}
|
//maxTemp = (maxTemp < fTemp) ? fTemp : maxTemp;
|
if(maxTemp <= fTemp){
|
maxTemp = fTemp;
|
//查看存的最高温度是不是当前温度,不是的话,要清空最高温度map,
|
//同时把最新的最高温度和坐标保存
|
Float maxTempOld = maxTempPoint.getTemp();
|
if(maxTempOld == null || maxTempOld!=maxTemp){ //首次赋值 或者 需要重置最高温度
|
maxTempPoint.setTemp(maxTemp);
|
List<Point> points = new ArrayList<>();
|
Point point = new Point(iWriteWidth,iWriteHeight);
|
points.add(point);
|
maxTempPoint.setPoints(points);
|
}else { //存在最高温度相同的另外一个点,保存下来进入最高温度列表
|
List<Point> points = maxTempPoint.getPoints();
|
points.add(new Point(iWriteWidth,iWriteHeight));
|
}
|
}
|
|
String temp = String.format("%.2f,", fTemp);
|
|
fp.write(temp.getBytes());
|
}
|
|
fp.write("\n".getBytes());
|
}
|
|
System.out.println("Min Temperature: " + minTempPoint);
|
System.out.println("Max Temperature: " + maxTempPoint);
|
|
} catch (IOException e) {
|
e.printStackTrace(); // 捕获并处理异常
|
}
|
}
|
|
/**
|
* 设备登录V30
|
*
|
* @param ip 设备IP
|
* @param port SDK端口,默认设备的8000端口
|
* @param user 设备用户名
|
* @param psw 设备密码
|
*/
|
public static int login_V30(String ip, short port, String user, String psw) {
|
HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
|
int iUserID = hCNetSDK.NET_DVR_Login_V30(ip, port, user, psw, m_strDeviceInfo);
|
System.out.println("UserID:" + lUserID);
|
if ((iUserID == -1) || (iUserID == 0xFFFFFFFF)) {
|
System.out.println("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
|
return iUserID;
|
} else {
|
System.out.println(ip + ":设备登录成功!");
|
return iUserID;
|
}
|
}
|
|
/**
|
* 登录设备,支持 V40 和 V30 版本,功能一致。
|
*
|
* @param ip 设备IP地址
|
* @param port SDK端口,默认为设备的8000端口
|
* @param user 设备用户名
|
* @param psw 设备密码
|
* @return 登录成功返回用户ID,失败返回-1
|
*/
|
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; // 返回登录结果
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|