C#实战:如何通过SDK控制海康网络摄像头并实现视频保存

1次阅读
没有评论

共计 3146 个字符,预计需要花费 8 分钟才能阅读完成。

image.webp

背景痛点

在实际开发中,使用海康威视 SDK 控制网络摄像头并保存视频时,开发者常遇到以下问题:

C# 实战:如何通过 SDK 控制海康网络摄像头并实现视频保存

  • DLL 依赖问题:海康 SDK 包含多个 DLL 文件,版本不匹配或缺失会导致程序崩溃
  • 连接不稳定:网络波动或设备繁忙时,登录和视频流获取容易超时
  • 视频保存兼容性:不同型号摄像头支持的编码格式各异,直接保存可能导致播放器无法识别
  • 资源释放不及时:未正确释放 SDK 资源可能导致内存泄漏或设备连接数耗尽

技术方案对比

与开源方案(如 OpenCV 的 RTSP 拉流、FFmpeg)相比,海康官方 SDK 具有明显优势:

  • 功能完整性:支持 PTZ 控制、报警订阅等高级功能
  • 性能更优:直接硬件解码,降低 CPU 占用
  • 稳定性保障:官方维护,长期兼容设备固件

当然,SDK 也存在学习曲线较陡、文档不够详细等缺点。

核心实现步骤

1. 环境准备

  1. 从海康官网下载最新 SDK(注意区分 32/64 位版本)
  2. 在项目中引用 HCNetSDK.dll、PlayCtrl.dll 等核心库
  3. 设置正确的 DLL 拷贝路径(建议使用 DllImport 指定绝对路径)

2. 设备登录

// 初始化 SDK
HCNetSDK.NET_DVR_Init();
// 设置连接超时(单位:毫秒)HCNetSDK.NET_DVR_SetConnectTime(2000, 1);

// 登录参数
HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
loginInfo.sDeviceAddress = "192.168.1.64";
loginInfo.sUserName = "admin";
loginInfo.sPassword = "123456";

HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
int userId = HCNetSDK.NET_DVR_Login_V40(ref loginInfo, ref deviceInfo);
if (userId < 0)
{uint errorCode = HCNetSDK.NET_DVR_GetLastError();
    throw new Exception($"登录失败,错误代码:{errorCode}");
}

3. 实时预览

// 预览参数
HCNetSDK.NET_DVR_PREVIEWINFO previewInfo = new HCNetSDK.NET_DVR_PREVIEWINFO();
previewInfo.hPlayWnd = pictureBox.Handle; // 显示窗口句柄
previewInfo.lChannel = 1; // 通道号
previewInfo.dwStreamType = 0; // 主码流

// 开始预览
int previewHandle = HCNetSDK.NET_DVR_RealPlay_V40(userId, ref previewInfo, null, null);
if (previewHandle < 0)
{uint errorCode = HCNetSDK.NET_DVR_GetLastError();
    throw new Exception($"预览失败,错误代码:{errorCode}");
}

4. 录像保存

// 录像参数
string savePath = "D:/record.mp4";

// 开始录像
bool success = HCNetSDK.NET_DVR_SaveRealData(previewHandle, savePath);
if (!success)
{uint errorCode = HCNetSDK.NET_DVR_GetLastError();
    throw new Exception($"开始录像失败,错误代码:{errorCode}");
}

// 停止录像(示例中省略了实际停止逻辑)HCNetSDK.NET_DVR_StopSaveRealData(previewHandle);

完整代码示例

以下是一个完整的控制台应用示例:

using System;
using System.Runtime.InteropServices;

class Program
{
    // 引入 SDK 函数
    [DllImport("HCNetSDK.dll")]
    public static extern bool NET_DVR_Init();

    [DllImport("HCNetSDK.dll")]
    public static extern int NET_DVR_Login_V40(ref HCNetSDK.NET_DVR_USER_LOGIN_INFO pLoginInfo, ref HCNetSDK.NET_DVR_DEVICEINFO_V40 lpDeviceInfo);

    static void Main(string[] args)
    {
        try
        {
            // 初始化 SDK
            if (!HCNetSDK.NET_DVR_Init())
            {Console.WriteLine("SDK 初始化失败");
                return;
            }

            // 设备登录(示例参数需替换为实际值)HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
            loginInfo.sDeviceAddress = "192.168.1.64";
            loginInfo.sUserName = "admin";
            loginInfo.sPassword = "123456";

            HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
            int userId = HCNetSDK.NET_DVR_Login_V40(ref loginInfo, ref deviceInfo);

            if (userId < 0)
            {uint errorCode = HCNetSDK.NET_DVR_GetLastError();
                Console.WriteLine($"登录失败,错误代码:{errorCode}");
                return;
            }

            Console.WriteLine("登录成功,按任意键退出...");
            Console.ReadKey();

            // 实际应用中应添加预览和录像逻辑
        }
        catch (Exception ex)
        {Console.WriteLine($"发生异常:{ex.Message}");
        }
        finally
        {
            // 清理 SDK 资源
            HCNetSDK.NET_DVR_Cleanup();}
    }
}

性能优化建议

当需要处理多摄像头时,建议采用以下策略:

  • 线程模型:每个摄像头使用独立线程管理,避免阻塞主线程
  • 连接池:复用已建立的设备连接,减少重复登录开销
  • 异步回调:使用 SDK 提供的报警消息回调机制,替代轮询检查

避坑指南

  1. SDK 版本兼容性
  2. 确保 SDK 版本与设备固件匹配
  3. 32 位 /64 位程序必须使用对应版本的 DLL

  4. 录像文件损坏

  5. 突然断电或程序崩溃会导致录像文件不完整
  6. 解决方案:定期分段保存(如每 10 分钟一个新文件)

  7. 设备连接数限制

  8. 海康设备通常有最大连接数限制
  9. 解决方案:及时释放不再使用的预览句柄和登录会话

扩展思考

掌握了基础功能后,可以尝试以下进阶功能:

  1. 移动侦测:通过 SDK 的报警接口实现区域入侵检测
  2. 云存储集成:将录像文件自动上传至阿里云 OSS 等云存储
  3. 智能分析:结合 OpenCV 实现人脸识别或车牌识别

总结

通过本文的步骤和代码示例,开发者可以快速实现海康网络摄像头的基础控制功能。实际应用中还需注意异常处理和资源管理,特别是在长时间运行的监控系统中。建议在开发过程中参考海康官方的开发文档和示例代码,遇到问题时优先查看错误代码对应的含义。

正文完
 0
评论(没有评论)