一、环境准备
1. 硬件要求
- 海康威视网络摄像头(如DS-2CD2系列)
- 支持Java开发的计算机
- 网络连接设备(确保摄像头与计算机在同一网络)
![图片[1]_使用Java调用海康威视SDK实现摄像头预览超详细教程_知途无界](https://zhituwujie.com/wp-content/uploads/2025/07/d2b5ca33bd20250717093218.png)
2. 软件准备
- JDK 1.8或更高版本
- IDE(Eclipse/IntelliJ IDEA)
- 海康威视SDK开发包(HCNetSDK)
3. SDK下载与配置
- 访问海康威视开放平台下载最新SDK
- 解压后得到以下关键文件:
HCNetSDK.jar(Java开发包)hcnetsdk.dll(Windows平台动态库)libhcnetsdk.so(Linux平台动态库)
二、项目配置
1. 创建Java项目
mvn archetype:generate -DgroupId=com.hikvision -DartifactId=camera-preview -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
2. 添加SDK依赖
将HCNetSDK.jar添加到项目依赖中:
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>com.hikvision</groupId>
<artifactId>HCNetSDK</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/HCNetSDK.jar</systemPath>
</dependency>
</dependencies>
3. 配置动态库路径
将动态库文件放在项目lib目录下,并设置系统属性:
// 在程序启动时加载
static {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
System.loadLibrary("hcnetsdk");
System.loadLibrary("PlayCtrl");
} else if (os.contains("linux")) {
System.loadLibrary("hcnetsdk");
}
}
三、初始化SDK
1. SDK初始化
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.hikvision.HCNetSDK;
public class HikvisionCamera {
private HCNetSDK hcNetSDK;
private HCNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo;
private int userId = -1;
public boolean initSDK() {
hcNetSDK = HCNetSDK.INSTANCE;
boolean initSuc = hcNetSDK.NET_DVR_Init();
if (!initSuc) {
System.err.println("初始化失败,错误码:" + hcNetSDK.NET_DVR_GetLastError());
return false;
}
// 设置连接超时和重连时间
hcNetSDK.NET_DVR_SetConnectTime(3000, 3);
hcNetSDK.NET_DVR_SetReconnect(10000, true);
return true;
}
}
2. 登录设备
public boolean login(String ip, int port, String username, String password) {
HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
loginInfo.sDeviceAddress = ip.getBytes();
loginInfo.wPort = (short) port;
loginInfo.sUserName = username.getBytes();
loginInfo.sPassword = password.getBytes();
loginInfo.bUseAsynLogin = false;
deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
userId = hcNetSDK.NET_DVR_Login_V30(loginInfo, deviceInfo);
if (userId < 0) {
System.err.println("登录失败,错误码:" + hcNetSDK.NET_DVR_GetLastError());
return false;
}
return true;
}
四、实现摄像头预览
1. 预览参数配置
public class PreviewParam {
public static final int PREVIEW_CHANNEL = 1; // 通道号
public static final int STREAM_TYPE = 0; // 0-主码流,1-子码流
public static final int LINK_MODE = 0; // 0-TCP,1-UDP
public static final int SHOW_MODE = 1; // 0-直接显示,1-回调显示
}
2. 创建预览窗口
import com.sun.jna.Native;
import com.sun.jna.examples.win32.W32API;
import com.sun.jna.examples.win32.GDI32;
import com.sun.jna.examples.win32.User32;
public class PreviewWindow {
private W32API.HWND hwnd;
private int width = 800;
private int height = 600;
public void createWindow() {
// Windows平台创建预览窗口
String className = "HikvisionPreview";
String windowName = "摄像头预览";
User32.WNDCLASSEX wc = new User32.WNDCLASSEX();
wc.hInstance = User32.INSTANCE.GetModuleHandle(null);
wc.lpfnWndProc = new User32.WNDPROC() {
public int callback(W32API.HWND hWnd, int uMsg,
W32API.WPARAM wParam, W32API.LPARAM lParam) {
return User32.INSTANCE.DefWindowProc(hWnd, uMsg, wParam, lParam);
}
};
wc.lpszClassName = className;
User32.INSTANCE.RegisterClassEx(wc);
hwnd = User32.INSTANCE.CreateWindowEx(
0, className, windowName,
User32.WS_OVERLAPPEDWINDOW,
User32.CW_USEDEFAULT, User32.CW_USEDEFAULT,
width, height,
null, null, wc.hInstance, null);
User32.INSTANCE.ShowWindow(hwnd, User32.SW_SHOW);
User32.INSTANCE.UpdateWindow(hwnd);
}
public W32API.HWND getHwnd() {
return hwnd;
}
}
3. 启动实时预览
private int previewHandle = -1;
public boolean startPreview(PreviewWindow previewWindow) {
HCNetSDK.NET_DVR_PREVIEWINFO previewInfo = new HCNetSDK.NET_DVR_PREVIEWINFO();
previewInfo.lChannel = PreviewParam.PREVIEW_CHANNEL;
previewInfo.dwStreamType = PreviewParam.STREAM_TYPE;
previewInfo.dwLinkMode = PreviewParam.LINK_MODE;
previewInfo.hPlayWnd = previewWindow.getHwnd();
previewInfo.bBlocked = 1;
previewHandle = hcNetSDK.NET_DVR_RealPlay_V40(userId, previewInfo, null, null);
if (previewHandle < 0) {
System.err.println("预览失败,错误码:" + hcNetSDK.NET_DVR_GetLastError());
return false;
}
return true;
}
4. 回调函数实现(可选)
// 实现回调接口
public class PreviewCallback implements HCNetSDK.FRealDataCallBack_V30 {
@Override
public void invoke(int lRealHandle, int dwDataType,
Pointer pBuffer, int dwBufSize, Pointer pUser) {
// 处理视频流数据
switch (dwDataType) {
case HCNetSDK.NET_DVR_SYSHEAD:
System.out.println("收到系统头数据");
break;
case HCNetSDK.NET_DVR_STREAMDATA:
System.out.println("收到视频流数据,大小:" + dwBufSize);
break;
case HCNetSDK.NET_DVR_AUDIOSTREAMDATA:
System.out.println("收到音频流数据");
break;
}
}
}
// 设置回调
public void setCallback() {
HCNetSDK.FRealDataCallBack_V30 callback = new PreviewCallback();
hcNetSDK.NET_DVR_SetRealDataCallBack_V30(previewHandle, callback, 0);
}
五、完整示例代码
public class HikvisionCameraDemo {
public static void main(String[] args) {
HikvisionCamera camera = new HikvisionCamera();
// 1. 初始化SDK
if (!camera.initSDK()) {
return;
}
// 2. 登录设备
String ip = "192.168.1.64";
int port = 8000;
String username = "admin";
String password = "hik12345";
if (!camera.login(ip, port, username, password)) {
camera.cleanup();
return;
}
// 3. 创建预览窗口
PreviewWindow previewWindow = new PreviewWindow();
previewWindow.createWindow();
// 4. 开始预览
if (!camera.startPreview(previewWindow)) {
camera.cleanup();
return;
}
// 5. 设置回调(可选)
camera.setCallback();
// 保持程序运行
try {
Thread.sleep(30000); // 预览30秒
} catch (InterruptedException e) {
e.printStackTrace();
}
// 6. 释放资源
camera.cleanup();
}
}
六、资源释放与错误处理
1. 停止预览
public void stopPreview() {
if (previewHandle >= 0) {
hcNetSDK.NET_DVR_StopRealPlay(previewHandle);
previewHandle = -1;
}
}
2. 注销登录
public void logout() {
if (userId >= 0) {
hcNetSDK.NET_DVR_Logout(userId);
userId = -1;
}
}
3. 清理SDK
public void cleanup() {
stopPreview();
logout();
if (hcNetSDK != null) {
hcNetSDK.NET_DVR_Cleanup();
}
}
4. 错误处理
public static String getErrorMsg(int errorCode) {
switch (errorCode) {
case HCNetSDK.NET_DVR_NOERROR: return "没有错误";
case HCNetSDK.NET_DVR_PASSWORD_ERROR: return "用户名或密码错误";
case HCNetSDK.NET_DVR_NOENOUGHPRI: return "权限不足";
case HCNetSDK.NET_DVR_NOINIT: return "SDK未初始化";
case HCNetSDK.NET_DVR_CHANNEL_ERROR: return "通道号错误";
// 更多错误码处理...
default: return "未知错误:" + errorCode;
}
}
七、常见问题解决方案
1. SDK初始化失败
- 问题:
NET_DVR_Init返回false - 解决方案:
- 检查动态库路径是否正确
- 确保动态库文件与程序架构匹配(32/64位)
- 以管理员权限运行程序
2. 登录失败
- 问题:
NET_DVR_Login_V30返回-1 - 解决方案:
- 检查IP、端口、用户名和密码
- 确认摄像头网络连接正常
- 检查防火墙设置,确保8000端口开放
3. 预览无图像
- 问题:预览窗口黑屏
- 解决方案:
- 确认通道号是否正确
- 检查摄像头是否启用主码流
- 尝试切换TCP/UDP模式
4. 内存泄漏
- 问题:长时间运行后内存占用过高
- 解决方案:
- 确保每次调用
NET_DVR_Init后都有对应的NET_DVR_Cleanup - 及时释放预览句柄和用户ID
- 避免频繁创建/销毁窗口
- 确保每次调用
八、高级功能扩展
1. 云台控制
public boolean ptzControl(int command, int speed) {
if (userId < 0) return false;
boolean result = hcNetSDK.NET_DVR_PTZControl_Other(
userId, PreviewParam.PREVIEW_CHANNEL, command, 0, speed);
if (!result) {
System.err.println("云台控制失败:" + getErrorMsg(hcNetSDK.NET_DVR_GetLastError()));
}
return result;
}
// 使用示例
camera.ptzControl(HCNetSDK.TILT_UP, 3); // 向上转动,速度3
2. 抓图功能
public boolean capturePicture(String savePath) {
if (previewHandle < 0) return false;
boolean result = hcNetSDK.NET_DVR_CapturePicture(
previewHandle, savePath.getBytes());
if (!result) {
System.err.println("抓图失败:" + getErrorMsg(hcNetSDK.NET_DVR_GetLastError()));
}
return result;
}
3. 录像功能
public boolean startRecord(String savePath) {
if (previewHandle < 0) return false;
boolean result = hcNetSDK.NET_DVR_SaveRealData(
previewHandle, savePath.getBytes());
if (!result) {
System.err.println("开始录像失败:" + getErrorMsg(hcNetSDK.NET_DVR_GetLastError()));
}
return result;
}
public boolean stopRecord() {
if (previewHandle < 0) return false;
boolean result = hcNetSDK.NET_DVR_StopSaveRealData(previewHandle);
if (!result) {
System.err.println("停止录像失败:" + getErrorMsg(hcNetSDK.NET_DVR_GetLastError()));
}
return result;
}
九、跨平台注意事项
1. Linux平台差异
- 动态库文件为
libhcnetsdk.so - 不需要创建Windows窗口句柄
- 使用X11或Qt等图形库创建预览窗口
2. MacOS支持
- 海康官方未提供Mac版SDK
- 可通过虚拟机或Docker运行Windows/Linux环境
- 考虑使用FFmpeg进行二次开发
十、性能优化建议
- 多线程处理:将预览和业务逻辑分离到不同线程
- 缓冲区管理:合理设置回调缓冲区大小
- 硬件加速:启用DirectShow或OpenGL渲染
- 资源复用:避免频繁登录/注销设备
通过本教程,您应该已经掌握了使用Java调用海康威视SDK实现摄像头预览的核心技术。实际开发中,请根据具体需求调整参数和处理逻辑,并参考海康威视官方文档获取最新API信息。
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END

























暂无评论内容