C#实战:海康网络摄像头控制与视频保存全流程指南

1次阅读
没有评论

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

image.webp

海康 SDK 协议特点与集成难点

海康威视设备主要采用 ISAPI(Internet Service API)协议进行通信,这是一种基于 HTTP/HTTPS 的 RESTful 接口。对于 C# 开发者来说,官方提供的 HCNetSDK.dll 需要特别注意:

C# 实战:海康网络摄像头控制与视频保存全流程指南

  • 多版本兼容性 :不同设备型号对应的 SDK 版本可能不同(如 V5.x 与 V6.x 不兼容)
  • 非托管代码交互 :需要处理复杂的结构体内存分配和指针传递
  • 回调函数机制 :视频流数据通过非托管回调函数传递,需要做线程安全处理

常见集成痛点是:

  1. 设备登录经常返回 ” 无权限 ” 错误(错误码 6)
  2. 视频流回调数据出现花屏或卡顿
  3. MP4 文件保存后时间戳异常

技术方案选型对比

方案对比表

方案 优点 缺点 适用场景
海康原生 SDK 功能最完整,低延迟 学习曲线陡峭 需要完整控制链路的项目
OpenCV 图像处理方便 不支持直接接入海康协议 需要实时分析视频内容
FFmpeg 格式转换强大 需要二次开发 只做视频转存场景

推荐组合方案:HCNetSDK+FFmpeg,用原生 SDK 获取流,FFmpeg 做格式转换。

核心实现流程

1. 设备发现与登录

public class HikCameraController : IDisposable
{
    private int m_userId = -1;
    private IntPtr m_devInfo;

    public async Task<bool> LoginAsync(string ip, string user, string pwd, int port=8000)
    {return await Task.Run(() => {NET_DVR_DEVICEINFO_V40 devInfo = new NET_DVR_DEVICEINFO_V40();
            m_userId = NET_DVR_Login_V40(ip, port, user, pwd, ref devInfo);
            return m_userId >= 0;
        });
    }
}

关键参数说明:
– 端口 8000 是海康默认服务端口
– 建议使用 V40 版本 API 以获得更好的兼容性

2. 实时视频流获取

private void StartPreview(int channel=1)
{NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO()
    {
        hPlayWnd = IntPtr.Zero, // 不绑定窗口
        lChannel = channel,
        dwStreamType = 0, // 主码流
        dwLinkMode = 0 // TCP 模式
    };

    m_realHandle = NET_DVR_RealPlay_V40(m_userId, ref previewInfo, 
        new REALDATACALLBACK(RealDataCallback), IntPtr.Zero);
}

private void RealDataCallback(int lRealHandle, uint dwDataType, IntPtr pBuffer, 
    uint dwBufSize, IntPtr pUser)
{// 这里处理视频流数据}

3. H.264 流保存为 MP4

推荐使用 FFmpeg 进行封装:

  1. 通过 SDK 获取原始 H.264 流
  2. 用 FFmpeg 添加 MP4 容器头
  3. 写入文件时注意 I 帧间隔
private Process ffmpegProcess;

private void StartRecording(string outputPath)
{ffmpegProcess = new Process();
    ffmpegProcess.StartInfo.FileName = "ffmpeg.exe";
    ffmpegProcess.StartInfo.Arguments = $"-f h264 -i pipe:0 -c copy {outputPath}";
    ffmpegProcess.StartInfo.UseShellExecute = false;
    ffmpegProcess.StartInfo.RedirectStandardInput = true;
    ffmpegProcess.Start();}

// 在回调函数中写入数据
if(dwDataType == NET_DVR_STREAMDATA)
{byte[] buffer = new byte[dwBufSize];
    Marshal.Copy(pBuffer, buffer, 0, (int)dwBufSize);
    await ffmpegProcess.StandardInput.BaseStream.WriteAsync(buffer, 0, buffer.Length);
}

性能优化要点

多摄像头并发处理

建议采用生产者 - 消费者模式:

graph LR
    A[摄像头 1] --> B[消息队列]
    C[摄像头 2] --> B
    B --> D[统一存储服务]

缓冲区设置经验值

分辨率 推荐缓冲区大小
720P 512KB
1080P 1MB
4K 2MB

磁盘 IO 优化

  • 使用 SSD 存储
  • 每个摄像头单独文件
  • 预分配文件空间

避坑指南

  1. SDK 版本问题 :
  2. 设备与 SDK 大版本必须一致
  3. 32/64 位程序要对应

  4. 防火墙配置 :

  5. 开放 8000、554 端口
  6. 允许 HCNetSDK.exe 出入站

  7. 时间戳异常 :

  8. 检查设备 NTP 配置
  9. 用 SDK 时间同步接口
    NET_DVR_GetSDKSystemDateTime(ref sysTime);

扩展思考:移动侦测触发存储

实现思路:

  1. 通过 SDK 设置移动侦测区域
  2. 注册报警回调函数
  3. 收到报警信号后启动录像

关键 API:

NET_DVR_SETUPALARM_PARAM_V50
NET_DVR_SetDVRMessageCallBack_V50

完整代码示例

参见 GitHub 仓库:HikVision-CSharp-Sample 包含:

  • 异步登录模块
  • 视频流封装类
  • 配置文件示例
  • 资源释放模板

总结

通过合理封装海康 SDK,配合 FFmpeg 等工具,可以构建稳定的视频监控系统。在实际项目中,建议:

  1. 做好 SDK 的日志记录
  2. 添加心跳检测机制
  3. 对关键操作添加重试逻辑

遇到问题时可优先检查:网络连通性、用户权限、SDK 版本这三大常见因素。

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