目录
C# Winform 调取紫光华智监控画面
1.下载官方SDK
链接:紫光华智监控SDK文件
2.IDM_NETSDK.cs 用来声明华智sdk(NetSDK/idm_netsdk.dll)中的C++函数
using System;
using System.Runtime.InteropServices;
public class IDM_NETSDK
{
#region 基础常量
public const int IDM_SUCCESS = 0;
public const int IDM_ERROR_DEFINED = 1012120000;
public const int IDM_ERROR_UNINITIALIZED = (IDM_ERROR_DEFINED + 1); /* SDK未初始化 */
public const int IDM_ERROR_PASSWORD = (IDM_ERROR_DEFINED + 2); /* 用户名密码错误 */
public const int IDM_ERROR_INVALID_HANDLE = (IDM_ERROR_DEFINED + 3); /* 无效的句柄 */
public const int IDM_ERROR_CHANNEL_NUMBER = (IDM_ERROR_DEFINED + 4); /* 通道号错误 */
public const int IDM_ERROR_MAX_NUM = (IDM_ERROR_DEFINED + 5); /* 超过最大数量 */
public const int IDM_ERROR_CONNECT_FAILED = (IDM_ERROR_DEFINED + 6); /* 连接设备失败 */
public const int IDM_ERROR_SEND_FAILED = (IDM_ERROR_DEFINED + 7); /* 发送失败 */
public const int IDM_ERROR_RECEIVE_FAILED = (IDM_ERROR_DEFINED + 8); /* 接收失败 */
public const int IDM_ERROR_RECEIVE_TIMEOUT = (IDM_ERROR_DEFINED + 9); /* 接收超时 */
public const int IDM_ERROR_DATA = (IDM_ERROR_DEFINED + 10); /* 发送或者接收的数据错误 */
public const int IDM_ERROR_PARAMETER = (IDM_ERROR_DEFINED + 11); /* 参数错误 */
public const int IDM_ERROR_OPERATE = (IDM_ERROR_DEFINED + 12); /* 操作错误 */
public const int IDM_ERROR_BUFFER_NOT_ENOUGH = (IDM_ERROR_DEFINED + 13); /* 数据缓冲区不足 */
public const int IDM_ERROR_CREATE_SOCKET = (IDM_ERROR_DEFINED + 14); /* 创建SOCKET失败 */
public const int IDM_ERROR_SET_SOCKET = (IDM_ERROR_DEFINED + 15); /* 主动注册模式下 找不到设备ID */
public const int IDM_ERROR_BIND_SOCKET = (IDM_ERROR_DEFINED + 16); /* 绑定SOCKET失败 */
public const int IDM_ERROR_LISTEN_SOCKET = (IDM_ERROR_DEFINED + 17); /* 监听SOCKET失败 */
public const int IDM_ERROR_CREATE_FILE = (IDM_ERROR_DEFINED + 18); /* 创建文件失败 */
public const int IDM_ERROR_OPEN_FILE = (IDM_ERROR_DEFINED + 19); /* 打开文件失败 */
public const int IDM_ERROR_WRITE_FILE = (IDM_ERROR_DEFINED + 20); /* 写文件失败 */
public const int IDM_ERROR_LOAD_LIVE = (IDM_ERROR_DEFINED + 21); /* 预览组件加载失败 */
public const int IDM_ERROR_LOAD_VOD = (IDM_ERROR_DEFINED + 22); /* 回放组件加载失败 */
public const int IDM_ERROR_LOAD_ALARM = (IDM_ERROR_DEFINED + 23); /* 报警组件加载失败 */
public const int IDM_ERROR_LOAD_VOICETALK = (IDM_ERROR_DEFINED + 24); /* 语音对讲组件加载失败 */
public const int IDM_ERROR_NOT_SUPPORT = (IDM_ERROR_DEFINED + 25); /* 设备不支持 */
public const int IDM_ERROR_ALLOC_FAILED = (IDM_ERROR_DEFINED + 26); /* 分配内存失败 */
public const int IDM_ERROR_NULLPTR = (IDM_ERROR_DEFINED + 27); /* 空指针 */
public const int IDM_ERROR_LOAD_PDSP = (IDM_ERROR_DEFINED + 28); /* 设备搜索组件加载失败 */
public const int IDM_ERROR_KEEPALIVE_TIMEOUT = (IDM_ERROR_DEFINED + 29); /* 接收心跳超时 */
public const int IDM_ERROR_INVALID_SOCKET = (IDM_ERROR_DEFINED + 30); /* 网络套接字失效 */
public const int IDM_ERROR_NO_NETCARD = (IDM_ERROR_DEFINED + 31); /* 网卡列表加载失败 */
public const int IDM_ERROR_SN_EXIST = (IDM_ERROR_DEFINED + 32); /* SN已存在 */
public const int IDM_ERROR_TASK_RUNNING = (IDM_ERROR_DEFINED + 33); /* 异步任务运行中 */
public const int IDM_IPV4_ADDRESS_LEN = 16;
public const int IDM_IPV6_ADDRESS_LEN = 64;
public const int IDM_DOMAIN_NAME_LEN = 64;
public const int IDM_SERIAL_NUMBER_LEN = 64;
public const int IDM_MAC_ADDRESS_LEN = 64;
public const int IDM_DEVICE_ID_LEN = 64;
public const int IDM_DEVICE_NAME_LEN = 64;
public const int IDM_DEVICE_MODEL_LEN = 64;
public const int IDM_DEVICE_IP_MAX_LEN = 16;
public const int IDM_USERNAME_MAX_LEN = 64;
public const int IDM_PASSWORD_MAX_LEN = 64;
public const int IDM_TIMESTR_MAX_LEN = 64;
public const int IDM_RTSPURL_MAX_LEN = 256;
public const int IDM_UPNP_PORT_NUM = 32;
public const int IDM_ALARM_OUT_MAX_NUM = 16;
public const int IDM_CHANNEL_MAX_NUM = 256;
public const int IDM_HARDDISK_MAX_NUM = 64;
/*下列异常事件类型是IDM_DEV_Exception_Callback_PF回调函数中的ulType*/
public const int EXCEPTION_KEEPALIVE = 0; /*设备连接异常(设置了断线重连,将会恢复连接)*/
public const int EXCEPTION_REALPLAY = 1;
public const int EXCEPTION_PLAYBACK = 2;
public const int EXCEPTION_ALARM = 3; /*告警连接异常(设置了断线重连,将会恢复告警)*/
public const int EXCEPTION_VOICE = 4;
public const int EXCEPTION_RECONNECT = 5; /*设备重连成功*/
public const int EXCEPTION_CHN_OFFLINE = 6;
public const int EXCEPTION_RECONNECT_FAILED = 7; /*设备重连失败(设置了断线重连, 恢复连接时设备报错)*/
public const int EXCEPTION_ALARM_RECONNECT = 8; /*告警恢复成功*/
public const int EXCEPTION_LIVE_CREATE_FILE_FAILED = 9; /*实时码流本地录制,创建失败(lHandle是预览句柄(plRealPlayHandle))*/
public const int EXCEPTION_LIVE_WRITE_FILE_FAILED = 10; /*实时码流本地录制,写文件失败(lHandle是预览句柄(plRealPlayHandle))*/
public const int EXCEPTION_VOD_CREATE_FILE_FAILED = 11; /*回放码流本地录制,创建失败(Handle是回放句柄(lPlayBackHandle))*/
public const int EXCEPTION_VOD_WRITE_FILE_FAILED = 12; /*回放码流本地录制,写文件失败(Handle是回放句柄(lPlayBackHandle))*/
public const int STREAM_VIDEO = 0;
public const int STREAM_AUDIO = 1;
public const int STREAM_PRIVATE = 2;
//录像回放控制参数=
public const int PLAYBACK_START = 0;
public const int PLAYBACK_PAUSE = 1; /*录像暂停*/
public const int PLAYBACK_RESUME = 2; /*录像恢复*/
public const int PLAYBACK_SPEED = 3; /*设置倍速*/
public const int PLAYBACK_FRAME = 4; /*单帧播放*/
public const int PLAYBACK_FORWARD = 5;
public const int PLAYBACK_BACKWARD = 6;
public const int PLAYBACK_SET_SEEK = 7;
public const int PLAYBACK_GET_SEEK = 8;
public const int PLAYBACK_SET_TIME = 9;
public const int PLAYBACK_GET_TIME = 10;
public const int PLAYBACK_AUDIO_ON = 11;
public const int PLAYBACK_AUDIO_OFF = 12;
public const int PLAYBACK_SET_VOLUME = 13;
//云台控制命令宏 IDM_DEV_PTZControl 方法的luCommond参数
public const int PTZ_LIGHT = 1;
public const int PTZ_WIPER = 2;
public const int PTZ_FAN = 3;
public const int PTZ_HEATER = 4;
public const int PTZ_INFRARED = 5;
public const int PTZ_FOCUS_NEAR = 11;
public const int PTZ_FOCUS_FAR = 12;
public const int PTZ_ZOOM_IN = 13;
public const int PTZ_ZOOM_OUT = 14;
public const int PTZ_IRIS_OPEN = 15;
public const int PTZ_IRIS_CLOSE = 16;
public const int PTZ_UP = 21;
public const int PTZ_DOWN = 22;
public const int PTZ_LEFT = 23;
public const int PTZ_RIGHT = 24;
public const int PTZ_LEFT_UP = 25;
public const int PTZ_RIGHT_UP = 26;
public const int PTZ_LEFT_DOWN = 27;
public const int PTZ_RIGHT_DOWN = 28;
public const int PTZ_AUTO_SCAN = 29;
public const int PTZ_AUTO_FOCUS = 30;
public const int PTZ_RESET_LENS = 31;
public const int PTZ_3D_ZOOM = 32;//3D定位 IDM_DEV_PTZ_3D_ZOOM_INFO_S
public const int PTZ_UP_ZOOM_IN = 33;
public const int PTZ_UP_ZOOM_OUT = 34;
public const int PTZ_DOWN_ZOOM_IN = 35;
public const int PTZ_DOWN_ZOOM_OUT = 36;
public const int PTZ_LEFT_ZOOM_IN = 37;
public const int PTZ_LEFT_ZOOM_OUT = 38;
public const int PTZ_RIGHT_ZOOM_IN = 39;
public const int PTZ_RIGHT_ZOOM_OUT = 40;
public const int PTZ_LEFT_UP_ZOOM_IN = 41;
public const int PTZ_LEFT_UP_ZOOM_OUT = 42;
public const int PTZ_RIGHT_UP_ZOOM_IN = 43;
public const int PTZ_RIGHT_UP_ZOOM_OUT = 44;
public const int PTZ_LEFT_DOWN_ZOOM_IN = 45;
public const int PTZ_LEFT_DOWN_ZOOM_OUT = 46;
public const int PTZ_RIGHT_DOWN_ZOOM_IN = 47;
public const int PTZ_RIGHT_DOWN_ZOOM_OUT = 48;
public const int PTZ_SETUP_PRESET = 51;
public const int PTZ_CLEAR_PRESET = 52;
public const int PTZ_GOTO_PRESET = 53;
public const int PTZ_SETUP_ZERO = 54;
public const int PTZ_CLEAR_ZERO = 55;
public const int PTZ_GOTO_ZERO = 56;
public const int PTZ_START_RECORD_TRAIL = 57;
public const int PTZ_STOP_RECORD_TRAIL = 58;
public const int PTZ_START_RUN_TRAIL = 59;
public const int PTZ_STOP_RUN_TRAIL = 60;
public const int PTZ_CLEAR_TRAIL = 61;
public const int PTZ_CLEAR_ALL_TRAIL = 62;
public const int PTZ_START_RUN_CRUISE = 63;
public const int PTZ_STOP_RUN_CRUISE = 64;
public const int PTZ_CLEAR_CRUISE = 65;
public const int PTZ_LOCK = 67;
public const int PTZ_UNLOCK = 68;
public const int PTZ_IRCUT = 69;
public const int PTZ_ONE_TOUCH_PARK = 70; //设置并开启一键守望
public const int PTZ_ONE_TOUCH_CRUISE = 71; //调用一键巡航
public const int PTZ_SET_INIT_POS = 72; //设置枪球联动球机云台初始位置
public const int PTZ_MANUAL_TRACK = 73; //手动跟踪(枪球联动) IDM_DEV_PTZ_3D_ZOOM_INFO_S
public const int PTZ_ASSIST_FOCUS = 74; //辅助聚焦 IDM_DEV_ASSIST_FOCUS_INFO_S
public const int SYSTEM_RESTORE = 0;
public const int SYSTEM_REBOOT = 1;
public const int ONE_TOUCH_PARK = 70;
public const int ONE_TOUCH_CRUISE = 71;
public const int SET_PTZ_INIT_POS = 72;
public const int MANUAL_TRACK = 73;
public const int CONFIG_VIDEO_CFG = 0x00000402;
#endregion
#region 委托回调
/* 异步登录回调函数 */
public delegate void IDM_DEV_Login_Callback_PF(
int lUserID,
int lResult,
IDM_DEV_DEVICE_INFO_S pstDeviceInfo,
IntPtr pUserData
);
public delegate void IDM_DEV_RealPlay_Callback_PF(
int lRealPlayHandle,
uint ulDataType, //0视频帧,1音频帧,2其它数据
IntPtr pucBuffer,//私有封装格式数据
int ulBufferSize,
IntPtr pUserData
);
/* 实时预览回调函数 */
public delegate void IDM_DEV_RealPlayES_Callback_PF(
int lRealPlayHandle,
IDM_DEV_PACKET_INFO_S pstPacketInfo,
IntPtr pUserData
);
#endregion
#region 结构体
[StructLayout(LayoutKind.Sequential)]
public struct IDM_DEV_VIDEO_ENCODE_PARAM_S
{
public byte ucStreamType;
public byte ucVideoType;
public byte ucEncodeType;
public byte ucEncodeLevel;
public byte ucSmartEncode;
public byte ucQuality;
public byte ucBitrateType;
public byte ucSmoothing;
public ushort usIFrameInterval;
public ushort usResolution;
public ushort usFrameRate;
public ushort usBitrate;
public ushort usImageWidth;
public ushort usImageHeight;
public byte ucThirdStreamEnable;
public byte ucBncOutputEnable;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] aucRes;
}
/* 设备参数信息 */
[StructLayout(LayoutKind.Sequential)]
public struct IDM_DEV_DEVICE_INFO_S
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_DEVICE_ID_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szDeviceID; /* 设备ID */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_DEVICE_NAME_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szDeviceName; /* 设备名称 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_SERIAL_NUMBER_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szSerialNum; /* 设备序列号 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_MAC_ADDRESS_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szMacAddress; /* 设备Mac地址 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_DEVICE_IP_MAX_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szIP; /* 设备IP地址 */
public int ulChannel; /* 通道号 */
public int usPort; /* 端口号 */
public byte ucRemainLoginTimes; /* 剩余可登录次数:用户名密码错误时有效 */
public byte ucPasswordLevel; /* 密码安全等级:0-无效 1-默认密码 2-弱密码 3-中密码 4-强密码 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_DEVICE_IP_MAX_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szLocalIP; /* 本地IP地址 */
public int ulRemainLockTime; /* 剩余锁定时间:单位:秒,用户锁定时有效 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] szAuthType; /* 认证类型 当前固定为摘要认证 取Digest*/
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] szRealm; /* 领域参数 根据设备唯一序号生成 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
public byte[] szNonce; /* 现时参数 根据事件生成 有生命周期 */
public uint ulUserLoginID; /* 用户登录ID */
public uint ulLinkSessionID; /* 登录主链路Session ID*/
public uint ulKeepaliveIntervel; /* 单次心跳时间 秒*/
public uint ulKeepaliveFailedTimes; /* 连续心跳失败次数 达到次数认为离线需要重新登录 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] szUserAuth; /* 用户权限 多元素英文逗号组合而成 每个元素最大8字节 最多128个元素*/
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] szPlayBackAuthChannels; /* 用户回放通道级权限 0-1组成 0无权限 1有权限*/
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] szPreviewAuthChannels; /* 用户实况通道级权限 0-1组成 0无权限 1有权限*/
public int ucUserLockStatus; /* 用户锁定状态 失败时有效 0-未锁定 1-锁定*/
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3000, ArraySubType = UnmanagedType.I1)]
public byte[] aucRes;
}
/* 设备重连 */
[StructLayout(LayoutKind.Sequential)]
public struct IDM_DEV_RECONNECT_INFO_S
{
public uint uiInterval; // 重连时间间隔,单位 : 毫秒(最小值3000)
public int ucEnable; // 是否重连,0 - 不重连,1 - 重连,默认值为0
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_DEVICE_IP_MAX_LEN)]
public byte[] ucRes;
}
/* 登录结构体 */
[StructLayout(LayoutKind.Sequential)]
public struct IDM_DEV_USER_LOGIN_INFO_S
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_DEVICE_IP_MAX_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szDeviceIP; /* 设备IP地址 */
public ushort usPort; /* 设备端口号 */
public byte ucRes1; /* 内部使用 请置0*/
public byte ucRes2; // 内部使用,请置0
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_USERNAME_MAX_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szUsername; /* 登录用户名 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_PASSWORD_MAX_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szPassword; /* 登录密码 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IDM_DEVICE_ID_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] szDeviceID; /* 设备ID,主动注册模式下使用ID进行登录*/
public long lLoginMode; /* 登录模式, 0-SDK私有协议登录 ,1-主动注册 */
public IDM_DEV_Login_Callback_PF pfLoginCallBack; /* 异步登录回调函数,暂不启用 */
public IntPtr pUserData; /* 用户数据 */
public byte ucCertLoginMode; /* 证书登录模式 0为普通登录 1为证书登录 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 43, ArraySubType = UnmanagedType.I1)]
public byte[] szTargetIP; /* 目标IP(兼容IPv4,IPv6),优先使用szDeviceIP字段*/
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64, ArraySubType = UnmanagedType.I1)]
public byte[] aucRes;
}
/* 预览参数结构体 */
[StructLayout(LayoutKind.Sequential)]
public struct IDM_DEV_PREVIEW_INFO_S
{
public long ulChannel; /* 通道号 */
public long ulStreamType; /* 码流类型:0-主码流 1-子码流 2-三码流 */
public long ulLinkMode; /* 连接方式:0-TCP 1-UDP 2-多播 3-RTP/RTSP,暂时只支持TCP */
public byte ulStreamTimeout; /*收流超时时间(秒)[5-120] 不在范围内,默认30秒*/
public byte ucStreamMode; /* 流模式, 0:音频复合流, 1:纯视频流 2:纯音频流*/
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 254, ArraySubType = UnmanagedType.I1)]
public byte[] aucRes; //254
}
/* 时间参数 CONFIG_SYSTEM_TIME */
[StructLayout(LayoutKind.Sequential)]
public struct IDM_DEV_TIME_PARAM_S
{
public int usYear; /* 年 */
public int usMonth; /* 月 */
public int usDay; /* 日 */
public int usHour; /* 时 */
public int usMinute; /* 分 */
public int usSecond; /* 秒 */
}
/* 手动抓拍参数 */
[StructLayout(LayoutKind.Sequential)]
public struct IDM_DEV_MANUALSNAP_S
{
public uint ulChanID;
public uint ulStreamType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]
public byte[] aucRes;
}
/* 手动抓拍结果 */
[StructLayout(LayoutKind.Sequential)]
public struct IDM_DEV_MANUALSNAP_RESULT_S
{
public IntPtr pBuffer; /* 数据缓冲区指针 */
public uint ulBufferSize; /* 数据缓冲区长度 */
public uint ulPictureSize; /* 图片大小 */
public IDM_DEV_TIME_PARAM_S stTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]
public byte[] aucRes;
}
[StructLayout(LayoutKind.Sequential)]
public struct IDM_DEV_PACKET_INFO_S
{
public uint ulFrameNum; /* 帧序号 */
public uint ulPacketType; /* 数据类型: 帧类型,0xF1-视频I帧,0xF2-视频P帧,0xF3-MJPEG图片帧,0xF4-辅助帧,0xF5-音频帧,0xF6-视频B帧 */
public uint ulEncodeType; /* 编码类型: 视频帧时: (只在I帧时才有编码格式) 1: MJPEG 2: H.264 3: H.265 4: MPEG4 音频帧时: 1: ADPCM 2:G.722 3:G.711U 4:G.711A 5:G.726 6:AAC 7:MP2L2 8:PCM 9:G.722.1*/
public uint ulPacketMode; /* 打包方式 0: 默认 */
public uint ulTimeStamp; /* 时间戳低位 时间戳的低位4个字节 */
public uint ulTimeStampHight; /* 时间戳高位 时间戳的高位4个字节 可以定义 8 字节的 时间戳 取 高位左移32位和低位相加*/
public uint ulFrameRate; /* 帧率 */
public ushort usWidth; /* 宽度 */
public ushort usHeight; /* 高度 */
public uint ulBufferSize; /* 数据大小 */
public IntPtr pucBuffer; /* 数据缓冲指针 数据是H264/H265裸流帧数据 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64, ArraySubType = UnmanagedType.I1)]
public byte[] aucRes;//64
}
#endregion
#region 函数导入声明
/// <summary>
/// 获取SDK版本
/// </summary>
/// <returns></returns>
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_GetSDKVersion();
/// <summary>
/// 初始化SDK
/// </summary>
/// <returns></returns>
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_Init();
/// <summary>
/// 登录设备
/// </summary>
/// <param name="stLoginInfo"></param>
/// <param name="pstDeviceInfo"></param>
/// <param name="plUserID"></param>
/// <returns></returns>
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_Login(IDM_DEV_USER_LOGIN_INFO_S stLoginInfo, ref IDM_DEV_DEVICE_INFO_S pstDeviceInfo, ref int plUserID);
/// <summary>
/// 启动预览
/// </summary>
/// <param name="lUserID"></param>
/// <param name="stPreviewInfo"></param>
/// <param name="pfRealPlayCallBack"></param>
/// <param name="pUserData"></param>
/// <param name="plRealPlayHandle"></param>
/// <returns></returns>
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_RealPlay(int lUserID, IDM_DEV_PREVIEW_INFO_S stPreviewInfo, IDM_DEV_RealPlay_Callback_PF pfRealPlayCallBack, IntPtr pUserData, ref int plRealPlayHandle);
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_RealPlayES(int lUserID, IDM_DEV_PREVIEW_INFO_S sPreviewInfo, IDM_DEV_RealPlayES_Callback_PF pfRealPlayCallBack, IntPtr pUserData, ref int plRealPlayHandle);
/*
*@brief: 保存实时流到文件
*@param: IN lRealPlayHandle 预览句柄
*@param: IN pcFileName 保存的文件路径
*@return: 成功返回IDM_SUCCESS,失败返回错误码
*/
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_SaveRealPlayData(int lRealPlayHandle, string pcFileName);
/*
*@brief: 停止保存实时流到文件
*@param: IN lRealPlayHandle 预览句柄
*@return: 成功返回IDM_SUCCESS,失败返回错误码
*/
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_StopSaveRealPlayData(int lRealPlayHandle);
/*
*@brief: 手动抓图并保存在用户申请的内存中
*@param: IN lUserID 设备句柄
*@param: IN pInter 抓拍参数
*@param: OUT pOuter 响应参数
*@return: 成功返回IDM_SUCCESS,失败返回错误码
*/
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_ManualSnap(int lUserID, ref IDM_DEV_MANUALSNAP_S pInter, ref IDM_DEV_MANUALSNAP_RESULT_S pOuter);
/// <summary>
/// 停止预览
/// </summary>
/// <param name="lRealPlayHandle"></param>
/// <returns></returns>
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_StopRealPlay(int lRealPlayHandle);
/// <summary>
/// 断线重连
/// </summary>
/// <param name="stReconnectInfo"></param>
/// <returns></returns>
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_SetReconnect(IDM_DEV_RECONNECT_INFO_S stReconnectInfo);
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_SetConfig(int lUserID, uint ulCommand, uint ulChannel, IntPtr pBuffer, uint ulBufferSize);
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_SetRealPlayESCallback(int lRealPlayHandle, IDM_DEV_RealPlayES_Callback_PF pfRealPlayCallback, IntPtr pUserData);
/// <summary>
/// 设备登出
/// </summary>
/// <param name="lUserID">设备句柄</param>
/// <returns></returns>
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_Logout(int lUserID);
/// <summary>
/// 释放资源
/// </summary>
/// <returns></returns>
[DllImport(@"NetSDK/idm_netsdk.dll")]
public static extern int IDM_DEV_Cleanup();
#endregion
}
2.HZ_PLAY.cs 用来声明解码SDK(play.dll)中的函数
using System;
using System.Runtime.InteropServices;
namespace ZGHZ
{
public class HZ_PLAY
{
#region 结构体
/* 帧信息 */
public struct FRAME_INFO
{
public int nWidth; // 画面宽,单位像素。如果是音频数据则为0
public int nHeight; // 画面高,如果是音频数据则为0
public int nStamp; // 时标信息,单位毫秒
public int nType; // 视频帧类型,T_AUDIO16,T_RGB32,T_IYUV
public int nFrameRate; // 视频表示帧率,音频表示采样率
}
public struct FRAME_DECODE_INFO
{
public int nFrameType;
public IntPtr pAudioData;
public int nAudioDataLen;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public IntPtr[] pVideoData;
[MarshalAs(UnmanagedType.SysInt, SizeConst = 3)]
public int[] nStride;//3
[MarshalAs(UnmanagedType.SysInt, SizeConst = 3)]
public int[] nWidth;//3
[MarshalAs(UnmanagedType.SysInt, SizeConst = 3)]
public int[] nHeight;//3
[MarshalAs(UnmanagedType.SysInt, SizeConst = 64)]
public int[] nReserved;//64
}
public struct FRAME_INFO_EX
{
public int nFrameType;
public int nFrameSeq;
public int nStamp;
public int nWidth;
public int nHeight;
public int nFrameRate;
public int nChannels;
public int nBitPerSample;
public int nSamplesPerSec;
[MarshalAs(UnmanagedType.SysInt, SizeConst = 64)]
public int[] nReserved;//64
}
#endregion
#region 委托回调
/**
* 解码回调函数。
*
* @param[in] nPort 通道号
* @param[in] pBuf 解码后的音视频数据
* @param[in] nSize 解码后的音视频数据pBuf的长度
* @param[in] pFrameInfo 图像和声音信息,请参见FRAME_INFO结构体
* @param[in] pUserData 用户自定义参数
* @param[in] nReserved2 保留参数
*/
public delegate void fDecCBFun(int nPort, IntPtr pBuf, int nSize, FRAME_INFO pFrameInfo, IntPtr pUserData, int nReserved2);
public delegate void fCBDecode(int nPort, FRAME_DECODE_INFO pFrameDecodeInfo, FRAME_INFO_EX pFrameInfo, IntPtr pUser);
public delegate void fDisplayCBFun(int nPort, IntPtr pBuf, int nSize, int nWidth, int nHeight, int nStamp, int nType, IntPtr nReserved);
#endregion
#region C++函数
// @bref 获取版本号
// $retvalue 返回值为版本号字符串,失败返回NULL
[DllImport(@"play.dll")]
public static extern int PLAY_GetSdkVersion();
[DllImport(@"play.dll")]
public static extern bool PLAY_GetFreePort(ref int plPort);
/// <summary>
/// 设置流模式
/// </summary>
/// <param name="nPort">播放端口</param>
/// <param name="nMode">0 实时流,1文件流</param>
/// <returns></returns>
[DllImport(@"play.dll")]
public static extern bool PLAY_SetStreamOpenMode(int nPort, int nMode);
[DllImport(@"play.dll")]
public static extern bool PLAY_OpenStream(int nPort, IntPtr pFileHeadBuf, int nSize, int nBufPoolSize);
[DllImport(@"play.dll")]
public static extern bool PLAY_InputData(int nPort, IntPtr pBuf, int nSize);
/**
* 设置解码回调流类型,在PLAY_Play之前调用。
*
* @param[in] nPort 通道号
* @param[in] nStream 1 视频流;2 音频流;3 复合流
* @return BOOL,成功返回TRUE,失败返回FALSE
* @note 如果返回失败,可以调用PLAY_GetLastErrorEx接口获取错误码。
*/
[DllImport(@"play.dll")]
public static extern bool PLAY_SetDecCBStream(int nPort, int nStream);
/**
* 设置解码回调,替换播放器中的显示部分,由用户自己控制显示,该函数在
* PLAY_Play之前调用,在PLAY_Stop时自动失效,下次调用PLAY_Play之前
* 需要重新设置。解码部分不控制速度,只要用户从回调函数中返回,解码器
* 就会解码下一部分数据。适用于只解码不显示的情形。
*
* @param[in] nPort 通道号
* @param[out] DecCBFun 解码回调函数指针,不能为NULL
* @return BOOL,成功返回TRUE,失败返回FALSE
* @note 如果返回失败,可以调用PLAY_GetLastErrorEx接口获取错误码。
*/
[DllImport(@"play.dll")]
public static extern bool PLAY_SetDecCallBack(int nPort, fDecCBFun DecCBFun);
[DllImport(@"play.dll")]
public static extern bool PLAY_SetVisibleDecodeCallBack(int nPort, fCBDecode cbDec, IntPtr pUser);
[DllImport(@"play.dll")]
public static extern bool PLAY_SetDisplayCallBack(int nPort, fDisplayCBFun DisplayCBFun, int nUser);
/**
* 开启播放。播放开始,播放视频画面大小将根据hWnd窗口调整,要全屏显示,只要把hWnd窗口放大到全屏。开始解码线程,若送入的显示窗
* 口句柄为NULL,则不显示,但是不影响解码。
*
* @param[in] nPort 通道号
* @param[in] hWnd 播放视频的窗口句柄
* @return BOOL,成功返回TURE,失败返回FALSE
* @note 如果返回失败,可以调用PLAY_GetLastErrorEx接口获取错误码。
*/
[DllImport(@"play.dll")]
public static extern bool PLAY_Play(int nPort, IntPtr hWnd);
/**
* 关闭播放。
*
* @param[in] nPort 通道号
* @return BOOL,成功返回TURE,失败返回FALSE
* @note 如果返回失败,可以调用PLAY_GetLastErrorEx接口获取错误码。
*/
[DllImport(@"play.dll")]
public static extern bool PLAY_Stop(int nPort);
/**
* 暂停/恢复播放。
*
* @param[in] nPort 通道号
* @param[in] nPause 1:暂停;0:恢复
* @return 成功返回TURE,失败返回FALSE
* @note 如果返回失败,可以调用PLAY_GetLastErrorEx接口获取错误码。
*/
[DllImport(@"play.dll")]
public static extern bool PLAY_Pause(int nPort, int nPause);
[DllImport(@"play.dll")]
public static extern bool PLAY_CloseStream(int nPort);
[DllImport(@"play.dll")]
public static extern bool PLAY_ReleasePort(int lPort);
#endregion
//
}
}
3.HZCameraControl.cs 调用IDM_NETSDK.cs中的方法
using System;
using System.Text;
namespace ZGHZ
{
public class HZCameraControl
{
int mUserID = -1;
int mRealPlayHandle = -1;
int mlPort = -1;
int mChannel = -1;
bool IsInit = false;
bool IsLogin = false;
bool IsPlaying = false;
public bool isUpdate = true;
//IDM_NETSDK.IDM_DEV_RealPlay_Callback_PF mRealPlayCallBack;
IDM_NETSDK.IDM_DEV_RealPlayES_Callback_PF mRealPlayESCallBack;
public HZ_PLAY.fDecCBFun mDecCBFunc;
//public HZ_PLAY.fDisplayCBFun mDisplayCBFunc;//fCBDecode
public HZCameraControl() { }
public bool Init()
{
IsInit = IDM_NETSDK.IDM_DEV_Init() == IDM_NETSDK.IDM_SUCCESS;
return IsInit;
}
/// <summary>
/// 登录
/// </summary>
/// <param name="_ip">监控IP</param>
/// <param name="_port">端口</param>
/// <param name="_userName">用户名</param>
/// <param name="_password">密码</param>
/// <returns></returns>
public bool Login(string _ip, int _port, string _userName, string _password)
{
IDM_NETSDK.IDM_DEV_USER_LOGIN_INFO_S user_info = new IDM_NETSDK.IDM_DEV_USER_LOGIN_INFO_S
{
lLoginMode = 0,
usPort = (ushort)_port,
aucRes = new byte[64]
};
//IP
byte[] ip = Encoding.Default.GetBytes(_ip);
user_info.szTargetIP = new byte[43];
user_info.szDeviceIP = new byte[IDM_NETSDK.IDM_DEVICE_IP_MAX_LEN];
ip.CopyTo(user_info.szTargetIP, 0);
ip.CopyTo(user_info.szDeviceIP, 0);
//用户名
byte[] username = Encoding.Default.GetBytes(_userName);
user_info.szUsername = new byte[IDM_NETSDK.IDM_USERNAME_MAX_LEN];
username.CopyTo(user_info.szUsername, 0);
//密码
byte[] password = Encoding.Default.GetBytes(_password);
user_info.szPassword = new byte[IDM_NETSDK.IDM_PASSWORD_MAX_LEN];
password.CopyTo(user_info.szPassword, 0);
//登录
IDM_NETSDK.IDM_DEV_DEVICE_INFO_S device_info = new IDM_NETSDK.IDM_DEV_DEVICE_INFO_S();
IsLogin = IDM_NETSDK.IDM_DEV_Login(user_info, ref device_info, ref mUserID) == IDM_NETSDK.IDM_SUCCESS;
if (IsLogin)
{
mChannel = device_info.ulChannel;
}
return IsLogin;
}
/// <summary>
/// 开启实时流
/// </summary>
/// <returns></returns>
public bool OpenPlay()
{
IntPtr pUserData = IntPtr.Zero;
IDM_NETSDK.IDM_DEV_PREVIEW_INFO_S private_info = new IDM_NETSDK.IDM_DEV_PREVIEW_INFO_S()
{
ulChannel = mChannel,
ulLinkMode = 0,
ulStreamTimeout = 50,
ulStreamType = 0,
ucStreamMode = 1,
aucRes = new byte[254]
};
//mRealPlayCallBack = OnRealPlayCallBack;
//IsPlaying = IDM_NETSDK.IDM_DEV_RealPlay(mUserID, private_info, mRealPlayCallBack, pUserData, ref mRealPlayHandle) == IDM_NETSDK.IDM_SUCCESS;
mRealPlayESCallBack = OnRealPlayCallBackES;
IsPlaying = IDM_NETSDK.IDM_DEV_RealPlayES(mUserID, private_info, mRealPlayESCallBack, pUserData, ref mRealPlayHandle) == IDM_NETSDK.IDM_SUCCESS;
return IsPlaying;
}
/// <summary>
/// 解码回调
/// </summary>
/// <param name="lRealPlayHandle"></param>
/// <param name="infos"></param>
/// <param name="pUserData"></param>
void OnRealPlayCallBackES(int lRealPlayHandle, IDM_NETSDK.IDM_DEV_PACKET_INFO_S infos, IntPtr pUserData)
{
try
{
switch (infos.ulPacketType)
{
case 0xF1:
if (mlPort == -1)
{
if (!HZ_PLAY.PLAY_GetFreePort(ref mlPort))
{
throw new Exception("get free port failed");
}
if (!HZ_PLAY.PLAY_SetStreamOpenMode(mlPort, 0))
{
throw new Exception("set StreamOpenMode failed");
}
if (!HZ_PLAY.PLAY_OpenStream(mlPort, IntPtr.Zero, 0, 1024 * 1024))
{
throw new Exception("open Stream failed");
}
if (!HZ_PLAY.PLAY_SetDecCallBack(mlPort, mDecCBFunc))
{
throw new Exception("set DecCallBack failed");
}
if (!HZ_PLAY.PLAY_SetDecCBStream(mlPort, 1))
{
throw new Exception("set DecCBStream failed");
}
if (!HZ_PLAY.PLAY_Play(mlPort, IntPtr.Zero))
{
throw new Exception("play failed");
}
}
break;
case 0xF2: break;
case 0xF3: break;
case 0xF4: break;
case 0xF5: break;
default:
if (isUpdate)
{
if (mlPort != -1)
HZ_PLAY.PLAY_InputData(mlPort, infos.pucBuffer, (int)infos.ulBufferSize);
}
break;
}
//if(mlPort!=-1)
HZ_PLAY.PLAY_InputData(mlPort, infos.pucBuffer, (int)infos.ulBufferSize);
}
catch (Exception e)
{
Console.WriteLine("RealPlay:" + e.ToString());
}
}
/// <summary>
/// 停止检测,并关闭实时流
/// </summary>
public void Stop()
{
mRealPlayESCallBack = null;
mDecCBFunc = null;
IDM_NETSDK.IDM_DEV_SetRealPlayESCallback(mRealPlayHandle, null, IntPtr.Zero);
IDM_NETSDK.IDM_DEV_StopRealPlay(mRealPlayHandle);
IDM_NETSDK.IDM_DEV_Logout(mUserID);
IDM_NETSDK.IDM_DEV_Cleanup();
int port = mlPort;
mlPort = -1;
HZ_PLAY.PLAY_Stop(port);
HZ_PLAY.PLAY_ReleasePort(port);
}
}
}
4.初始化
HZCameraControl mCameraControl = new HZCameraControl();
//初始化SDK
void InitCamera()
{
//监控初始化
if (!mCameraControl.Init())
{
MessageBox.Show("监控初始化失败");
return;
}
//用户登录 网络相机IP地址 端口号(默认9000) 登录名 密码
if (!mCameraControl.Login(Config.Single.IP, Config.Single.Port, Config.Single.UserName, Config.Single.Password))
{
MessageBox.Show("用户登录失败");
return;
}
//设置解码回调
mCameraControl.mDecCBFunc = DecodeCallBack;
//获取监控数据
if (!mCameraControl.OpenPlay())
{
return;
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
mCameraControl.Stop();
}
5.解码回调函数
public delegate void RefreshFrameHandle();
RefreshFrameHandle refreshFramCallback;
void DecodeCallBack(int nPort, IntPtr pBuf, int nSize, HZ_PLAY.FRAME_INFO pFrameInfo, IntPtr pUserData, int nReserved2)
{
//限制画面刷新
mCameraControl.isUpdate = false;
if (pFrameInfo.nType == 3)
{
//监控视频YUV流转RGB图片
int width = pFrameInfo.nWidth;
int height = pFrameInfo.nHeight;
if (width <= 0 || height <= 0)
return;
byte[] bytes = new byte[nSize];
Marshal.Copy(pBuf, bytes, 0, bytes.Length);
try
{
refreshFramCallback = new RefreshFrameHandle(() =>
{
//在主线程中处理数据
RefreshFrame(width, height, bytes);
});
this?.Invoke(refreshFramCallback);
}
catch { }
}
}
6.数据处理
//加载OpenCVSharp4 nuget包进行数据转换
void RefreshFrame(int width, int height, byte[] bytes)
{
try
{
#region OpenCV YUV转Mat
using (Mat mat = new Mat(height + height / 2, width, MatType.CV_8UC1, bytes))
{
Mat dst = new Mat();
//YUV转RGB
Cv2.CvtColor(mat, dst, ColorConversionCodes.YUV2RGB_YV12);
//显示监控画面
this.pictureBox1.Image = dst.ToBitmap();
dst.Dispose();//释放资源
mat.Dispose();// using代码块种mat会自动释放
}
#endregion
}
catch (ObjectDisposedException e)
{
Console.WriteLine("fresh:" + e.TargetSite.Name);
}
}