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, "0", "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 points = new ArrayList<>();
Point point = new Point(iWriteWidth,iWriteHeight);
points.add(point);
minTempPoint.setPoints(points);
}else { //存在最低温度相同的另外一个点,保存下来进入最低温度列表
List 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 points = new ArrayList<>();
Point point = new Point(iWriteWidth,iWriteHeight);
points.add(point);
maxTempPoint.setPoints(points);
}else { //存在最高温度相同的另外一个点,保存下来进入最高温度列表
List 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; // 返回登录结果
}
}