海康摄像头取流示例初始签入

This commit is contained in:
2025-12-26 03:18:21 +08:00
parent 86db2cf6b4
commit 6281f4248e
44 changed files with 5588 additions and 0 deletions

View File

@@ -0,0 +1,495 @@
namespace SHH.CameraSdk;
/// <summary>
/// 海康 HCNetSDK.dll 原生方法封装(静态部分类)
/// 功能包含设备登录、预览、PTZ控制、异常回调等核心 SDK 接口定义
/// 注意:所有 API 均直接映射海康原生 DLL 函数,参数顺序与类型需严格匹配官方文档
/// </summary>
public static partial class HikNativeMethods
{
#region --- (Basic Configuration) ---
/// <summary>
/// HCNetSDK.dll 动态库路径
/// 说明:确保项目中该路径与实际文件位置一致,否则会导致 DllImport 调用失败
/// </summary>
private const string DllName = "Drivers\\Hikvision\\HCNetSDK.dll";
#endregion
#region --- (Structures) ---
/// <summary>
/// 设备信息结构体 (NET_DEVICEINFO_V30)
/// 功能:存储设备序列号、通道数、协议类型、能力集等核心信息
/// 注:登录设备成功后通过 NET_DVR_Login_V30 接口返回
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct NET_DEVICEINFO_V30
{
/// <summary> 设备序列号长度48字节 </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] sSerialNumber;
/// <summary> 报警输入个数 </summary>
public byte byAlarmInPortNum;
/// <summary> 报警输出个数 </summary>
public byte byAlarmOutPortNum;
/// <summary> 硬盘个数 </summary>
public byte byDiskNum;
/// <summary> 设备类型1-DVR2-ATM DVR3-DVS 等 </summary>
public byte byDVRType;
/// <summary> 模拟通道个数 </summary>
public byte byChanNum;
/// <summary> 起始通道号目前从1开始 </summary>
public byte byStartChan;
/// <summary> 语音通道数 </summary>
public byte byAudioChanNum;
/// <summary> 最大数字通道个数低8位 </summary>
public byte byIPChanNum;
/// <summary> 零通道编码个数 </summary>
public byte byZeroChanNum;
/// <summary> 主码流传输协议类型0-私有协议1-RTSP2-同时支持两者 </summary>
public byte byMainProto;
/// <summary> 子码流传输协议类型0-私有协议1-RTSP2-同时支持两者 </summary>
public byte bySubProto;
/// <summary> 基础能力集位掩码位与结果为1表示支持对应功能 </summary>
/// <remarks>
/// bySupport & 0x1: 支持智能搜索<br/>
/// bySupport & 0x2: 支持备份<br/>
/// bySupport & 0x4: 支持压缩参数能力获取<br/>
/// bySupport & 0x8: 支持多网卡<br/>
/// bySupport & 0x10: 支持远程SADP<br/>
/// bySupport & 0x20: 支持Raid卡功能<br/>
/// bySupport & 0x40: 支持IPSAN目录查找<br/>
/// bySupport & 0x80: 支持RTP over RTSP
/// </remarks>
public byte bySupport;
/// <summary> 能力集扩充位掩码位与结果为1表示支持对应功能 </summary>
/// <remarks>
/// bySupport1 & 0x1: 支持SNMP v30<br/>
/// bySupport1 & 0x2: 支持区分回放和下载<br/>
/// bySupport1 & 0x4: 支持布防优先级<br/>
/// bySupport1 & 0x8: 智能设备支持布防时间段扩展<br/>
/// bySupport1 & 0x10: 支持多磁盘数超过33个<br/>
/// bySupport1 & 0x20: 支持RTSP over HTTP<br/>
/// bySupport1 & 0x80: 支持车牌新报警信息2012-9-28且支持NET_DVR_IPPARACFG_V40结构体
/// </remarks>
public byte bySupport1;
/// <summary> 能力集扩充位掩码位与结果为1表示支持对应功能 </summary>
/// <remarks>
/// bySupport2 & 0x1: 解码器支持通过URL取流解码<br/>
/// bySupport2 & 0x2: 支持FTP V40<br/>
/// bySupport2 & 0x4: 支持ANR<br/>
/// bySupport2 & 0x8: 支持CCD的通道参数配置<br/>
/// bySupport2 & 0x10: 支持布防报警回传信息(仅抓拍机报警,新老报警结构)<br/>
/// bySupport2 & 0x20: 支持单独获取设备状态子项<br/>
/// bySupport2 & 0x40: 是码流加密设备
/// </remarks>
public byte bySupport2;
/// <summary> 设备型号 </summary>
public ushort wDevType;
/// <summary> 能力集扩充位掩码位与结果为1表示支持对应功能 </summary>
/// <remarks>
/// bySupport3 & 0x1: 支持多码流<br/>
/// bySupport3 & 0x4: 支持按组配置(通道图像参数、报警输入参数等)<br/>
/// bySupport3 & 0x8: 支持TCP/UDP/多播预览的延时预览字段<br/>
/// bySupport3 & 0x10: 支持获取报警主机主要状态V40<br/>
/// bySupport3 & 0x20: 支持通过DDNS域名解析取流
/// </remarks>
public byte bySupport3;
/// <summary> 多码流支持标识(按位表示) </summary>
/// <remarks>0-不支持1-支持bit1-码流3bit2-码流4bit7-主码流bit8-子码流</remarks>
public byte byMultiStreamProto;
/// <summary> 起始数字通道号0表示无效 </summary>
public byte byStartDChan;
/// <summary> 起始数字对讲通道号0表示无效 </summary>
public byte byStartDTalkChan;
/// <summary> 数字通道个数高8位 </summary>
public byte byHighDChanNum;
/// <summary> 能力集扩充位掩码位与结果为1表示支持对应功能 </summary>
public byte bySupport4;
/// <summary> 支持语种能力(按位表示) </summary>
/// <remarks>
/// byLanguageType = 0: 老设备<br/>
/// byLanguageType & 0x1: 支持中文<br/>
/// byLanguageType & 0x2: 支持英文
/// </remarks>
public byte byLanguageType;
/// <summary> 音频输入通道数 </summary>
public byte byVoiceInChanNum;
/// <summary> 音频输入起始通道号 </summary>
public byte byStartVoiceInChanNo;
/// <summary> 保留字段必须置0 </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] byRes3;
/// <summary> AES算法加密/解密能力 </summary>
public byte byMirrorCap;
/// <summary> 起始数字通道号(扩展) </summary>
public ushort wStartIPChanNo;
/// <summary> 保留字段必须置0 </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
public byte[] byRes;
}
/// <summary>
/// 预览参数结构体 (NET_DVR_PREVIEWINFO)
/// 功能:配置实时预览的通道、码流类型、连接方式等参数
/// 注:用于 NET_DVR_RealPlay_V40 接口的输入参数
/// </summary>
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_PREVIEWINFO
{
/// <summary> 通道号模拟通道从1开始 </summary>
public Int32 lChannel;
/// <summary> 码流类型0-主码流1-子码流2-码流33-码流4以此类推 </summary>
public uint dwStreamType;
/// <summary> 连接方式0-TCP1-UDP2-多播3-RTP4-RTP/RTSP5-RTSP/HTTP </summary>
public uint dwLinkMode;
/// <summary> 播放窗口句柄 </summary>
/// <remarks>IntPtr.Zero 表示不让 SDK 直接渲染,仅获取原始流数据</remarks>
public IntPtr hPlayWnd;
/// <summary> 取流模式0-非阻塞1-阻塞阻塞模式超时5秒返回 </summary>
/// <remarks>阻塞模式不适合轮询取流操作</remarks>
public bool bBlocked;
/// <summary> 是否启用回放录像0-不启用1-启用 </summary>
public bool bPassbackRecord;
/// <summary> 预览模式0-正常预览1-延迟预览 </summary>
public byte byPreviewMode;
/// <summary> 流IDlChannel为0xffffffff时启用长度32字节 </summary>
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = STREAM_ID_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] byStreamID;
/// <summary> 应用层协议类型0-私有协议1-RTSP协议 </summary>
public byte byProtoType;
/// <summary> 保留字段必须置0 </summary>
public byte byRes1;
/// <summary> 码流编解码类型0-通用编码数据1-热成像原始数据(含温度加密信息) </summary>
public byte byVideoCodingType;
/// <summary> 播放库最大缓冲帧数范围1-500表示默认1帧 </summary>
public uint dwDisplayBufNum;
/// <summary> NPQ模式0-直连1-过流媒体 </summary>
public byte byNPQMode;
/// <summary> 保留字段必须置0 </summary>
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 215, ArraySubType = UnmanagedType.I1)]
public byte[] byRes;
}
/// <summary>
/// 时间结构体 (NET_DVR_TIME)
/// [Fix Bug P: 结构体炸弹] 修复结构体对齐问题,避免栈内存覆盖导致随机崩溃
/// </summary>
/// <remarks>
/// 原问题ushort/byte 混合定义导致结构体总大小不足16字节SDK写入时覆盖栈变量<br/>
/// 修复方案:使用 Pack=4 对齐,成员类型统一为 uint4字节与 C++ DWORD 匹配
/// </remarks>
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct NET_DVR_TIME
{
public uint dwYear; // 年份
public uint dwMonth; // 月份1-12
public uint dwDay; // 日期1-31
public uint dwHour; // 小时0-23
public uint dwMinute; // 分钟0-59
public uint dwSecond; // 秒0-59
}
#endregion
#region --- (Constants) ---
/// <summary> 流ID长度32字节 </summary>
public const int STREAM_ID_LEN = 32;
/// <summary> 数据类型常量:系统头数据 </summary>
public const int NET_DVR_SYSHEAD = 1;
/// <summary> 数据类型常量视频流数据H.264/H.265 </summary>
public const int NET_DVR_STREAMDATA = 2;
/// <summary> 数据类型常量:音频数据 </summary>
public const int NET_DVR_AUDIOSTREAMDATA = 3;
/// <summary> 命令常量:获取时间配置 </summary>
public const uint NET_DVR_GET_TIMECFG = 118;
#endregion
#region --- PTZ (PTZ Control) ---
/// <summary> PTZ命令常量镜头控制 </summary>
public const uint ZOOM_IN = 11; // 焦距变大(拉近)
public const uint ZOOM_OUT = 12; // 焦距变小(拉远)
public const uint FOCUS_NEAR = 13; // 焦点前调
public const uint FOCUS_FAR = 14; // 焦点后调
public const uint IRIS_OPEN = 15; // 光圈扩大
public const uint IRIS_CLOSE = 16; // 光圈缩小
/// <summary> PTZ命令常量方向控制 </summary>
public const uint TILT_UP = 21; // 云台上仰
public const uint TILT_DOWN = 22; // 云台下俯
public const uint PAN_LEFT = 23; // 云台左转
public const uint PAN_RIGHT = 24; // 云台右转
public const uint UP_LEFT = 25; // 上左移动
public const uint UP_RIGHT = 26; // 上右移动
public const uint DOWN_LEFT = 27; // 下左移动
public const uint DOWN_RIGHT = 28; // 下右移动
public const uint PAN_AUTO = 29; // 自动扫描
/// <summary> PTZ命令常量辅助功能 </summary>
public const uint LIGHT_PWRON = 2; // 接通灯光电源
public const uint WIPER_PWRON = 3; // 接通雨刷开关
#endregion
#region --- (Exception Callback) ---
/// <summary> 异常类型常量 </summary>
public const int EXCEPTION_EXCHANGE = 0x8000; // 用户交互时异常
public const int EXCEPTION_AUDIOEXCHANGE = 0x8001; // 语音对讲异常
public const int EXCEPTION_ALARM = 0x8002; // 报警异常
public const int EXCEPTION_PREVIEW = 0x8003; // 网络预览异常
public const int EXCEPTION_SERIAL = 0x8004; // 透明通道异常
public const int EXCEPTION_RECONNECT = 0x8005; // 预览时重连成功
/// <summary>
/// 异常消息回调委托
/// 功能SDK 发生异常时触发返回异常类型、用户ID、相关句柄等信息
/// </summary>
/// <param name="dwType">异常类型(对应 EXCEPTION_XXX 常量)</param>
/// <param name="lUserID">用户IDNET_DVR_Login_V30 返回值)</param>
/// <param name="lHandle">异常关联句柄(预览句柄/报警句柄等)</param>
/// <param name="pUser">用户自定义数据指针</param>
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void EXCEPTION_CALLBACK(uint dwType, int lUserID, int lHandle, IntPtr pUser);
#endregion
#region --- (Preview Callback) ---
/// <summary>
/// 预览数据回调委托
/// 功能:实时预览时触发,返回原始流数据(系统头/视频流/音频流)
/// </summary>
/// <param name="lRealHandle">预览句柄NET_DVR_RealPlay_V40 返回值)</param>
/// <param name="dwDataType">数据类型(对应 NET_DVR_XXX 数据类型常量)</param>
/// <param name="pBuffer">数据缓冲区指针</param>
/// <param name="dwBufSize">缓冲区大小(字节)</param>
/// <param name="pUser">用户自定义数据指针</param>
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void REALDATACALLBACK(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser);
#endregion
#region --- SDK (Basic SDK Interfaces) ---
/// <summary>
/// 初始化 SDK
/// 功能:调用所有其他 SDK 接口的前提,必须先初始化再使用
/// </summary>
/// <returns>初始化成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_Init();
/// <summary>
/// 释放 SDK 资源
/// 功能:程序退出前调用,释放 SDK 占用的非托管资源(网络连接、内存等)
/// </summary>
/// <returns>释放成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_Cleanup();
/// <summary>
/// 获取最后一次操作的错误码
/// 功能API 调用失败后,通过此接口获取具体错误原因
/// </summary>
/// <returns>错误码(需结合海康官方文档查询含义)</returns>
[DllImport(DllName)]
public static extern uint NET_DVR_GetLastError();
/// <summary>
/// 设置网络连接超时时间和连接尝试次数
/// </summary>
/// <param name="dwWaitTime">超时时间(毫秒),推荐 3000ms</param>
/// <param name="dwTryTimes">连接尝试次数,推荐 1 次</param>
/// <returns>设置成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_SetConnectTime(uint dwWaitTime, uint dwTryTimes);
/// <summary>
/// 设置自动重连功能
/// </summary>
/// <param name="dwInterval">重连间隔(毫秒),推荐 10000ms</param>
/// <param name="bEnableRecon">是否启用重连0-禁用1-启用</param>
/// <returns>设置成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_SetReconnect(uint dwInterval, bool bEnableRecon);
#endregion
#region --- / (Device Login/Logout) ---
/// <summary>
/// 用户注册设备(登录)
/// 功能建立与设备的连接获取用户ID后续接口调用的核心标识
/// </summary>
/// <param name="sDVRIP">设备IP地址</param>
/// <param name="wDVRPort">设备端口号海康默认8000</param>
/// <param name="sUserName">登录用户名(默认 admin</param>
/// <param name="sPassword">登录密码</param>
/// <param name="lpDeviceInfo">输出参数:设备信息结构体</param>
/// <returns>登录成功返回用户ID非负整数失败返回 -1</returns>
[DllImport(DllName)]
public static extern int NET_DVR_Login_V30(string sDVRIP, Int32 wDVRPort, string sUserName, string sPassword, ref NET_DEVICEINFO_V30 lpDeviceInfo);
/// <summary>
/// 用户注销(登出)
/// 功能断开与设备的连接释放用户ID关联的资源
/// </summary>
/// <param name="lUserID">用户IDNET_DVR_Login_V30 返回值)</param>
/// <returns>登出成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_Logout(int lUserID);
#endregion
#region --- (Preview Control) ---
/// <summary>
/// 实时预览V40版本支持回调
/// 功能:启动设备实时取流,通过回调获取原始流数据
/// </summary>
/// <param name="lUserID">用户IDNET_DVR_Login_V30 返回值)</param>
/// <param name="lpPreviewInfo">预览参数结构体</param>
/// <param name="fRealDataCallBack_V30">流数据回调函数</param>
/// <param name="pUser">用户自定义数据指针</param>
/// <returns>预览成功返回预览句柄(非负整数),失败返回 -1</returns>
[DllImport(DllName)]
public static extern int NET_DVR_RealPlay_V40(int lUserID, ref NET_DVR_PREVIEWINFO lpPreviewInfo, REALDATACALLBACK fRealDataCallBack_V30, IntPtr pUser);
/// <summary>
/// 停止预览
/// 功能:停止实时取流,释放预览句柄关联的资源
/// </summary>
/// <param name="lRealHandle">预览句柄NET_DVR_RealPlay_V40 返回值)</param>
/// <returns>停止成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_StopRealPlay(int lRealHandle);
/// <summary>
/// 强制生成I帧
/// 功能主动触发设备发送I帧优化视频流解码延时
/// </summary>
/// <param name="lUserID">用户ID</param>
/// <param name="lChannel">通道号</param>
/// <returns>操作成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_MakeKeyFrame(int lUserID, int lChannel);
#endregion
#region --- PTZ (PTZ Control Interfaces) ---
/// <summary>
/// 云台控制(带速度)
/// 功能:控制云台旋转、镜头缩放、光圈调节等操作
/// </summary>
/// <param name="lUserID">用户ID</param>
/// <param name="lChannel">通道号</param>
/// <param name="dwPTZCommand">PTZ控制命令对应 PTZ 命令常量)</param>
/// <param name="dwStop">启停标识0-开始1-停止</param>
/// <param name="dwSpeed">控制速度1-7数值越大速度越快</param>
/// <returns>操作成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_PTZControlWithSpeed_Other(int lUserID, int lChannel, uint dwPTZCommand, uint dwStop, uint dwSpeed);
#endregion
#region --- (Exception Callback Interfaces) ---
/// <summary>
/// 设置连接超时时间和重连策略(兼容旧版本)
/// </summary>
/// <param name="dwInterval">重连间隔(毫秒),建议 3000</param>
/// <param name="bEnableRecon">是否启用重连1-启用0-禁用</param>
/// <returns>设置成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_SetReconnect(uint dwInterval, int bEnableRecon);
/// <summary>
/// 注册异常、重连等消息的回调函数
/// 功能:绑定异常回调委托,接收 SDK 层面的异常通知
/// </summary>
/// <param name="nMessage">消息类型0 表示所有消息)</param>
/// <param name="hWnd">窗口句柄(可为 IntPtr.Zero</param>
/// <param name="fExceptionCallBack">异常回调函数委托</param>
/// <param name="pUser">用户自定义数据指针</param>
/// <returns>注册成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool NET_DVR_SetExceptionCallBack_V30(uint nMessage, IntPtr hWnd, EXCEPTION_CALLBACK fExceptionCallBack, IntPtr pUser);
#endregion
#region --- (General Configuration Interfaces) ---
/// <summary>
/// 获取设备配置
/// 功能:通用接口,根据命令号获取设备特定配置(如时间配置、通道参数等)
/// </summary>
/// <param name="lUserID">用户ID</param>
/// <param name="dwCommand">配置命令号(如 NET_DVR_GET_TIMECFG</param>
/// <param name="lChannel">通道号(-1 表示设备级配置)</param>
/// <param name="lpOutBuffer">输出缓冲区指针(存储配置数据)</param>
/// <param name="dwOutBufferSize">输出缓冲区大小(字节)</param>
/// <param name="lpBytesReturned">输出参数:实际返回的数据大小(字节)</param>
/// <returns>获取成功返回 true失败返回 false</returns>
[DllImport(DllName, CallingConvention = CallingConvention.StdCall)]
public static extern bool NET_DVR_GetDVRConfig(
int lUserID,
uint dwCommand,
int lChannel,
IntPtr lpOutBuffer,
uint dwOutBufferSize,
ref uint lpBytesReturned);
#endregion
}