当前位置: 首页 > ai >正文

C#项目集成海康SDK指南:从搭建环境到实现视频预览、录制、截屏

        

前言

        本文以 Windows C# 项目为例讲解如何对接海康威视的SDK开发包,实现视频预览、录像和截图等核心功能。

        这篇文章基于一个实际的Demo项目,我会一步步带你完成整个过程,包括环境准备、界面设计、代码实现、优化技巧和调试建议。

准备开发环境      

  • 开发工具:Visual Studio 2019或更高版本(推荐Community版)。
  • SDK下载:从海康威视开放平台下载最新的设备网络SDK(CH-HCNetSDK)

        或从这里直接下载(包含了 x86/x64) 

下载后解压,你会看到一个类似 CH-HCNetSDKV6.x.x.x_buildxxxx 的文件夹。

我们需要关注的是其中的两个部分:

  • 库文件:在 \lib\CSharp\ 目录下,存放着我们C#开发所需的核心 DLL 文件。
  • 开发文档:在 \doc\ 目录下,有非常详尽的API说明和编程手册,这是后续开发的重要参考。

海康SDK开发通用流程

        在深入代码细节之前,我们先理清海康SDK开发的一个通用、标准的流程。无论功能多复杂,万变不离其宗,基本都遵循以下五个步骤。建立起这个宏观概念,能让你在后续开发中思路更清晰。

  1. 初始化 (Initialization)

    • 做什么: 调用 NET_DVR_Init()
    • 目的: 这是所有操作的第一步,用于初始化SDK内部资源。在整个程序生命周期内,只需调用一次。
  2. 注册与登录 (Registration & Login)

    • 做什么: 调用 NET_DVR_Login_V30()
    • 目的: 向指定的设备(摄像头或NVR)发起登录请求。成功后,SDK会返回一个唯一的用户ID(lUserID),这个ID是后续所有操作的“通行证”。
  3. 功能实现 (Feature Implementation)

    • 做什么: 调用具体的业务API,例如 NET_DVR_RealPlay_V40() (实时预览), NET_DVR_CaptureJPEGPicture() (抓图) 等。
    • 目的: 实现你的核心业务需求。所有这些功能函数,都需要传入上一步获取的用户ID。
  4. 注销与退出 (Logout)

    • 做什么: 调用 NET_DVR_Logout()
    • 目的: 当与一台设备的所有交互结束后,应主动登出,释放该设备占用的连接资源。
  5. 清理与释放 (Cleanup)

    • 做什么: 调用 NET_DVR_Cleanup()
    • 目的: 这是所有操作的最后一步,在程序退出前调用,用于释放SDK在初始化时申请的所有资源。

        记住这个“初始化 -> 登录 -> 功能 -> 注销 -> 清理”的生命周期,是写出稳定可靠程序的关键。

        下面让我们正式开始编码。

搭建并集成海康SDK的C#项目

第1步:创建C#项目并配置平台

        在 Visual Studio 中,创建一个新的“Windows窗体应用(.NET Framework)”项目。

        最关键的一步:海康SDK的DLL是区分32位和64位的。我们必须确保项目的目标平台与所使用的DLL版本一致。目前主流PC都是64位系统,因此强烈建议:

在 项目属性 -> 生成 -> 目标平台 中,明确选择 x64

        如果这里选择 Any CPU,在64位系统上运行时,程序默认以64位方式启动,若加载了32位的DLL就会出错,反之亦然。明确指定 x64 可以避免这类 BadImageFormatException 异常。

第2步:复制核心DLL文件

        将SDK库文件复制到你的项目输出目录中。这样,程序运行时才能找到它们。你需要从SDK的 \lib\CSharp\dll\ 目录中,将64位版本的所有文件复制到项目的 bin\x64\Debug 目录下。

        必需的文件通常包括:

  • HCNetSDK.dll (网络库核心)
  • PlayCtrl.dll (播放库核心)
  • HCCore.dll (基础核心库)
  • 以及其他如 AudioRender.dllSuperRender.dllhpr.dll 等所有相关文件。

一个更稳妥的方法是使用“后期生成事件”,让Visual Studio在每次编译后自动完成复制操作。

第3步:引入SDK的C#封装文件

        SDK的函数是用C++编写的,在C#中调用它们需要使用 P/Invoke 技术。幸运的是,海康官方已经为我们做好了这件事。

        你只需要在官方下载的 Demo示例 中找到 CHCNetSDK.cs 和 PlayCtrl.cs 这两个文件,并将它们直接复制添加到你的项目中即可。这两个文件用C#语法定义了SDK中几乎所有的函数、结构体和常量。

实现视频功能

        环境就绪,现在我们开始编码,实现三大核心功能。

第1步:界面设计

使用Visual Studio的设计器创建主窗口MainForm。界面包括以下部分:

  • 设备信息组:输入IP、端口、用户名、密码,并有登录/登出按钮。
  • 预览控制组:预览画面显示区(PictureBox)、开始/停止预览按钮、录像按钮、截图按钮。
  • 日志显示区:ListBox用于显示操作日志。
Demo 程序运行界面​​​​

第2步:初始化与登录

        这是所有操作的基础。

// 在程序入口,如 Program.cs 或主窗口构造函数中
CHCNetSDK.NET_DVR_Init();// 在主窗口中定义登录所需变量
private Int32 m_lUserID = -1;
private CHCNetSDK.NET_DVR_DEVICEINFO_V30 m_struDeviceInfo;// 登录按钮的点击事件
private void buttonLogin_Click(object sender, EventArgs e)
{if (m_lUserID >= 0) // 已登录,则执行注销{CHCNetSDK.NET_DVR_Logout(m_lUserID);m_lUserID = -1;// ... 更新UI状态return;}// 获取IP、端口、用户名、密码string sDVRIP = textBoxIP.Text;Int16 wDVRPort = Int16.Parse(textBoxPort.Text);string sUserName = textBoxUserName.Text;string sPassword = textBoxPassword.Text;m_struDeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();m_lUserID = CHCNetSDK.NET_DVR_Login_V30(sDVRIP, wDVRPort, sUserName, sPassword, ref m_struDeviceInfo);if (m_lUserID < 0){MessageBox.Show("登录失败,错误码: " + CHCNetSDK.NET_DVR_GetLastError());return;}MessageBox.Show("登录成功!");// ... 更新UI状态
}

m_lUserID 是登录后获取的用户ID,后续所有针对该设备的操作都需要用到它。

第3步:实现实时预览

我们采用最高效的SDK直接渲染模式。

// 在主窗口中定义预览句柄
private Int32 m_lRealHandle = -1;// “开始预览”按钮点击事件
private void buttonStartPreview_Click(object sender, EventArgs e)
{if (m_lUserID < 0) { MessageBox.Show("请先登录设备"); return; }if (m_lRealHandle >= 0) { return; } // 已经在预览CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();lpPreviewInfo.hPlayWnd = pictureBoxPreview.Handle; // 将PictureBox的句柄赋给SDKlpPreviewInfo.lChannel = 1;                        // 预览通道1lpPreviewInfo.dwStreamType = 0;                    // 0-主码流, 1-子码流lpPreviewInfo.dwLinkMode = 0;                      // 0-TCP, 1-UDPlpPreviewInfo.bBlocked = true;                     // 阻塞取流// 第二个回调函数参数传 null,代表不使用回调m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null, IntPtr.Zero);if (m_lRealHandle < 0){MessageBox.Show("预览失败,错误码: " + CHCNetSDK.NET_DVR_GetLastError());return;}
}// “停止预览”按钮点击事件
private void buttonStopPreview_Click(object sender, EventArgs e)
{if (m_lRealHandle < 0) { return; }CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle);m_lRealHandle = -1;pictureBoxPreview.Refresh(); // 刷新PictureBox, 清除最后一帧图像
}

第4步:实现手动录像和即时抓图

这两项功能都依赖于一个已经开启的预览。

手动录像

// “开始录像”按钮点击事件
private void buttonStartRecord_Click(object sender, EventArgs e)
{if (m_lRealHandle < 0) { MessageBox.Show("请先开始预览"); return; }string sVideoFileName = "D:\\Record\\" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".mp4";// 使用 V30 接口可以指定文件格式,这里使用2代表PS封装格式,可以被多数播放器识别if (!CHCNetSDK.NET_DVR_SaveRealData_V30(m_lRealHandle, 2, sVideoFileName)){MessageBox.Show("开始录像失败,错误码: " + CHCNetSDK.NET_DVR_GetLastError());return;}
}// “停止录像”按钮点击事件
private void buttonStopRecord_Click(object sender, EventArgs e)
{if (m_lRealHandle < 0) { return; }CHCNetSDK.NET_DVR_StopSaveRealData(m_lRealHandle);
}

即时抓图

// “抓图”按钮点击事件
private void buttonCapture_Click(object sender, EventArgs e)
{if (m_lUserID < 0) { MessageBox.Show("请先登录设备"); return; }string sJpegFileName = "D:\\Picture\\" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".jpg";CHCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new CHCNetSDK.NET_DVR_JPEGPARA();lpJpegPara.wPicQuality = 0; // 图像质量, 0-最好lpJpegPara.wPicSize = 0xff; // 抓图尺寸, 0xff-按当前预览分辨率if (!CHCNetSDK.NET_DVR_CaptureJPEGPicture(m_lUserID, 1, ref lpJpegPara, sJpegFileName)){MessageBox.Show("抓图失败,错误码: " + CHCNetSDK.NET_DVR_GetLastError());return;}MessageBox.Show("抓图成功: " + sJpegFileName);
}

第5步:整合与收尾

        将以上所有功能整合到主窗口的事件中,并确保在程序关闭时,按照“停止预览 -> 注销登录 -> 清理SDK”的顺序,优雅地释放所有资源。这是保证程序稳定性的最后一道防线。

// MainForm.cs
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{// 停止预览if (m_lRealHandle >= 0){CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle);}// 注销登录if (m_lUserID >= 0){CHCNetSDK.NET_DVR_Logout(m_lUserID);}// 释放SDK资源CHCNetSDK.NET_DVR_Cleanup();
}

性能优化与调试

  • CPU优化:避免重复渲染和不必要回调,如上文所述。监控任务管理器,目标CPU占用<10%。
  • 错误处理:始终检查SDK函数返回值,并使用NET_DVR_GetLastError获取错误码。常见错误如29(操作失败)可能由于参数错误引起。错误码具体含义参见 NET_DVR_GetLastError。

  • 资源释放:在停止预览时调用NET_DVR_StopRealPlayNET_DVR_Cleanup
  • 调试技巧:添加日志记录,测试不同分辨率和帧率的影响。使用备份项目比较优化前后效果。
  • 求助官方技术:有些问题,尤其是C#、Java 项目的,官方给出的Demo 可能都不周全。没有思路的时候就给海康的官方SDK邮箱发了封邮件求助。

总结

        通过这个指南,你应该可以顺利地搭建起一个基础的海康威视监控应用。这只是一个起点,海康SDK还提供了丰富的进阶功能,如云台控制、事件报警、智能分析等,欢迎有经验的朋友评论区里一起探讨。


参考

海康威视-引领智能物联新未来

海康开放平台

NET_DVR_GetLastError

http://www.xdnf.cn/news/18129.html

相关文章:

  • 【LeetCode】16. 最接近的三数之和
  • 图论——Bellman-Ford和SPFA
  • 大模型+RPA:如何用AI实现企业流程自动化的“降本增效”?
  • traceroute命令使用指南
  • Linux学习-5网络管理
  • 企业如何让内部视频仅限指定域名播放,确保视频不被泄露?
  • SpreadJS 协同服务器 MongoDB 数据库适配支持
  • Flink Checkpoint 原理深度剖析与作用讲解(flink面试高频问题)
  • RK3128增加usb调试模式,开放adb和root权限
  • 分布式搜索(Elasticsearch)深入用法
  • 基于Python的宠物服务管理系统 Python+Django+Vue.js
  • 卫生许可证识别技术:通过OCR与NLP实现高效合规管理,提升审核准确性与效率
  • 传输层协议——UDP和TCP
  • 论文阅读:Prompt Optimization in Large Language Models
  • 传统概率信息检索模型:理论基础、演进与局限
  • 轻度娱乐浪潮下定制开发开源AI智能名片S2B2C商城小程序的机遇与策略
  • RNN(循环神经网络)和Transformer是处理自然语言处理(NLP)任务区别
  • 10.Ansible角色管理
  • 力扣2道dp
  • Rust 入门 生命周期-next2 (十九)
  • flask——4:请求与响应
  • Kubernetes(K8s)常用命令全解析:从基础到进阶
  • Unity进阶--C#补充知识点--【Unity跨平台的原理】Mono与IL2CPP
  • Disbursement on Quarantine Policy(概率、逆元计算期望)
  • 【深度学习】pytorch深度学习框架的环境配置
  • Ansible文件部署与大项目多主机管理
  • 学习嵌入式的第二十天——数据结构
  • redis-集成prometheus监控(k8s)
  • 实习两个月总结
  • 从0到1掌握 Spring Security(第三篇):三种认证方式,按配置一键切换