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

1次阅读
没有评论

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

image.webp

背景痛点

在实际开发中,使用海康威视 SDK 进行二次开发时,开发者常常会遇到以下几个典型问题:

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

  1. DLL 依赖问题 :海康 SDK 包含多个 DLL 文件,不同版本之间可能存在兼容性问题,导致程序无法正常运行。

  2. 连接不稳定 :网络波动或摄像头配置不当会导致连接频繁断开,影响系统可靠性。

  3. 视频保存格式限制 :SDK 默认保存的视频格式可能与业务需求不符,需要额外处理。

  4. 内存泄漏 :不正确的资源释放会导致内存泄漏,长时间运行后程序崩溃。

技术方案对比

海康威视 SDK

  • 优点:官方支持,功能全面,稳定性高,支持硬件加速
  • 缺点:学习曲线陡峭,文档较少,部分接口设计不够友好

开源方案(如 FFmpeg、ONVIF)

  • 优点:跨平台,社区支持好,灵活性高
  • 缺点:功能有限,性能不如官方 SDK,稳定性较差

对于大多数企业级应用,建议使用官方 SDK 以获得最佳性能和稳定性。

核心实现

1. 环境准备

首先需要从海康官网下载最新的 SDK 开发包(HCNetSDK),包含以下关键文件:

  • HCNetSDK.dll
  • PlayCtrl.dll
  • SuperRender.dll

2. SDK 初始化

// 初始化 SDK
bool initResult = CHCNetSDK.NET_DVR_Init();
if (!initResult)
{Console.WriteLine("SDK 初始化失败");
    return;
}

// 设置连接超时和重连参数
CHCNetSDK.NET_DVR_SetConnectTime(2000, 1);
CHCNetSDK.NET_DVR_SetReconnect(10000, true);

3. 设备登录

CHCNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();
int userId = CHCNetSDK.NET_DVR_Login_V30(ip, port, username, password, ref deviceInfo);
if (userId < 0)
{uint errorCode = CHCNetSDK.NET_DVR_GetLastError();
    Console.WriteLine($"登录失败,错误代码:{errorCode}");
    return;
}

4. 实时预览

CHCNetSDK.NET_DVR_PREVIEWINFO previewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO()
{
    hPlayWnd = IntPtr.Zero, // 不显示画面
    lChannel = channelNumber,
    dwStreamType = 0, // 主码流
    dwLinkMode = 0, // TCP 模式
    bBlocked = 1 // 阻塞模式
};

int previewHandle = CHCNetSDK.NET_DVR_RealPlay_V40(userId, ref previewInfo, null, IntPtr.Zero);
if (previewHandle < 0)
{uint errorCode = CHCNetSDK.NET_DVR_GetLastError();
    Console.WriteLine($"预览失败,错误代码:{errorCode}");
    return;
}

5. 视频保存

// 创建 MP4 文件
CHCNetSDK.NET_DVR_MP4CFG mp4Cfg = new CHCNetSDK.NET_DVR_MP4CFG()
{dwSize = (uint)Marshal.SizeOf(typeof(CHCNetSDK.NET_DVR_MP4CFG)),
    dwVideoFileType = 1 // MP4 格式
};

string savePath = "D:\\record.mp4";
bool saveResult = CHCNetSDK.NET_DVR_SaveRealData(previewHandle, savePath);
if (!saveResult)
{uint errorCode = CHCNetSDK.NET_DVR_GetLastError();
    Console.WriteLine($"保存失败,错误代码:{errorCode}");
    return;
}

完整代码示例

using System;
using System.Runtime.InteropServices;

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

        // 2. 登录设备
        CHCNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();
        int userId = CHCNetSDK.NET_DVR_Login_V30("192.168.1.64", 8000, "admin", "password123", ref deviceInfo);
        if (userId < 0)
        {Console.WriteLine($"登录失败,错误代码:{CHCNetSDK.NET_DVR_GetLastError()}");
            CHCNetSDK.NET_DVR_Cleanup();
            return;
        }

        // 3. 开始预览
        CHCNetSDK.NET_DVR_PREVIEWINFO previewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO()
        {
            hPlayWnd = IntPtr.Zero,
            lChannel = 1,
            dwStreamType = 0,
            dwLinkMode = 0,
            bBlocked = 1
        };

        int previewHandle = CHCNetSDK.NET_DVR_RealPlay_V40(userId, ref previewInfo, null, IntPtr.Zero);
        if (previewHandle < 0)
        {Console.WriteLine($"预览失败,错误代码:{CHCNetSDK.NET_DVR_GetLastError()}");
            CHCNetSDK.NET_DVR_Logout(userId);
            CHCNetSDK.NET_DVR_Cleanup();
            return;
        }

        // 4. 保存视频
        string savePath = "D:\\record.mp4";
        if (!CHCNetSDK.NET_DVR_SaveRealData(previewHandle, savePath))
        {Console.WriteLine($"保存失败,错误代码:{CHCNetSDK.NET_DVR_GetLastError()}");
        }
        else
        {Console.WriteLine("视频保存成功,按任意键停止...");
            Console.ReadKey();}

        // 5. 释放资源
        CHCNetSDK.NET_DVR_StopSaveRealData(previewHandle);
        CHCNetSDK.NET_DVR_StopRealPlay(previewHandle);
        CHCNetSDK.NET_DVR_Logout(userId);
        CHCNetSDK.NET_DVR_Cleanup();}
}

性能优化

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

  1. 线程模型选择
  2. 每个摄像头使用独立线程处理
  3. 使用线程池管理资源
  4. 避免 UI 线程阻塞

  5. 资源管理

  6. 限制同时预览的摄像头数量
  7. 动态调整视频质量
  8. 合理设置缓冲区大小

  9. 异步处理

  10. 使用回调函数处理视频数据
  11. 事件驱动架构

避坑指南

  1. SDK 版本兼容性
  2. 确保 SDK 版本与摄像头固件版本匹配
  3. 测试不同版本组合的稳定性

  4. 内存泄漏

  5. 确保每次登录后都有对应的登出
  6. 正确释放所有句柄
  7. 使用 try-finally 保证资源释放

  8. 网络问题

  9. 设置合理的超时时间
  10. 实现自动重连机制
  11. 监控网络状态

扩展思考

  1. 运动检测
  2. 使用 SDK 提供的移动侦测功能
  3. 实现自定义算法分析视频流

  4. 云存储集成

  5. 将视频上传到阿里云 OSS 或 AWS S3
  6. 实现断点续传
  7. 加密存储

  8. 智能分析

  9. 人脸识别
  10. 车牌识别
  11. 行为分析

总结

本文详细介绍了使用 C# 和海康威视 SDK 控制网络摄像头并保存视频的完整流程。通过合理的资源管理和异常处理,可以构建稳定可靠的视频监控系统。希望这些实践经验能够帮助开发者快速上手海康 SDK 开发,避免常见的陷阱和问题。

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