> 技术文档 > 使用Java调用海康威视SDK实现摄像头预览(详细教程)_java调用海康sdk

使用Java调用海康威视SDK实现摄像头预览(详细教程)_java调用海康sdk


本文提供完整可运行的Java代码示例,通过JNA调用海康威视SDK实现摄像头实时预览,包含关键错误处理和资源释放逻辑。


一、环境准备(关键步骤)
  1. SDK下载
    从海康威视开放平台下载最新SDK(选择对应系统版本)

    • Windows:HCNetSDK.dll, PlayCtrl.dll, HCNetSDKCom文件夹
    • Linux:libhcnetsdk.so
  2. 项目配置

    src/├── main/│ ├── java/│ │ └── com/example/HikvisionDemo.java│ └── resources/│ └── sdk/ # 存放所有dll/so文件
  3. Maven依赖

     net.java.dev.jna jna 5.13.0

二、核心代码实现(带详细注释)
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(必须优先调用) boolean NET_DVR_Init(); // 设备登录 int NET_DVR_Login_V30(String ip, int port, String user, String pwd, NET_DVR_DEVICEINFO_V30 deviceInfo); // 启动预览 int NET_DVR_RealPlay_V30(int userId, NET_DVR_CLIENTINFO clientInfo, FRealDataCallBack_V30 callback, Pointer user); // 停止预览 boolean NET_DVR_StopRealPlay(int handle); // 注销登录 boolean NET_DVR_Logout(int userId); // 清理SDK boolean NET_DVR_Cleanup(); // 回调函数接口(处理视频流) interface FRealDataCallBack_V30 extends Callback { void invoke(int realHandle, int dataType, byte[] buffer, int bufSize, Pointer user); } } // 2. 设备信息结构体 public static class NET_DVR_DEVICEINFO_V30 extends Structure { public byte[] sSerialNumber = new byte[48]; // 序列号 public int byChanNum; // 通道数 public int byStartChan; // 起始通道号 // ... 其他字段省略(实际需补全) } // 3. 预览参数结构体 public static class NET_DVR_CLIENTINFO extends Structure { public int lChannel; // 通道号(从1开始) public int hPlayWnd; // 窗口句柄(0表示不显示窗口) // ... 其他字段省略 } public static void main(String[] args) { // 初始化SDK if (!HCNetSDK.INSTANCE.NET_DVR_Init()) { System.err.println(\"SDK初始化失败!错误码:\" + getLastError()); return; } // 设备登录 NET_DVR_DEVICEINFO_V30 deviceInfo = new NET_DVR_DEVICEINFO_V30(); int userId = HCNetSDK.INSTANCE.NET_DVR_Login_V30( \"192.168.1.64\", // 摄像头IP 8000, // 端口(默认8000) \"admin\",  // 用户名 \"hik12345\", // 密码 deviceInfo ); if (userId  { if (dataType == 0) System.out.println(\"实时视频数据: \" + bufSize + \" bytes\"); // 此处可扩展:视频流解码/保存/推流等 }; int playHandle = HCNetSDK.INSTANCE.NET_DVR_RealPlay_V30( userId, clientInfo, callback, null ); if (playHandle < 0) { System.err.println(\"预览失败!错误码:\" + getLastError()); logout(userId); return; } System.out.println(\"预览启动成功,按Enter键退出...\"); System.in.read(); // 阻塞等待 // 资源释放(必须执行) HCNetSDK.INSTANCE.NET_DVR_StopRealPlay(playHandle); logout(userId); } // 获取最新错误码 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(); }}

三、关键注意事项
  1. 错误处理规范

    • 每次SDK调用后检查返回值
    • 使用NET_DVR_GetLastError()获取错误码(错误码列表)
    • 典型错误:
      • 1:用户名密码错误
      • 7:通道号无效
      • 10:设备不在线
  2. 视频流处理扩展

    • 在回调函数中:
      if (dataType == 0) { // 视频帧 saveToFile(buffer, bufSize); // 保存为MP4} else if (dataType == 1) { // 音频帧 // 处理音频}
  3. 多平台兼容方案

    // 动态加载库路径String libPath = System.getProperty(\"os.name\").contains(\"Win\") ? \"sdk/HCNetSDK.dll\" : \"sdk/libhcnetsdk.so\";HCNetSDK.INSTANCE = Native.load(libPath, HCNetSDK.class);

四、常见问题解决
问题现象 解决方案 UnsatisfiedLinkError 确认dll/so文件路径正确且位数匹配(x86/x64) 预览无视频流 检查通道号是否匹配设备支持的通道范围 高CPU占用 在回调函数中避免阻塞操作,改用队列异步处理 内存泄漏 确保NET_DVR_Cleanup()在程序退出前被执行

最佳实践:生产环境建议添加NET_DVR_SetConnectTime(3000)设置超时,避免线程阻塞。

通过以上步骤,即可稳定实现摄像头预览功能。扩展功能(如抓图、录像)需调用SDK中对应的NET_DVR_CaptureJPEGPictureNET_DVR_SaveRealData接口。