获取硬盘录像机参数及摄像头信息

发布时间 2023-06-20 10:06:34作者: 摧残一生

获取硬盘录像机参数及摄像头信息

获取硬盘录像机参数

命令参数

NET_DVR_GET_DEVICECFG_V40

结构体

NET_DVR_DEVICECFG_V40

//DVR设备参数
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_DEVICECFG_V40
{
    public uint dwSize;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sDVRName; //DVR名称
    public uint dwDVRID;				//DVR ID,用于遥控器 //V1.4(0-99), V1.5(0-255)
    public uint dwRecycleRecord;		//是否循环录像,0:不是; 1:是
    //以下不可更改
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SERIALNO_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sSerialNumber; //序列号
    public uint dwSoftwareVersion;			//软件版本号,高16位是主版本,低16位是次版本
    public uint dwSoftwareBuildDate;			//软件生成日期,0xYYYYMMDD
    public uint dwDSPSoftwareVersion;		    //DSP软件版本,高16位是主版本,低16位是次版本
    public uint dwDSPSoftwareBuildDate;		// DSP软件生成日期,0xYYYYMMDD
    public uint dwPanelVersion;				// 前面板版本,高16位是主版本,低16位是次版本
    public uint dwHardwareVersion;	// 硬件版本,高16位是主版本,低16位是次版本
    public byte byAlarmInPortNum;		//DVR报警输入个数
    public byte byAlarmOutPortNum;		//DVR报警输出个数
    public byte byRS232Num;			//DVR 232串口个数
    public byte byRS485Num;			//DVR 485串口个数 
    public byte byNetworkPortNum;		//网络口个数
    public byte byDiskCtrlNum;			//DVR 硬盘控制器个数
    public byte byDiskNum;				//DVR 硬盘个数
    public byte byDVRType;				//DVR类型, 1:DVR 2:ATM DVR 3:DVS ......
    public byte byChanNum;				//DVR 通道个数
    public byte byStartChan;			//起始通道号,例如DVS-1,DVR - 1
    public byte byDecordChans;			//DVR 解码路数
    public byte byVGANum;				//VGA口的个数 
    public byte byUSBNum;				//USB口的个数
    public byte byAuxoutNum;			//辅口的个数
    public byte byAudioNum;			//语音口的个数
    public byte byIPChanNum;			//最大数字通道数 低8位,高8位见byHighIPChanNum 
    public byte byZeroChanNum;			//零通道编码个数
    public byte bySupport;        //能力,位与结果为0表示不支持,1表示支持,
                                    //bySupport & 0x1, 表示是否支持智能搜索
                                    //bySupport & 0x2, 表示是否支持备份
                                    //bySupport & 0x4, 表示是否支持压缩参数能力获取
                                    //bySupport & 0x8, 表示是否支持多网卡
                                    //bySupport & 0x10, 表示支持远程SADP
                                    //bySupport & 0x20, 表示支持Raid卡功能
                                    //bySupport & 0x40, 表示支持IPSAN搜索
                                    //bySupport & 0x80, 表示支持rtp over rtsp
    public byte byEsataUseage;		//Esata的默认用途,0-默认备份,1-默认录像
    public byte byIPCPlug;			//0-关闭即插即用,1-打开即插即用
    public byte byStorageMode;		//0-盘组模式,1-磁盘配额, 2抽帧模式
    public byte bySupport1;     //能力,位与结果为0表示不支持,1表示支持
                                //bySupport1 & 0x1, 表示是否支持snmp v30
                                //bySupport1 & 0x2, 支持区分回放和下载
                                //bySupport1 & 0x4, 是否支持布防优先级	
                                //bySupport1 & 0x8, 智能设备是否支持布防时间段扩展
                                //bySupport1 & 0x10, 表示是否支持多磁盘数(超过33个)
                                //bySupport1 & 0x20, 表示是否支持rtsp over http	
    public ushort wDevType;//设备型号
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = DEV_TYPE_NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byDevTypeName;//设备型号名称 
    public byte bySupport2; //能力集扩展,位与结果为0表示不支持,1表示支持
                            //bySupport2 & 0x1, 表示是否支持扩展的OSD字符叠加(终端和抓拍机扩展区分)
    public byte byAnalogAlarmInPortNum; //模拟报警输入个数
    public byte byStartAlarmInNo;    //模拟报警输入起始号
    public byte byStartAlarmOutNo;  //模拟报警输出起始号
    public byte byStartIPAlarmInNo;  //IP报警输入起始号  0-无效
    public byte byStartIPAlarmOutNo; //IP报警输出起始号 0-无效
    public byte byHighIPChanNum;     //数字通道个数,高8位 
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 9, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes2;			//保留
}
代码
Dictionary<String, string> pairs = new Dictionary<string, string>();
// 返回值
UInt32 dwReturn = 0;
// 获取结构体大小:public CHCNetSDK.NET_DVR_DEVICECFG_V40 StruDeviceCfg;为全局
Int32 nSize = Marshal.SizeOf(StruDeviceCfg);
// 开辟空间
IntPtr ptrDeviceCfg = Marshal.AllocHGlobal(nSize);
// 将结构体放入到内存空间中
Marshal.StructureToPtr(StruDeviceCfg, ptrDeviceCfg, false);
// 调用命令
if (!CHCNetSDK.NET_DVR_GetDVRConfig(lUserId, CHCNetSDK.NET_DVR_GET_DEVICECFG_V40, -1, ptrDeviceCfg, (UInt32)nSize, ref dwReturn))
{
    // 如果获取错误,则获取错误信息
    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
    _logerror.Error("NET_DVR_GET_DEVICECFG_V40 failed, error code= " + iLastErr);
}
else
{
    // 将内存中的信息转换为NET_DVR_DEVICECFG_V40结构体
    StruDeviceCfg = (CHCNetSDK.NET_DVR_DEVICECFG_V40)Marshal.PtrToStructure(ptrDeviceCfg, typeof(CHCNetSDK.NET_DVR_DEVICECFG_V40));
	// 获取数值,具体参见结构体实例
    pairs.Add("DevName", Encoding.GetEncoding("GBK").GetString(StruDeviceCfg.sDVRName).TrimEnd('\0'));
    pairs.Add("DevType", Encoding.UTF8.GetString(StruDeviceCfg.byDevTypeName).TrimEnd('\0'));
    pairs.Add("ANum", Convert.ToString(StruDeviceCfg.byChanNum));
    pairs.Add("IPNum", Convert.ToString(StruDeviceCfg.byIPChanNum + 256 * StruDeviceCfg.byHighIPChanNum));
    pairs.Add("ZeroNum", Convert.ToString(StruDeviceCfg.byZeroChanNum));
    pairs.Add("NetNum", Convert.ToString(StruDeviceCfg.byNetworkPortNum));
    pairs.Add("AlarmInNum", Convert.ToString(StruDeviceCfg.byAlarmInPortNum));
    pairs.Add("AlarmOutNum", Convert.ToString(StruDeviceCfg.byAlarmOutPortNum));
    pairs.Add("xDevSerial", Encoding.UTF8.GetString(StruDeviceCfg.sSerialNumber).TrimEnd('\0'));
}
// 将StruDeviceCfg设置为null
StruDeviceCfg = default;
// 清空内存
Marshal.FreeHGlobal(ptrDeviceCfg);
// 返回
return pairs;

获取硬盘录像机的摄像头信息

命令参数

CHCNetSDK.NET_DVR_GET_IPPARACFG_V40

结构体

CHCNetSDK.NET_DVR_IPPARACFG_V40

/* V40扩展IP接入配置结构 */
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_IPPARACFG_V40
{
    public uint dwSize;/* 结构大小 */
    public uint dwGroupNum;
    public uint dwAChanNum;
    public uint dwDChanNum;
    public uint dwStartDChan;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_CHANNUM_V30, ArraySubType = UnmanagedType.I1)]
    public byte[] byAnalogChanEnable; /* 模拟通道是否启用,从低到高表示1-32通道,0表示无效 1有效 */

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_IP_DEVICE_V40, ArraySubType = UnmanagedType.Struct)]
    public NET_DVR_IPDEVINFO_V31[] struIPDevInfo; /* IP设备 */

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_CHANNUM_V30, ArraySubType = UnmanagedType.Struct)]
    public NET_DVR_STREAM_MODE[] struStreamMode;/* IP通道 */

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 20, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes2; /* 模拟通道是否启用,从低到高表示1-32通道,0表示无效 1有效 */
}

NET_DVR_IPDEVINFO_V31

//ipc接入设备信息扩展,支持ip设备的域名添加
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_IPDEVINFO_V31
{
    public byte byEnable;//该IP设备是否有效
    public byte byProType;
    public byte byEnableQuickAdd;
    public byte byRes1;//保留字段,置0
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sUserName;//用户名
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = PASSWD_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sPassword;//密码
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_DOMAIN_NAME, ArraySubType = UnmanagedType.I1)]
    public byte[] byDomain;//设备域名
    public NET_DVR_IPADDR struIP;//IP地址
    public ushort wDVRPort;// 端口号
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 34, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes2;//保留字段,置0

    public void Init()
    {
        sUserName = new byte[NAME_LEN];
        sPassword = new byte[PASSWD_LEN];
        byDomain = new byte[MAX_DOMAIN_NAME];
        byRes2 = new byte[34];
    }
}
代码
  • MonitorCamera类

    public class MonitorCamera
    {
    	// 摄像头名称
        public string name { get; set; }
        // 摄像头ip地址
        public string ip { get; set; }
        // 摄像头通道地址
        public string channel { get; set; }
    }
    
  • dwAChanTotalNum变量及dwDChanTotalNum获取

    摄像头数量

    int lUserID = CHCNetSDK.NET_DVR_Login_V30(accessInfo.Ip地址, Int16.Parse(accessInfo.端口号), accessInfo.用户名, accessInfo.密码, ref DeviceInfo);
    if (lUserID >= 0)
    {
    	dwAChanTotalNum = (uint)DeviceInfo.byChanNum;
    	dwDChanTotalNum = (uint)DeviceInfo.byIPChanNum + 256 * (uint)DeviceInfo.byHighDChanNum;
    	return "";
    }
    
  • 摄像头数组获得

    List<MonitorCamera> cameras = new List<MonitorCamera>();
    uint dwSize = (uint)Marshal.SizeOf(StruIpParaCfgV40);
    IntPtr ptrIpParaCfgV40 = Marshal.AllocHGlobal((Int32)dwSize);
    Marshal.StructureToPtr(StruIpParaCfgV40, ptrIpParaCfgV40, false);
    uint dwReturn = 0;
    //该Demo仅获取第一组64个通道,如果设备IP通道大于64路,需要按组号0~i多次调用NET_DVR_GET_IPPARACFG_V40获取
    int iGroupNo = 0;  
    // 调用海康命令
    if (!CHCNetSDK.NET_DVR_GetDVRConfig(lUserID, CHCNetSDK.NET_DVR_GET_IPPARACFG_V40, iGroupNo, ptrIpParaCfgV40, dwSize, ref dwReturn))
    {
        iLastErr = CHCNetSDK.NET_DVR_GetLastError();
        _logerror.Error(String.Format("获得硬盘录像机通道号NET_DVR_GET_IPPARACFG_V40 failed, error code={0}", iLastErr));
    }
    else
    {
        // 将内存信息转换为结构体
        StruIpParaCfgV40 = (CHCNetSDK.NET_DVR_IPPARACFG_V40)Marshal.PtrToStructure(ptrIpParaCfgV40, typeof(CHCNetSDK.NET_DVR_IPPARACFG_V40));
        int i;
        // 判断摄像头路数
        for (i = 0; i < dwAChanTotalNum; i++)
        {
            // 获取摄像头ip地址
            String strIp = System.Text.Encoding.Default.GetString(StruIpParaCfgV40.struIPDevInfo[i].struIP.sIpV4);
            int nIndex = strIp.IndexOf('\0');
            // 判断是否存在ip地址
            if (!String.IsNullOrEmpty(strIp) && strIp.IndexOf("0.0.0") == -1 && nIndex > 1)
            {
                //存在,则进行声明,存储数据
                MonitorCamera monitor = GetCamera((i + (int)DeviceInfo.byStartChan).ToString(), strIp.Substring(0, nIndex));
                if (GetCameraConfig(lUserID, (i + (int)DeviceInfo.byStartChan)).Length == 0 && StruPicCfgV40.sChanName != null) {
                    // 获取摄像头名称
                    monitor.name = Encoding.GetEncoding("GBK").GetString(StruPicCfgV40.sChanName).TrimEnd('\0');
                }
                cameras.Add(monitor);
            }
        }
        uint iDChanNum = 64;
        if (dwDChanTotalNum < 64)
        {
            iDChanNum = dwDChanTotalNum; //如果设备IP通道小于64路,按实际路数获取
        }
    
        //和上面的循环一致,至于为什么会有两个路,感觉一个是按照路数来设定的,还有一个是按照ip来设定的,不仅仅是摄像头使用,可能还有其他设备也是用该代码
        for (i = 0; i < iDChanNum; i++)
        {
            String strIp = Encoding.Default.GetString(StruIpParaCfgV40.struIPDevInfo[i].struIP.sIpV4);
            int nIndex = strIp.IndexOf('\0');
            if (!String.IsNullOrEmpty(strIp) && strIp.IndexOf("0.0.0") == -1 && nIndex > 1) {
                MonitorCamera monitor = GetCamera((i + (int)StruIpParaCfgV40.dwStartDChan).ToString(), strIp.Substring(0, nIndex), );
                // 获得的StruPicCfgV40为全局变量,如果成功则赋值
                if (GetCameraConfig(lUserID, (i + (int)StruIpParaCfgV40.dwStartDChan)).Length == 0 && StruPicCfgV40.sChanName != null)
                {
                    //获取通道名称,监控画面上现实的文字
                    monitor.name = Encoding.GetEncoding("GBK").GetString(StruPicCfgV40.sChanName).TrimEnd('\0');
                }
                cameras.Add(monitor);
            }
        }
        StruIpParaCfgV40 = default;
    }
    Marshal.FreeHGlobal(ptrIpParaCfgV40);
    return cameras;
    
  • GetCamera代码实例

    private MonitorCamera GetCamera(String channel, String ip) {
        MonitorCamera camera = new MonitorCamera
            {        
                ip = ip,
                channel = channel
            };
        return camera;
    }
    
  • GetCameraConfig代码实例

    // 目的是获得StruPicCfgV40结构体
    internal String GetCameraConfig(int lUserID, int lChannel)
    {
        UInt32 dwReturn = 0;
        Int32 nSize = Marshal.SizeOf(StruPicCfgV40);
        IntPtr getPtrPicCfg = Marshal.AllocHGlobal(nSize);
        Marshal.StructureToPtr(StruPicCfgV40, getPtrPicCfg, false);
        // 获得该通道的信息
        if (!CHCNetSDK.NET_DVR_GetDVRConfig(lUserID, CHCNetSDK.NET_DVR_GET_PICCFG_V40, lChannel, getPtrPicCfg, (UInt32)nSize, ref dwReturn))
        {
            _logerror.Error("NET_DVR_GET_PICCFG_V40 failed, error code= " + CHCNetSDK.NET_DVR_GetLastError());
            Marshal.FreeHGlobal(getPtrPicCfg);
            return "获取信息失败";
        }
        else
        {
            StruPicCfgV40 = (CHCNetSDK.NET_DVR_PICCFG_V40)Marshal.PtrToStructure(getPtrPicCfg, typeof(CHCNetSDK.NET_DVR_PICCFG_V40));
            Marshal.FreeHGlobal(getPtrPicCfg);
        }
        return "";
    }