使用Java調(diào)用??低昐DK實(shí)現(xiàn)攝像頭預(yù)覽超詳細(xì)教程
本文提供完整可運(yùn)行的Java代碼示例,通過JNA調(diào)用??低昐DK實(shí)現(xiàn)攝像頭實(shí)時(shí)預(yù)覽,包含關(guān)鍵錯(cuò)誤處理和資源釋放邏輯。
一、環(huán)境準(zhǔn)備(關(guān)鍵步驟)
SDK下載
從??低曢_放平臺(tái)下載最新SDK(選擇對(duì)應(yīng)系統(tǒng)版本)- Windows:
HCNetSDK.dll
,PlayCtrl.dll
,HCNetSDKCom
文件夾 - Linux:
libhcnetsdk.so
- Windows:
項(xiàng)目配置
src/
├── main/
│ ├── java/
│ │ └── com/example/HikvisionDemo.java
│ └── resources/
│ └── sdk/ # 存放所有dll/so文件
Maven依賴
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency>
二、核心代碼實(shí)現(xiàn)(帶詳細(xì)注釋)
import com.sun.jna.*; import com.sun.jna.ptr.IntByReference; import java.io.File; public class HikvisionDemo { // 1. 定義SDK接口 public interface HCNetSDK extends Library { HCNetSDK INSTANCE = Native.load( System.getProperty("user.dir") + "/src/main/resources/sdk/HCNetSDK", HCNetSDK.class ); // 初始化SDK(必須優(yōu)先調(diào)用) boolean NET_DVR_Init(); // 設(shè)備登錄 int NET_DVR_Login_V30(String ip, int port, String user, String pwd, NET_DVR_DEVICEINFO_V30 deviceInfo); // 啟動(dòng)預(yù)覽 int NET_DVR_RealPlay_V30(int userId, NET_DVR_CLIENTINFO clientInfo, FRealDataCallBack_V30 callback, Pointer user); // 停止預(yù)覽 boolean NET_DVR_StopRealPlay(int handle); // 注銷登錄 boolean NET_DVR_Logout(int userId); // 清理SDK boolean NET_DVR_Cleanup(); // 回調(diào)函數(shù)接口(處理視頻流) interface FRealDataCallBack_V30 extends Callback { void invoke(int realHandle, int dataType, byte[] buffer, int bufSize, Pointer user); } } // 2. 設(shè)備信息結(jié)構(gòu)體 public static class NET_DVR_DEVICEINFO_V30 extends Structure { public byte[] sSerialNumber = new byte[48]; // 序列號(hào) public int byChanNum; // 通道數(shù) public int byStartChan; // 起始通道號(hào) // ... 其他字段省略(實(shí)際需補(bǔ)全) } // 3. 預(yù)覽參數(shù)結(jié)構(gòu)體 public static class NET_DVR_CLIENTINFO extends Structure { public int lChannel; // 通道號(hào)(從1開始) public int hPlayWnd; // 窗口句柄(0表示不顯示窗口) // ... 其他字段省略 } public static void main(String[] args) { // 初始化SDK if (!HCNetSDK.INSTANCE.NET_DVR_Init()) { System.err.println("SDK初始化失?。″e(cuò)誤碼:" + getLastError()); return; } // 設(shè)備登錄 NET_DVR_DEVICEINFO_V30 deviceInfo = new NET_DVR_DEVICEINFO_V30(); int userId = HCNetSDK.INSTANCE.NET_DVR_Login_V30( "192.168.1.64", // 攝像頭IP 8000, // 端口(默認(rèn)8000) "admin", // 用戶名 "hik12345", // 密碼 deviceInfo ); if (userId < 0) { System.err.println("登錄失?。″e(cuò)誤碼:" + getLastError()); cleanup(); return; } System.out.println("登錄成功!用戶ID: " + userId); // 啟動(dòng)預(yù)覽(回調(diào)函數(shù)接收視頻流) NET_DVR_CLIENTINFO clientInfo = new NET_DVR_CLIENTINFO(); clientInfo.lChannel = 1; // 通道號(hào)(根據(jù)設(shè)備信息設(shè)置) clientInfo.hPlayWnd = 0; // 0表示不顯示窗口(若需GUI顯示需設(shè)置實(shí)際句柄) HCNetSDK.FRealDataCallBack_V30 callback = (realHandle, dataType, buffer, bufSize, user) -> { if (dataType == 0) System.out.println("實(shí)時(shí)視頻數(shù)據(jù): " + bufSize + " bytes"); // 此處可擴(kuò)展:視頻流解碼/保存/推流等 }; int playHandle = HCNetSDK.INSTANCE.NET_DVR_RealPlay_V30( userId, clientInfo, callback, null ); if (playHandle < 0) { System.err.println("預(yù)覽失??!錯(cuò)誤碼:" + getLastError()); logout(userId); return; } System.out.println("預(yù)覽啟動(dòng)成功,按Enter鍵退出..."); System.in.read(); // 阻塞等待 // 資源釋放(必須執(zhí)行) HCNetSDK.INSTANCE.NET_DVR_StopRealPlay(playHandle); logout(userId); } // 獲取最新錯(cuò)誤碼 private static int getLastError() { return HCNetSDK.INSTANCE.NET_DVR_GetLastError(); } // 安全注銷 private static void logout(int userId) { HCNetSDK.INSTANCE.NET_DVR_Logout(userId); cleanup(); } // 清理SDK private static void cleanup() { HCNetSDK.INSTANCE.NET_DVR_Cleanup(); } }
三、關(guān)鍵注意事項(xiàng)
錯(cuò)誤處理規(guī)范
- 每次SDK調(diào)用后檢查返回值
- 使用
NET_DVR_GetLastError()
獲取錯(cuò)誤碼(錯(cuò)誤碼列表) - 典型錯(cuò)誤:
1
:用戶名密碼錯(cuò)誤7
:通道號(hào)無效10
:設(shè)備不在線
視頻流處理擴(kuò)展
- 在回調(diào)函數(shù)中:
if (dataType == 0) { // 視頻幀 saveToFile(buffer, bufSize); // 保存為MP4 } else if (dataType == 1) { // 音頻幀 // 處理音頻 }
- 在回調(diào)函數(shù)中:
多平臺(tái)兼容方案
// 動(dòng)態(tài)加載庫路徑 String libPath = System.getProperty("os.name").contains("Win") ? "sdk/HCNetSDK.dll" : "sdk/libhcnetsdk.so"; HCNetSDK.INSTANCE = Native.load(libPath, HCNetSDK.class);
四、常見問題解決
問題現(xiàn)象 | 解決方案 |
---|---|
UnsatisfiedLinkError | 確認(rèn)dll/so文件路徑正確且位數(shù)匹配(x86/x64) |
預(yù)覽無視頻流 | 檢查通道號(hào)是否匹配設(shè)備支持的通道范圍 |
高CPU占用 | 在回調(diào)函數(shù)中避免阻塞操作,改用隊(duì)列異步處理 |
內(nèi)存泄漏 | 確保NET_DVR_Cleanup() 在程序退出前被執(zhí)行 |
最佳實(shí)踐:生產(chǎn)環(huán)境建議添加
NET_DVR_SetConnectTime(3000)
設(shè)置超時(shí),避免線程阻塞。
通過以上步驟,即可穩(wěn)定實(shí)現(xiàn)攝像頭預(yù)覽功能。擴(kuò)展功能(如抓圖、錄像)需調(diào)用SDK中對(duì)應(yīng)的NET_DVR_CaptureJPEGPicture
和NET_DVR_SaveRealData
接口。
到此這篇關(guān)于使用Java調(diào)用海康威視SDK實(shí)現(xiàn)攝像頭預(yù)覽的文章就介紹到這了,更多相關(guān)Java??低昐DK實(shí)現(xiàn)攝像頭預(yù)覽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MAC上IntelliJ IDEA的svn無法保存密碼解決方案
今天小編就為大家分享一篇關(guān)于MAC上IntelliJ IDEA的svn無法保存密碼解決方案,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10Mybatis結(jié)果集自動(dòng)映射的實(shí)例代碼
在使用Mybatis時(shí),有的時(shí)候我們可以不用定義resultMap,而是直接在<select>語句上指定resultType。這個(gè)時(shí)候其實(shí)就用到了Mybatis的結(jié)果集自動(dòng)映射,下面通過本文給大家分享Mybatis結(jié)果集自動(dòng)映射的實(shí)例代碼,一起看看吧2017-02-02Java通過PowerMockito和Mokito進(jìn)行單元測(cè)試的實(shí)現(xiàn)
PowerMockito和Mockito都是Java語言中的測(cè)試框架,用于進(jìn)行單元測(cè)試和集成測(cè)試,本文就來詳細(xì)的介紹一下通過PowerMockito和Mokito進(jìn)行單元測(cè)試,感興趣的可以了解一下2023-08-08SpringBoot實(shí)現(xiàn)多租戶架構(gòu)
在SpringBoot中可以通過多數(shù)據(jù)源和動(dòng)態(tài)路由來實(shí)現(xiàn)多租戶機(jī)制,本文主要介紹了SpringBoot實(shí)現(xiàn)多租戶架構(gòu),具有一定的參考價(jià)值,感興趣的可以里哦啊接一下2024-03-03java圖片色階調(diào)整和亮度調(diào)整代碼示例
這篇文章主要介紹了java圖片色階調(diào)整和亮度調(diào)整代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11springboot starter介紹與自定義starter示例詳解
Spring Boot 的 Starter 是一組比較方便的依賴描述符,可以通過 Maven 將其打成jar包,并在你的項(xiàng)目中直接引用,這篇文章主要介紹了springboot starter介紹與自定義starter示例,需要的朋友可以參考下2025-05-05springboot2.3 整合mybatis-plus 高級(jí)功能(圖文詳解)
這篇文章主要介紹了springboot2.3 整合mybatis-plus 高級(jí)功能,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08Springboot之如何統(tǒng)計(jì)代碼執(zhí)行耗時(shí)時(shí)間
這篇文章主要介紹了Springboot之如何統(tǒng)計(jì)代碼執(zhí)行耗時(shí)時(shí)間問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03