开发者

使用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文件

  1. Maven依赖

    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>5.13.0</version>
    </dependency>
    

二、核心代码实现(带详细注释)

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_DEVIphpCEINFO_V30();
        int userId = HCNetSDK.INSTANCE.NET_DVR_Login_V30(
            "192.168.1.64",  // 摄像头IP
            8000,             // 端口(默认8000)
            "admin",           // 用户名
            "hik12345",        // 密码
            deviceInfo
        );
        
        if (userId < 0) {
            System.err.println("登录失败!错误码:" + getLastError());
            cleanup();
            return;
        }
        System.out.println("登录成功!用户ID: " + userId);

        // 启动预览(回调函数接收视频流)
        NET_DVR_CLIENTINFO clientInfo = new NET_DVR_CLIENTINFO();
        clientInfo.lChannel = 1;  // 通道号(根据设备信息设置)
        clientInfo.hPlayWnd = 0;  // 0表示不显示窗口(若需GUI显示需设置实际句柄)

        HCNetSDK.FRealDataCallBapythonck_V30 callback = (realHandle, dataType, buffer, bufSize, user) -> {
            if (dataType == 0) System.out.println("实时视频数据: " + bufSize + " bytes");
            // 此处可扩展:视频流解码/保存/推流等
   php     };

        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接口。

到此这篇关于使用Java调用海康威视SDK实现摄像头预览的文章就介绍到这了,更多相关Java海康威视SDK实现摄像头预览内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜