海康开放平台——海康文档链接——海康开发包和文档下载链接
硬件:海康超脑NVR(全称Network Video Recorder,即网络视频录像机)、人脸摄像机。
环境:JDK_1.8 Windows 64位 jna.jar版本为3.0.9
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>3.0.9</version>
</dependency>
定义SDK接口:
自定义一个接口HCNetSDK,继承Library 或 StdCallLibrary。默认的是继承Library ,如果动态链接库里的函数是以stdcall方式输出的,那么就继承StdCallLibrary。接口内部需要一个公共静态常量:INSTANCE,通过这个常量,就可以获得这个接口的实例,从而使用接口的方法,也就是调用外部dll/so的函数。INSTANCE常量通过 Native.loadLibrary() API函数获得,(新版本的jna中,常量是通过Native.load()函数获取的)该函数有2个参数:
1)第一个参数是动态链接库dll/so的全路径名称(可以是绝对路径或者相对路径),本demo采用的是绝对路径。
2)第二个参数是自定义接口的Class类型。JNA通过这个Class类型,根据指定的.dll/.so文件,动态创建接口的实例。该实例由JNA通过反射自动生成。
// SDK接口说明,HCNetSDK.dll
public interface HCNetSDK extends StdCallLibrary {
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("E:\\DEMO_TEST\\JAVA_Demo\\JNA_TEST\\lib\\HCNetSDK.dll", HCNetSDK.class);
// 动态库中结构体、接口描述
public static class NET_DVR_USER_LOGIN_INFO extends Structure{
public byte[] sDeviceAddress = new byte[NET_DVR_DEV_ADDRESS_MAX_LEN];
public byte byUseTransport;
public short wPort;
public byte[] sUserName = new byte[NET_DVR_LOGIN_USERNAME_MAX_LEN];
public byte[] sPassword = new byte[NET_DVR_LOGIN_PASSWD_MAX_LEN];
public FLoginResultCallback cbLoginResult;
public Pointer pUser;
public boolean bUseAsynLogin;
public byte byProxyType; // 0:不使用代理,1:使用标准代理,2:使用EHome代理
public byte byUseUTCTime; // 0-不进行转换,默认,1-接口上输入输出全部使用UTC时间,SDK完成UTC时间与设备时区的转换,2-接口上输入输出全部使用平台本地时间,SDK完成平台本地时间与设备时区的转换
public byte byLoginMode; // 0-Private 1-ISAPI 2-自适应
public byte byHttps; // 0-不适用tls,1-使用tls 2-自适应
public int iProxyID; // 代理服务器序号,添加代理服务器信息时,相对应的服务器数组下表值
public byte byVerifyMode; // 认证方式,0-不认证,1-双向认证,2-单向认证;认证仅在使用TLS的时候生效;
public byte[] byRes2 = new byte[119];
// 结构体中重写getFieldOrder方法,FieldOrder顺序要和结构体中定义的顺序保持一致
@Override
protected List getFieldOrder(){
return Arrays.asList("sDeviceAddress","byUseTransport","wPort","sUserName","sPassword", "cbLoginResult","pUser","bUseAsynLogin","byProxyType","byUseUTCTime",
"byLoginMode","byHttps","iProxyID","byVerifyMode","byRes2");
}
}
// 常量(宏)定义
public static final int NET_DVR_DEV_ADDRESS_MAX_LEN = 129;
public static final int NET_DVR_LOGIN_USERNAME_MAX_LEN = 64;
public static final int NET_DVR_LOGIN_PASSWD_MAX_LEN = 64;
/*** API函数声明 ***/
// 初始化SDK,调用其他SDK函数的前提
boolean NET_DVR_Init();
// 启用日志文件写入接口
boolean NET_DVR_SetLogToFile(int bLogEnable , String strLogDir, boolean bAutoDel);
// 返回最后操作的错误码
int NET_DVR_GetLastError();
// 释放SDK资源,在程序结束之前调用
boolean NET_DVR_Cleanup();
// 登录接口
int NET_DVR_Login_V40(NET_DVR_USER_LOGIN_INFO pLoginInfo, NET_DVR_DEVICEINFO_V40 lpDeviceInfo);
// 用户注销
boolean NET_DVR_Logout(int lUserID);
// 回调函数申明
public static interface FLoginResultCallback extends StdCallCallback{
// 登录状态回调函数
public int invoke(int lUserID,int dwResult,NET_DVR_DEVICEINFO_V30 lpDeviceinfo,Pointer pUser);
}
测试登录
package com.hik;
/**
* @author test
* @create 2021-02-07-15:53
*/
public class jna_test {
// 接口的实例,通过接口实例调用外部dll/so的函数
static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
// 用户登录返回句柄
static int lUserID;
int iErr = 0;
public static void main(String[] args) throws InterruptedException {
jna_test test01 = new jna_test();
// 初始化
boolean initSuc = hCNetSDK.NET_DVR_Init();
if (initSuc != true) {
System.out.println("初始化失败");
}
// 打印SDK日志
hCNetSDK.NET_DVR_SetLogToFile(3, ".\\SDKLog\\", false);
// 用户登陆操作
test01.Login_V40("192.168.1.64",(short)8000,"admin","test12345");
/*
*实现SDK中其余功能模快
*/
Thread.sleep(5000);
//用户注销,释放SDK
test01.Logout();
}
/**
*
* @param m_sDeviceIP 设备ip地址
* @param wPort 端口号,设备网络SDK登录默认端口8000
* @param m_sUsername 用户名
* @param m_sPassword 密码
*/
public void Login_V40(String m_sDeviceIP,short wPort,String m_sUsername,String m_sPassword) {
/* 注册 */
// 设备登录信息
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
// 设备信息
HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
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.wPort =wPort ;
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());
// 是否异步登录:false- 否,true- 是
m_strLoginInfo.bUseAsynLogin = false;
// write()调用后数据才写入到内存中
m_strLoginInfo.write();
lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (lUserID == -1) {
System.out.println("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
return;
} else {
System.out.println("登录成功!");
// read()后,结构体中才有对应的数据
m_strDeviceInfo.read();
return;
}
}
//设备注销 SDK释放
public void Logout() {
if (lUserID>=0)
{
if (hCNetSDK.NET_DVR_Logout(lUserID) == false) {
System.out.println("注销失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
}
System.out.println("注销成功");
hCNetSDK.NET_DVR_Cleanup();
return;
}
else{
System.out.println("设备未登录");
hCNetSDK.NET_DVR_Cleanup();
return;
}
}
}
批量获取人脸库信息
批量获取或设置人脸库信息:(命令:GET /ISAPI/Intelligent/FDLib
、PUT /ISAPI/Intelligent/FDLib
);
-
SDK初始化
// 接口的实例,通过接口实例调用外部dll/so的函数 static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE; // step1:初始化 boolean initSuc = hCNetSDK.NET_DVR_Init(); if (initSuc != true) { System.out.println("初始化失败"); }
-
打印SDK日志
/** * 启用日志文件写入接口 * * @param bLogEnable 日志的等级(默认为0):0-表示关闭日志,1-表示只输出ERROR错误日志,2-输出ERROR错误信息和DEBUG调试信息,3-输出ERROR错误信息、DEBUG调试信息和INFO普通信息等所有信息 * @param strLogDir 日志文件的路径,windows默认值为"C:\\SdkLog\\";linux默认值"/home/sdklog/" * @param bAutoDel 是否删除超出的文件数,默认值为TRUE * @return */ // step2:打印SDK日志 hCNetSDK.NET_DVR_SetLogToFile(3, ".\\SDKLog\\", false);
-
用户登陆操作
// 登录接口 int NET_DVR_Login_V40(NET_DVR_USER_LOGIN_INFO pLoginInfo, NET_DVR_DEVICEINFO_V40 lpDeviceInfo);
-
获取人脸库信息
//命令 GET /ISAPI/Intelligent/FDLib //ISAPI协议命令透传 boolean NET_DVR_STDXMLConfig(int lUserID, NET_DVR_XML_CONFIG_INPUT lpInputParam, NET_DVR_XML_CONFIG_OUTPUT lpOutputParam);
批量获取人脸库信息方法:
public static final int ISAPI_DATA_LEN = 1024 * 1024; public static final int ISAPI_STATUS_LEN = 4 * 4096; public static final int BYTE_ARRAY_LEN = 1024; HCNetSDK hCNetSDK = HCNetSDK.INSTANCE; /** * 批量获取人脸库信息 * * @param lUserID 登录返回的句柄 */ public void getFaceLibInfo(int lUserID) { //获取人脸比对库能力集判断设备是否支持相关功能 // String url = "GET /ISAPI/Intelligent/FDLib/capabilities"; //命令 String url = "GET /ISAPI/Intelligent/FDLib"; HCNetSDK.BYTE_ARRAY ptrUrl = new HCNetSDK.BYTE_ARRAY(BYTE_ARRAY_LEN); System.arraycopy(url.getBytes(), 0, ptrUrl.byValue, 0, url.length()); // 数据写入到内存 ptrUrl.write(); //透传接口输入参数结构体 HCNetSDK.NET_DVR_XML_CONFIG_INPUT netDvrXmlConfigInput = new HCNetSDK.NET_DVR_XML_CONFIG_INPUT(); //结构体大小 netDvrXmlConfigInput.dwSize = netDvrXmlConfigInput.size(); //请求信令,字符串格式 netDvrXmlConfigInput.lpRequestUrl = ptrUrl.getPointer(); //请求信令长度,字符串长度 netDvrXmlConfigInput.dwRequestUrlLen = url.length(); //输入参数缓冲区,XML/JSON格式 netDvrXmlConfigInput.lpInBuffer = null;//ptrInBuffer.getPointer(); //输入参数缓冲区大小 netDvrXmlConfigInput.dwInBufferSize = 0;//ptrInBuffer.byValue.length; netDvrXmlConfigInput.write(); HCNetSDK.BYTE_ARRAY ptrStatusByte = new HCNetSDK.BYTE_ARRAY(ISAPI_STATUS_LEN); HCNetSDK.BYTE_ARRAY ptrOutByte = new HCNetSDK.BYTE_ARRAY(ISAPI_DATA_LEN); HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT struXMLOutput = new HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT(); struXMLOutput.dwSize = struXMLOutput.size(); struXMLOutput.lpOutBuffer = ptrOutByte.getPointer(); struXMLOutput.dwOutBufferSize = ptrOutByte.size(); struXMLOutput.lpStatusBuffer = ptrStatusByte.getPointer(); struXMLOutput.dwStatusSize = ptrStatusByte.size(); struXMLOutput.write(); //ISAPI协议命令透传 if (!hCNetSDK.NET_DVR_STDXMLConfig(lUserID, netDvrXmlConfigInput, struXMLOutput)) { System.out.println("NET_DVR_STDXMLConfig失败,错误号:" + hCNetSDK.NET_DVR_GetLastError()); return; } else { struXMLOutput.read(); ptrOutByte.read(); ptrStatusByte.read(); String strOutXML = new String(ptrOutByte.byValue).trim(); System.out.println("获取设备能力集输出结果:" + strOutXML); String strStatus = new String(ptrStatusByte.byValue).trim(); System.out.println("获取设备能力集返回状态:" + strStatus); } }
-
用户注销,释放SDK
// 用户注销 boolean NET_DVR_Logout(int lUserID); // 释放SDK资源,在程序结束之前调用 boolean NET_DVR_Cleanup();
创建人脸库
创建人脸库:(命令:POST /ISAPI/Intelligent/FDLib
);
-
SDK初始化
// 接口的实例,通过接口实例调用外部dll/so的函数 static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE; // step1:初始化 boolean initSuc = hCNetSDK.NET_DVR_Init(); if (initSuc != true) { System.out.println("初始化失败"); }
-
打印SDK日志
/** * 启用日志文件写入接口 * * @param bLogEnable 日志的等级(默认为0):0-表示关闭日志,1-表示只输出ERROR错误日志,2-输出ERROR错误信息和DEBUG调试信息,3-输出ERROR错误信息、DEBUG调试信息和INFO普通信息等所有信息 * @param strLogDir 日志文件的路径,windows默认值为"C:\\SdkLog\\";linux默认值"/home/sdklog/" * @param bAutoDel 是否删除超出的文件数,默认值为TRUE * @return */ // step2:打印SDK日志 hCNetSDK.NET_DVR_SetLogToFile(3, ".\\SDKLog\\", false);
-
用户登陆操作
// 登录接口 int NET_DVR_Login_V40(NET_DVR_USER_LOGIN_INFO pLoginInfo, NET_DVR_DEVICEINFO_V40 lpDeviceInfo);
-
创建人脸库
// 命令 POST /ISAPI/Intelligent/FDLib // ISAPI协议命令透传 boolean NET_DVR_STDXMLConfig(int lUserID, NET_DVR_XML_CONFIG_INPUT lpInputParam, NET_DVR_XML_CONFIG_OUTPUT lpOutputParam); // 创建成功后 // 使用dom4j解析xml,获取FDID lpOutputParam.read(); String xmlStr = lpOutputParam.lpOutBuffer.getString(0); // dom4j解析xml try { Document document; document = DocumentHelper.parseText(xmlStr); Element FDLibInfoList = document.getRootElement(); // 同时迭代当前节点下面的所有子节点 Iterator<Element> iterator = FDLibInfoList.elementIterator(); Element FDLibInfo = iterator.next(); Iterator<Element> iterator2 = FDLibInfo.elementIterator(); while (iterator2.hasNext()) { Element e = iterator2.next(); if (e.getName().equals("FDID")) { String FDID = e.getText(); System.out.println("FDID = " + FDID); } } } catch (DocumentException e1) { e1.printStackTrace(); }
创建人脸库方法:
public static final int ISAPI_DATA_LEN = 1024 * 1024; public static final int ISAPI_STATUS_LEN = 4 * 4096; public static final int BYTE_ARRAY_LEN = 1024; HCNetSDK hCNetSDK = HCNetSDK.INSTANCE; /** * 创建人脸库 * * @param lUserID 登录返回的句柄 * @param faceId 人脸库ID * @param faceLibName 人脸库名称(目前不能是中文) */ public void createFaceLib(int lUserID, String faceId, String faceLibName) { //创建人脸库 String url = "POST /ISAPI/Intelligent/FDLib"; HCNetSDK.BYTE_ARRAY ptrUrl = new HCNetSDK.BYTE_ARRAY(BYTE_ARRAY_LEN); System.arraycopy(url.getBytes(), 0, ptrUrl.byValue, 0, url.length()); // 数据写入到内存 ptrUrl.write(); //透传接口输入参数结构体 HCNetSDK.NET_DVR_XML_CONFIG_INPUT netDvrXmlConfigInput = new HCNetSDK.NET_DVR_XML_CONFIG_INPUT(); //结构体大小 netDvrXmlConfigInput.dwSize = netDvrXmlConfigInput.size(); //请求信令,字符串格式 netDvrXmlConfigInput.lpRequestUrl = ptrUrl.getPointer(); //请求信令长度,字符串长度 netDvrXmlConfigInput.dwRequestUrlLen = url.length(); // 人脸库名称 String strInBuffer = new String("<CreateFDLibList><CreateFDLib><id>" + faceId + "</id><name>" + faceLibName + "</name><thresholdValue>1</thresholdValue><autoUpdata>true</autoUpdata></CreateFDLib></CreateFDLibList>"); HCNetSDK.BYTE_ARRAY ptrByte = new HCNetSDK.BYTE_ARRAY(ISAPI_DATA_LEN); ptrByte.byValue = strInBuffer.getBytes(); ptrByte.write(); netDvrXmlConfigInput.lpInBuffer = ptrByte.getPointer(); netDvrXmlConfigInput.dwInBufferSize = strInBuffer.length(); netDvrXmlConfigInput.write(); HCNetSDK.BYTE_ARRAY ptrStatusByte = new HCNetSDK.BYTE_ARRAY(ISAPI_STATUS_LEN); HCNetSDK.BYTE_ARRAY ptrOutByte = new HCNetSDK.BYTE_ARRAY(ISAPI_DATA_LEN); HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT struXMLOutput = new HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT(); struXMLOutput.dwSize = struXMLOutput.size(); struXMLOutput.lpOutBuffer = ptrOutByte.getPointer(); struXMLOutput.dwOutBufferSize = ptrOutByte.size(); struXMLOutput.lpStatusBuffer = ptrStatusByte.getPointer(); struXMLOutput.dwStatusSize = ptrStatusByte.size(); struXMLOutput.write(); //ISAPI协议命令透传 if (!hCNetSDK.NET_DVR_STDXMLConfig(lUserID, netDvrXmlConfigInput, struXMLOutput)) { System.out.println("NET_DVR_STDXMLConfig失败,错误号:" + hCNetSDK.NET_DVR_GetLastError()); return; } else { struXMLOutput.read(); ptrOutByte.read(); ptrStatusByte.read(); String strOutXML = new String(ptrOutByte.byValue).trim(); System.out.println("获取设备能力集输出结果:" + strOutXML); String xmlStr = struXMLOutput.lpOutBuffer.getString(0); // dom4j解析xml try { Document document; document = DocumentHelper.parseText(xmlStr); Element FDLibInfoList = document.getRootElement(); // 同时迭代当前节点下面的所有子节点 Iterator<Element> iterator = FDLibInfoList.elementIterator(); Element FDLibInfo = iterator.next(); Iterator<Element> iterator2 = FDLibInfo.elementIterator(); while (iterator2.hasNext()) { Element e = iterator2.next(); if (e.getName().equals("FDID")) { String FDID = e.getText(); System.out.println("FDID = " + FDID); } } } catch (DocumentException e1) { e1.printStackTrace(); } } }
-
用户注销,释放SDK
// 用户注销 boolean NET_DVR_Logout(int lUserID); // 释放SDK资源,在程序结束之前调用 boolean NET_DVR_Cleanup();
上传人脸图片到人脸库
- 初始化SDK
NET_DVR_Init
- 用户注册
NET_DVR_Login_V40
- 创建人脸库
NET_DVR_STDXMLConfig
命令: POST /ISAPI/Intelligent/FDLib - 建立人脸数据上传的长链接
NET_DVR_UploadFile_V40(命令:IMPORT_DATA_TO_FACELIB)
- 上传人脸数据(人脸图片+图片附加信息)到人脸库
NET_DVR_UploadSend
- 获取上传状态和进度
NET_DVR_GetUploadState
- 获取结果信息(图片ID)
NET_DVR_GetUploadResult
- 上传结束,断开链接,释放资源
NET_DVR_UploadClose
- 注销用户
NET_DVR_Logout
- 释放SDK资源
NET_DVR_Cleanup
-
上传接口调用流程:
(1) 调用NET_DVR_UploadFile_V40
(命令:IMPORT_DATA_TO_FACELIB)开始上传数据。上传条件里面NET_DVR_FACELIB_COND.byConcurrent赋值为0时不开启并发处理,设备会自动对上传的图片进行建模,如果批量上传大量图片,可以赋值为1开启并发处理,提高速度,但是上传之后需要自己建模。(2) 调用
NET_DVR_UploadSend
发送一张人脸图片数据和附加信息。(3) 上传过程中循环调用
NET_DVR_GetUploadState
获取上传状态和进度。(4) 上传成功之后调用
NET_DVR_GetUploadResult
获取结果信息(图片ID等)。(5) 重复步骤2、3、4,顺序上传其他人脸数据。
(6) 调用
NET_DVR_UploadClose
停止上传,释放资源。
完整代码
HCNetSDK.java
import com.sun.jna.Callback;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.examples.win32.W32API;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
import java.util.Arrays;
import java.util.List;
// SDK接口说明,HCNetSDK.dll
public interface HCNetSDK extends StdCallLibrary {
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("C:\\Users\\ZhangWanPeng\\Desktop\\HCNetSDK.dll", HCNetSDK.class);
// 常量(宏)定义
public static final int NAME_LEN = 32; //用户名长度
public static final int MACADDR_LEN = 6; //mac地址长度
public static final int NET_DVR_DEV_ADDRESS_MAX_LEN = 129;
public static final int NET_DVR_LOGIN_USERNAME_MAX_LEN = 64;
public static final int NET_DVR_LOGIN_PASSWD_MAX_LEN = 64;
public static final int SERIALNO_LEN = 48; //序列号长度
public static final int NET_SDK_CONFIG_STATUS_SUCCESS = 1000;
public static final int NET_SDK_CONFIG_STATUS_NEEDWAIT = 1001;
public static final int NET_SDK_CONFIG_STATUS_FINISH = 1002;
public static final int NET_SDK_CONFIG_STATUS_FAILED = 1003;
public static final int NET_SDK_CONFIG_STATUS_EXCEPTION = 1004;
public static final int IMPORT_DATA_TO_FACELIB = 39; //导入人脸数据(人脸图片+图片附加信息)到人脸库
/**
* 人脸库ID最大长度
*/
public static final int NET_SDK_MAX_FDID_LEN = 256;
// 文件上传URL最大长度
public static final int MAX_UPLOADFILE_URL_LEN = 240;
// 动态库中结构体、接口描述
public static class NET_DVR_USER_LOGIN_INFO extends Structure {
public byte[] sDeviceAddress = new byte[NET_DVR_DEV_ADDRESS_MAX_LEN];
public byte byUseTransport;
public short wPort;
public byte[] sUserName = new byte[NET_DVR_LOGIN_USERNAME_MAX_LEN];
public byte[] sPassword = new byte[NET_DVR_LOGIN_PASSWD_MAX_LEN];
public FLoginResultCallback cbLoginResult;
public Pointer pUser;
public boolean bUseAsynLogin;
public byte byProxyType; // 0:不使用代理,1:使用标准代理,2:使用EHome代理
public byte byUseUTCTime; // 0-不进行转换,默认,1-接口上输入输出全部使用UTC时间,SDK完成UTC时间与设备时区的转换,2-接口上输入输出全部使用平台本地时间,SDK完成平台本地时间与设备时区的转换
public byte byLoginMode; // 0-Private 1-ISAPI 2-自适应
public byte byHttps; // 0-不适用tls,1-使用tls 2-自适应
public int iProxyID; // 代理服务器序号,添加代理服务器信息时,相对应的服务器数组下表值
public byte byVerifyMode; // 认证方式,0-不认证,1-双向认证,2-单向认证;认证仅在使用TLS的时候生效;
public byte[] byRes2 = new byte[119];
// 结构体中重写getFieldOrder方法,FieldOrder顺序要和结构体中定义的顺序保持一致
@Override
protected List getFieldOrder() {
return Arrays.asList("sDeviceAddress", "byUseTransport", "wPort", "sUserName", "sPassword", "cbLoginResult", "pUser", "bUseAsynLogin", "byProxyType", "byUseUTCTime",
"byLoginMode", "byHttps", "iProxyID", "byVerifyMode", "byRes2");
}
}
//NET_DVR_Login_V30()参数结构
public static class NET_DVR_DEVICEINFO_V30 extends Structure {
public byte[] sSerialNumber = new byte[SERIALNO_LEN]; //序列号
public byte byAlarmInPortNum; //报警输入个数
public byte byAlarmOutPortNum; //报警输出个数
public byte byDiskNum; //硬盘个数
public byte byDVRType; //设备类型, 1:DVR 2:ATM DVR 3:DVS ......
public byte byChanNum; //模拟通道个数
public byte byStartChan; //起始通道号,例如DVS-1,DVR - 1
public byte byAudioChanNum; //语音通道数
public byte byIPChanNum; //最大数字通道个数,低位
public byte byZeroChanNum; //零通道编码个数 //2010-01-16
public byte byMainProto; //主码流传输协议类型 0-private, 1-rtsp,2-同时支持private和rtsp
public byte bySubProto; //子码流传输协议类型0-private, 1-rtsp,2-同时支持private和rtsp
public byte bySupport; //能力,位与结果为0表示不支持,1表示支持,
public byte bySupport1; // 能力集扩充,位与结果为0表示不支持,1表示支持
public byte bySupport2; /*能力*/
public short wDevType; //设备型号
public byte bySupport3; //能力集扩展
public byte byMultiStreamProto;//是否支持多码流,按位表示,0-不支持,1-支持,bit1-码流3,bit2-码流4,bit7-主码流,bit-8子码流
public byte byStartDChan; //起始数字通道号,0表示无效
public byte byStartDTalkChan; //起始数字对讲通道号,区别于模拟对讲通道号,0表示无效
public byte byHighDChanNum; //数字通道个数,高位
public byte bySupport4; //能力集扩展
public byte byLanguageType;// 支持语种能力,按位表示,每一位0-不支持,1-支持
// byLanguageType 等于0 表示 老设备
// byLanguageType & 0x1表示支持中文
// byLanguageType & 0x2表示支持英文
public byte byVoiceInChanNum; //音频输入通道数
public byte byStartVoiceInChanNo; //音频输入起始通道号 0表示无效
public byte byRes3; //保留
public byte byMirrorChanNum; //镜像通道个数,<录播主机中用于表示导播通道>
public short wStartMirrorChanNo; //起始镜像通道号
public byte byRes2; //保留
}
//NET_DVR_Login_V40()参数
public static class NET_DVR_DEVICEINFO_V40 extends Structure {
public NET_DVR_DEVICEINFO_V30 struDeviceV30 = new NET_DVR_DEVICEINFO_V30();
public byte bySupportLock;
public byte byRetryLoginTime;
public byte byPasswordLevel;
public byte byProxyType;
public int dwSurplusLockTime;
public byte byCharEncodeType;//字符编码类型:0- 无字符编码信息(老设备),1- GB2312(简体中文),2- GBK,3- BIG5(繁体中文),4- Shift_JIS(日文),5- EUC-KR(韩文),6- UTF-8,7- ISO8859-1,8- ISO8859-2,9- ISO8859-3,…,依次类推,21- ISO8859-15(西欧)
public byte bySupportDev5; //支持v50版本的设备参数获取,设备名称和设备类型名称长度扩展为64字节
public byte byLoginMode; //登录模式 0-Private登录 1-ISAPI登录
public byte[] byRes2 = new byte[253];
}
//预览参数结构体
public static class NET_DVR_PREVIEWINFO extends Structure {
public int lChannel;//通道号
public int dwStreamType; // 码流类型,0-主码流,1-子码流,2-码流3,3-码流4, 4-码流5,5-码流6,7-码流7,8-码流8,9-码流9,10-码流10
public int dwLinkMode;// 0:TCP方式,1:UDP方式,2:多播方式,3 - RTP方式,4-RTP/RTSP,5-RSTP/HTTP ,6- HRUDP(可靠传输) ,7-RTSP/HTTPS
public W32API.HWND hPlayWnd;//播放窗口的句柄,为NULL表示不播放图象
public int bBlocked; //0-非阻塞取流, 1-阻塞取流, 如果阻塞SDK内部connect失败将会有5s的超时才能够返回,不适合于轮询取流操作.
public int bPassbackRecord; //0-不启用录像回传,1启用录像回传
public byte byPreviewMode;//预览模式,0-正常预览,1-延迟预览
public byte[] byStreamID = new byte[32];//流ID,lChannel为0xffffffff时启用此参数
public byte byProtoType; //应用层取流协议,0-私有协议,1-RTSP协议
public byte byRes1;
public byte byVideoCodingType; //码流数据编解码类型 0-通用编码数据 1-热成像探测器产生的原始数据(温度数据的加密信息,通过去加密运算,将原始数据算出真实的温度值)
public int dwDisplayBufNum; //播放库播放缓冲区最大缓冲帧数,范围1-50,置0时默认为1
public byte byNPQMode; //NPQ是直连模式,还是过流媒体 0-直连 1-过流媒体
public byte[] byRes = new byte[215];
}
//上传文件
public static class NET_DVR_UploadFile_V40 extends Structure {
public int lUserID;
public int dwUploadType;
public byte[] lpInBuffer;
}
public static class BYTE_ARRAY extends Structure {
public byte[] byValue;
public BYTE_ARRAY(int iLen) {
byValue = new byte[iLen];
}
}
//JSON数据配置结构体
public static class NET_DVR_JSON_DATA_CFG extends Structure {
public int dwSize; //结构体大小
public Pointer lpJsonData; //JSON报文
public int dwJsonDataSize; //JSON报文大小
public Pointer lpPicData; //图片内容
public int dwPicDataSize; //图片内容大小
public int lpInfraredFacePicBuffer; //红外人脸图片数据缓存
public Pointer dwInfraredFacePicSize; //红外人脸图片数据大小,等于0时,代表无人脸图片数据(当JSON报文为当ResponseStatus(JSON)报文时,该字段无意义;当Inbound Data(JSON)报文中没有infraredFaceURL时,该字段需要带上二进制图片内容)
public byte[] byRes = new byte[248];
}
//报警设备信息
public static class NET_DVR_ALARMER extends Structure {
public byte byUserIDValid; /* userid是否有效 0-无效,1-有效 */
public byte bySerialValid; /* 序列号是否有效 0-无效,1-有效 */
public byte byVersionValid; /* 版本号是否有效 0-无效,1-有效 */
public byte byDeviceNameValid; /* 设备名字是否有效 0-无效,1-有效 */
public byte byMacAddrValid; /* MAC地址是否有效 0-无效,1-有效 */
public byte byLinkPortValid; /* login端口是否有效 0-无效,1-有效 */
public byte byDeviceIPValid; /* 设备IP是否有效 0-无效,1-有效 */
public byte bySocketIPValid; /* socket ip是否有效 0-无效,1-有效 */
public int lUserID; /* NET_DVR_Login()返回值, 布防时有效 */
public byte[] sSerialNumber = new byte[SERIALNO_LEN]; /* 序列号 */
public int dwDeviceVersion; /* 版本信息 高16位表示主版本,低16位表示次版本*/
public byte[] sDeviceName = new byte[NAME_LEN]; /* 设备名字 */
public byte[] byMacAddr = new byte[MACADDR_LEN]; /* MAC地址 */
public short wLinkPort; /* link port */
public byte[] sDeviceIP = new byte[128]; /* IP地址 */
public byte[] sSocketIP = new byte[128]; /* 报警主动上传时的socket IP地址 */
public byte byIpProtocol; /* Ip协议 0-IPV4, 1-IPV6 */
public byte[] byRes2 = new byte[11];
}
/**
* 导入人脸数据(人脸图片+图片附件信息)到人脸库的条件参数结构体
*/
public static class NET_DVR_FACELIB_COND extends Structure {
public int dwSize; //结构体大小
public byte[] szFDID = new byte[256]; //人脸库ID(设备自动生成的FDID或者是自定义的customFaceLibID),唯一标识
public byte byConcurrent; //设备并发处理:0- 不开启(设备自动会建模),1- 开始(设备不会自动进行建模)
public byte byCover; //是否覆盖式导入(人脸库存储满的情况下强制覆盖导入时间最久的图片数据):0- 否,1- 是
public byte byCustomFaceLibID; //人脸库ID是否是自定义:0- 不是,1- 是
public byte byRes1; //保留,置为0
public byte[] byIdentityKey = new byte[64]; //交互操作口令
public byte[] byRes = new byte[60]; //保留,置为0
}
//数据发送输入参数结构体
public static class NET_DVR_SEND_PARAM_IN extends Structure {
public Pointer pSendData; //发送的缓冲区,PicURL == 1 的时候,内存中存储的是 URL 字符串,byUploadModeling == 1 的时候,内存中存储的是 建模base64加密数据
public int dwSendDataLen; //发送数据长度,PicURL == 1 的时候,表示的 URL 字符串的长度,byUploadModeling == 1 的时候,表示为建模数据base64后的加密长度
public NET_DVR_TIME_V30 struTime = new NET_DVR_TIME_V30(); //图片时间
public byte byPicType; //图片格式,1-jpg,2-bmp,3-png,4-SWF,5-GIF
public byte byPicURL; //图片数据采用URL方式 0-二进制图片数据,1-图片数据走URL方式
/*是否上传建模数据;
0- 二进制图片数据方式(pSendData指向二进制图片数据, dwPicDataLen为图片二进制数据长度),
1- 直接上传建模数据(pSendData指向建模base64加密数据, dwPicDataLen为建模数据base64后的加密长度)。
注:建模数据采用base64加密方式,选择为建模数据上传后,byPicURL 无需。
当”/ISAPI/Intelligent/channels/<ID>/faceContrast/capabilities”能力中返回isSupportUploadModeling能力节点时,支持上传建模数据. */
public byte byUploadModeling;
public byte byRes1;
public int dwPicMangeNo; //图片管理号
public byte[] sPicName = new byte[NAME_LEN]; //图片名称
public int dwPicDisplayTime; //图片播放时长,单位秒
public Pointer pSendAppendData; //发送图片的附加信息缓冲区,对应FaceAppendData 的XML描述;
public int dwSendAppendDataLen; //发送图片的附加信息数据长度 FaceAppendData XML的长度;
public byte[] byRes = new byte[192];
}
/**
* 文件上传结果信息结构体
*/
public static class NET_DVR_UPLOAD_FILE_RET extends Structure {
public byte[] sUrl = new byte[MAX_UPLOADFILE_URL_LEN]; //文件上传返回的URL或者ID
public byte[] byRes = new byte[260]; //保留
}
public static class NET_DVR_TIME_V30 extends Structure {
public short wYear;
public byte byMonth;
public byte byDay;
public byte byHour;
public byte byMinute;
public byte bySecond;
public byte byRes;
public short wMilliSec;
public byte[] byRes1 = new byte[2];
}
/**
* 透传接口输入参数结构体
*/
public static class NET_DVR_XML_CONFIG_INPUT extends Structure {
public int dwSize; //结构体大小
public Pointer lpRequestUrl; //请求信令,字符串格式
public int dwRequestUrlLen; //请求信令长度,字符串长度
public Pointer lpInBuffer; //输入参数缓冲区,XML/JSON格式
public int dwInBufferSize; //输入参数缓冲区大小
public int dwRecvTimeOut; //报文分段个数:0- 无效; 其他- lpInBuffer传入NET_DVR_MIME_UNIT结构体指针,该值即代表结构体个数
public byte[] byRes = new byte[32]; //保留,置为0
}
/**
* 透传接口输出参数结构体
*/
public static class NET_DVR_XML_CONFIG_OUTPUT extends Structure {
public int dwSize; //结构体大小
public Pointer lpOutBuffer; //输出参数缓冲区,XML/JSON格式,请求信令为“GET”类型时应用层需要事先分配足够大的内存
public int dwOutBufferSize; //输出参数缓冲区大小(内存大小)
public int dwReturnedXMLSize; //实际输出的XML/JSON内容大小
public Pointer lpStatusBuffer; //返回的状态参数(XML/JSON格式:ResponseStatus),获取命令成功时不会赋值,如果不需要,可以置NULL
public int dwStatusSize; //状态缓冲区大小(内存大小)
public byte[] byRes = new byte[32]; //保留,置为0
}
public static interface FRemoteConfigCallBack extends StdCallCallback {
public void invoke(int dwType, Pointer lpBuffer, int dwBufLen, Pointer pUserData);
}
/*** API函数声明 ***/
// 初始化SDK,调用其他SDK函数的前提
boolean NET_DVR_Init();
/**
* 启用日志文件写入接口
*
* @param bLogEnable 日志的等级(默认为0):0-表示关闭日志,1-表示只输出ERROR错误日志,2-输出ERROR错误信息和DEBUG调试信息,3-输出ERROR错误信息、DEBUG调试信息和INFO普通信息等所有信息
* @param strLogDir 日志文件的路径,windows默认值为"C:\\SdkLog\\";linux默认值"/home/sdklog/"
* @param bAutoDel 是否删除超出的文件数,默认值为TRUE
* @return
*/
boolean NET_DVR_SetLogToFile(int bLogEnable, String strLogDir, boolean bAutoDel);
// 返回最后操作的错误码
int NET_DVR_GetLastError();
// 释放SDK资源,在程序结束之前调用
boolean NET_DVR_Cleanup();
// 登录接口
int NET_DVR_Login_V40(NET_DVR_USER_LOGIN_INFO pLoginInfo, NET_DVR_DEVICEINFO_V40 lpDeviceInfo);
// 用户注销
boolean NET_DVR_Logout(int lUserID);
// 回调函数申明
public static interface FLoginResultCallback extends StdCallCallback {
// 登录状态回调函数
public int invoke(int lUserID, int dwResult, NET_DVR_DEVICEINFO_V30 lpDeviceinfo, Pointer pUser);
}
public static interface FRealDataCallback_V30 extends Callback {
public void invoke(int lRealHandle, int dwDataType,
ByteByReference pBuffer, int dwBufSize, Pointer pUser);
}
public static interface FMSGCallBack_V31 extends StdCallCallback {
public boolean invoke(int lCommand, NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser);
}
// 设置网络连接超时时间和连接尝试次数。
boolean NET_DVR_SetConnectTime(int dwWaitTime, int dwTryTimes);
// NET_DVR_SetReconnect
boolean NET_DVR_SetReconnect(int dwInterval, int bEnableRecon);
/**
* 上传文件
*
* @param lUserID NET_DVR_Login_V40等登录接口的返回值
* @param dwUploadType 上传文件类型
* @param lpInBuffer 输入参数
* @param dwInBufferSize 输入缓冲区大小
* @param sFileName 上传文件的路径(包括文件名)
* @param lpOutBuffer 输出参数
* @param dwOutBufferSize 输出缓冲区大小
* @return
*/
int NET_DVR_UploadFile_V40(int lUserID, int dwUploadType, Pointer lpInBuffer, int dwInBufferSize, String sFileName, Pointer lpOutBuffer, int dwOutBufferSize);
/**
* 发送数据
*
* @param lUploadHandle 文件上传句柄,NET_DVR_UploadFile_V40的返回值
* @param pstruSendParamIN 上传的数据内容
* @param lpOutBuffer 输出参数,保留,置为NULL
* @return
*/
int NET_DVR_UploadSend(int lUploadHandle, Pointer pstruSendParamIN, Void lpOutBuffer);
//启动远程配置
int NET_DVR_StartRemoteConfig(int lUserID, int dwCommand, Pointer lpInBuffer, int dwInBufferLen, FRemoteConfigCallBack cbStateCallBack, Pointer pUserData);
int NET_DVR_SendWithRecvRemoteConfig(int lHandle, Pointer lpInBuff, int dwInBuffSize, Pointer lpOutBuff, int dwOutBuffSize, IntByReference dwOutDataLen);
boolean NET_DVR_StopRemoteConfig(int lHandle);
//获取设备能力集
boolean NET_DVR_GetDeviceAbility(int lUserID, int dwAbilityType, Pointer pInBuf, int dwInLength, Pointer pOutBuf, int dwOutLength);
boolean NET_DVR_SetDVRMessageCallBack_V31(FMSGCallBack_V31 fMessageCallBack, Pointer pUser);
/**
* 获取文件上传的进度和状态
*
* @param lUploadHandle 文件上传的句柄,NET_DVR_UploadFile_V40的返回值
* @param pProgress 返回的进度值,0~100
* @return
*/
int NET_DVR_GetUploadState(int lUploadHandle, Pointer pProgress);
/**
* 获取当前上传的结果信息
*
* @param lUploadHandle 文件上传的句柄,NET_DVR_UploadFile_V40的返回值
* @param lpOutBuffer 结果信息缓冲区
* @param dwOutBufferSize 缓冲区大小
* @return
*/
boolean NET_DVR_GetUploadResult(int lUploadHandle, Pointer lpOutBuffer, int dwOutBufferSize);
//停止文件上传
boolean NET_DVR_UploadClose(int lUploadHandle);
//ISAPI协议命令透传
boolean NET_DVR_STDXMLConfig(int lUserID, NET_DVR_XML_CONFIG_INPUT lpInputParam, NET_DVR_XML_CONFIG_OUTPUT lpOutputParam);
}
UploadFaceUtil.java
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author ZWP
* @date 2022/1/28 14:00
*/
public class UploadFaceUtil {
HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
/**
* SDK登录
*
* @param m_sDeviceIP 设备ip地址
* @param wPort 端口号,设备网络SDK登录默认端口8000
* @param m_sUsername 用户名
* @param m_sPassword 密码
* @return
*/
public int login(String m_sDeviceIP, short wPort, String m_sUsername, String m_sPassword) {
// 初始化
boolean initSuc = hCNetSDK.NET_DVR_Init();
if (!initSuc) {
System.out.println("初始化失败");
return -1;
}
// 打印SDK日志
hCNetSDK.NET_DVR_SetLogToFile(3, ".\\SDKLog\\", false);
/* 注册 */
// 设备登录信息
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
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.wPort = wPort;
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());
// 是否异步登录:false- 否,true- 是
m_strLoginInfo.bUseAsynLogin = false;
// write()调用后数据才写入到内存中
m_strLoginInfo.write();
// 设备信息
HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (lUserID == -1) {
System.out.println("登录失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());
} else {
System.out.println("登录成功!");
// read()后,结构体中才有对应的数据
m_strDeviceInfo.read();
}
return lUserID;
}
/**
* 设备注销 SDK释放
*/
public void logout(int lUserID) {
if (lUserID >= 0) {
// 注销
if (!hCNetSDK.NET_DVR_Logout(lUserID)) {
System.out.println("注销失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
}
System.out.println("注销成功");
// 释放SDK资源
hCNetSDK.NET_DVR_Cleanup();
} else {
System.out.println("设备未登录");
hCNetSDK.NET_DVR_Cleanup();
}
}
/**
* 建立图片上传连接
*
* @param lUserID 用户句柄(登录的返回值)
* @param strFDID 人脸库ID(设备自动生成的FDID或者是自定义的customFaceLibID),唯一标识
*/
public int faceupload(int lUserID, String strFDID) {
HCNetSDK.NET_DVR_FACELIB_COND struInput = new HCNetSDK.NET_DVR_FACELIB_COND();
//结构体大小
struInput.dwSize = struInput.size();
//设备并发处理:0- 不开启(设备自动会建模),1- 开始(设备不会自动进行建模)
struInput.byConcurrent = 0;
//人脸库ID是否是自定义:0- 不是,1- 是
struInput.byCustomFaceLibID = 0;
//是否覆盖式导入(人脸库存储满的情况下强制覆盖导入时间最久的图片数据):0- 否,1- 是
struInput.byCover = 1;
struInput.szFDID = new byte[HCNetSDK.NET_SDK_MAX_FDID_LEN]; //人脸库ID最大长度 256
//将指定源数组中的数组从指定位置复制到目标数组的指定位置。
System.arraycopy(strFDID.getBytes(), 0, struInput.szFDID, 0, strFDID.getBytes().length);
//数据写入到内存中
struInput.write();
// 获取Pointer对象
Pointer inputPointer = struInput.getPointer();
// 上传人脸图片
int uploadFileV40 = hCNetSDK.NET_DVR_UploadFile_V40(lUserID, HCNetSDK.IMPORT_DATA_TO_FACELIB, inputPointer, struInput.size(), null, null, 0);
if (uploadFileV40 == -1) {
System.out.println("上传失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());
} else {
System.out.println("上传成功!");
}
return uploadFileV40;
}
/**
* 上传图片
*
* @param lUploadHandle 文件上传的句柄
* @param picPath 图片路径
* @param dataXMLPath XML文件路径
*/
public void uploadSend(int lUploadHandle, String picPath, String dataXMLPath) {
//图片文件
FileInputStream picfile = null;
//XML文件(附加消息)
FileInputStream xmlfile = null;
int picdataLength = 0;
int xmldataLength = 0;
try {
// 创建文件
picfile = new FileInputStream(new File(System.getProperty("user.dir") + picPath));
xmlfile = new FileInputStream(new File(System.getProperty("user.dir") + dataXMLPath));
// 获取文件的字节数
picdataLength = picfile.available();
xmldataLength = xmlfile.available();
} catch (IOException e) {
e.printStackTrace();
}
if (picdataLength < 0 || xmldataLength < 0) {
System.out.println("上传图片大小/xml文件大小 < 0");
return;
}
HCNetSDK.BYTE_ARRAY ptrpicByte = new HCNetSDK.BYTE_ARRAY(picdataLength);
HCNetSDK.BYTE_ARRAY ptrxmlByte = new HCNetSDK.BYTE_ARRAY(xmldataLength);
try {
// 从内存中读取数据到byte数组
picfile.read(ptrpicByte.byValue);
xmlfile.read(ptrxmlByte.byValue);
} catch (IOException e) {
e.printStackTrace();
}
//数据写入到内存中
ptrpicByte.write();
ptrxmlByte.write();
HCNetSDK.NET_DVR_SEND_PARAM_IN netDvrSendParamIn = new HCNetSDK.NET_DVR_SEND_PARAM_IN();
//图片格式:1- jpg,2- bmp,3- png,4- SWF,5- GIF
netDvrSendParamIn.byPicType = 1;
// 图片管理号,人脸库不支持,设为0
netDvrSendParamIn.dwPicMangeNo = 0;
// 图片播放时长,单位:秒,人脸库不支持,设为0
netDvrSendParamIn.dwPicDisplayTime = 0;
netDvrSendParamIn.byPicURL = 0;
// 发送的缓冲区,PicURL == 1 的时候,内存中存储的是 URL 字符串,byUploadModeling == 1 的时候,内存中存储的是 建模base64加密数据
netDvrSendParamIn.pSendData = ptrpicByte.getPointer();
// 发送数据长度,PicURL == 1 的时候,表示的 URL 字符串的长度,byUploadModeling == 1 的时候,表示为建模数据base64后的加密长度
netDvrSendParamIn.dwSendDataLen = picdataLength;
// 发送图片的附加信息缓冲区,对应FaceAppendData 的XML描述;
netDvrSendParamIn.pSendAppendData = ptrxmlByte.getPointer();
// 发送图片的附加信息数据长度 FaceAppendData XML的长度;
netDvrSendParamIn.dwSendAppendDataLen = xmldataLength;
//数据写入到内存中
netDvrSendParamIn.write();
// 发送数据
int dvrUploadSend = hCNetSDK.NET_DVR_UploadSend(lUploadHandle, netDvrSendParamIn.getPointer(), null);
if (dvrUploadSend == -1) {
System.out.println("发送数据失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());
return;
} else {
System.out.println("发送数据成功!");
}
// 关闭流
try {
picfile.close();
xmlfile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取上传状态和进度
*
* @param lUploadHandle 文件上传的句柄
*/
public int getUploadState(int lUploadHandle) throws InterruptedException {
Thread.sleep(500);
// 原生整型引用
IntByReference pInt = new IntByReference(0);
int netDvrGetUploadState = hCNetSDK.NET_DVR_GetUploadState(lUploadHandle, pInt.getPointer());
switch (netDvrGetUploadState) {
case -1:
System.out.println("获取文件上传的进度和状态失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());
break;
case 1:
System.out.println("progress = " + pInt.getValue());
System.out.println("获取文件上传的进度和状态成功!");
break;
case 2:
System.out.println("正在上传!!!! progress = " + pInt.getValue());
break;
default:
System.out.println("获取文件上传的进度和状态失败!,接口返回值为 = " + netDvrGetUploadState);
System.out.println("获取文件上传的进度和状态失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());
break;
}
return netDvrGetUploadState;
}
/**
* 获取结果信息(图片ID等)
*
* @param lUploadHandle 文件上传的句柄
*/
public String getUploadResult(int lUploadHandle) {
// 图片ID
String picID = null;
// 文件上传结果信息结构体
HCNetSDK.NET_DVR_UPLOAD_FILE_RET netDvrUploadFileRet = new HCNetSDK.NET_DVR_UPLOAD_FILE_RET();
// 数据写入到内存中
netDvrUploadFileRet.write();
// 获取结果信息
if (!hCNetSDK.NET_DVR_GetUploadResult(lUploadHandle, netDvrUploadFileRet.getPointer(), netDvrUploadFileRet.size())) {
System.out.println("获取结果信息失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());
} else {
// 从内存中读取数据
netDvrUploadFileRet.read();
// 文件上传返回的URL或者ID
picID = String.valueOf(netDvrUploadFileRet.sUrl).trim();
System.out.println("图片上传成功 PicID:" + picID);
}
return picID;
}
}
UploadFace.java
/**
* @author ZWP
* @date 2022/1/28 13:58
*/
public class UploadFace {
static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
static int lUserID = -1;//用户句柄
static int m_lUploadHandle = -1;//文件上传句柄
static int m_UploadStatus = -1;//上传进度值
public static void main(String[] args) throws InterruptedException {
UploadFaceUtil uploadFaceUtil = new UploadFaceUtil();
// 用户登陆操作==初始化==打印SDK日志
lUserID = uploadFaceUtil.login("192.168.7.43", (short) 8000, "admin", "123456");
// step1:创建人脸库
// step2:建立图片上传的长连接
m_lUploadHandle = uploadFaceUtil.faceupload(lUserID, "06CD85AED2FE4F82B7FD7C878EDD91BF");
if (m_lUploadHandle == -1) {
return;
}
// step3:上传图片
uploadFaceUtil.uploadSend(m_lUploadHandle, "\\pic\\face.jpg", "\\pic\\data.xml");
// step4:获取上传状态和进度
m_UploadStatus = uploadFaceUtil.getUploadState(m_lUploadHandle);
if (m_UploadStatus == 1) {
// step5:上传成功之后调用NET_DVR_GetUploadResult获取结果信息(图片ID等)。
String uploadResult = uploadFaceUtil.getUploadResult(m_lUploadHandle);
System.out.println("PicID:" + uploadResult);
}
if (m_UploadStatus >= 3 || m_UploadStatus == -1) {
System.out.println("m_UploadStatus = " + m_UploadStatus);
m_lUploadHandle = -1;
}
// step6:停止文件上传
hCNetSDK.NET_DVR_UploadClose(m_lUploadHandle);
// 线程睡眠5秒钟
Thread.sleep(5000);
// step7:用户注销,释放SDK
uploadFaceUtil.logout(lUserID);
}
}
data.xml
<FaceAppendData>
<bornTime>2022-01-28</bornTime>
<name>张万鹏</name>
<sex>male</sex>
<province>11</province>
<city>01</city>
<certificateType>officerID</certificateType>
<certificateNumber>1123123123</certificateNumber>
<PersonInfoExtendList>
<PersonInfoExtend>
<id>1</id>
<enable>false</enable>
<name>test1</name>
<value>test2</value>
</PersonInfoExtend>
</PersonInfoExtendList>
</FaceAppendData>