海康NVR設備上傳人臉圖片到人臉庫
海康開放平台——海康文檔鏈接——海康開發包和文檔下載鏈接
硬體:海康超腦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>