diff --git a/Cis.sln b/Cis.sln index 3ce8f72..cbb9209 100644 --- a/Cis.sln +++ b/Cis.sln @@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cis.Core", "Cis.Core\Cis.Co EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cis.Web.Entry", "Cis.Web.Entry\Cis.Web.Entry.csproj", "{9826E365-EEE9-4721-A738-B02AB64D47E5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EC.Helper", "EC.Helper\EC.Helper.csproj", "{C2A5AEC8-F4FB-4D57-AE32-80502979FB9E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +35,10 @@ Global {9826E365-EEE9-4721-A738-B02AB64D47E5}.Debug|Any CPU.Build.0 = Debug|Any CPU {9826E365-EEE9-4721-A738-B02AB64D47E5}.Release|Any CPU.ActiveCfg = Release|Any CPU {9826E365-EEE9-4721-A738-B02AB64D47E5}.Release|Any CPU.Build.0 = Release|Any CPU + {C2A5AEC8-F4FB-4D57-AE32-80502979FB9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2A5AEC8-F4FB-4D57-AE32-80502979FB9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2A5AEC8-F4FB-4D57-AE32-80502979FB9E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2A5AEC8-F4FB-4D57-AE32-80502979FB9E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/EC.Helper/CameraSDK/Common/CameraStruct.cs b/EC.Helper/CameraSDK/Common/CameraStruct.cs new file mode 100644 index 0000000..42f6e27 --- /dev/null +++ b/EC.Helper/CameraSDK/Common/CameraStruct.cs @@ -0,0 +1,164 @@ +namespace EC.Helper.CameraSDK; + +/// +/// 相机信息 +/// +public class CameraInfo +{ + #region Attr + + /// + /// 相机类型 + /// + public int Type { get; set; } + + /// + /// ip 地址 + /// + public string Ip { get; set; } = string.Empty; + + /// + /// 端口 + /// + public int Port { get; set; } + + /// + /// 账号 + /// + public string UserName { get; set; } = string.Empty; + + /// + /// 密码 + /// + public string Password { get; set; } = string.Empty; + + #endregion Attr + + public static CameraInfo New(int type, string ip, int port, string userName, string password) + { + CameraInfo info = new() { Type = type, Ip = ip, Port = port, UserName = userName, Password = password }; + if (port <= 0) + throw new Exception("Camera type not support."); + return info; + } + + public static CameraInfo New(int type, string ip, string userName, string password) + { + CameraInfo info = new() { Type = type, Ip = ip, UserName = userName, Password = password }; + int port = (CameraType)type switch + { + CameraType.HiK => CameraPort.HiK, + CameraType.DaHua => CameraPort.DaHua, + CameraType.YuShi => CameraPort.YuShi, + _ => -1, + }; + info.Port = port; + if (port <= 0) + throw new Exception("Camera type not support."); + return info; + } +} + +/// +/// 相机类型 +/// +public enum CameraType +{ + HiK = 0, + DaHua = 1, + YuShi = 2, +} + +/// +/// 相机默认连接端口 +/// +public class CameraPort +{ + public const int HiK = 8000; + public const int DaHua = 37777; + public const int YuShi = 8800; +} + +/// +/// Ptz 信息 +/// +public class PtzInfo +{ + #region Attr + + public double Pan { get; set; } + public double Tilt { get; set; } + public double Zoom { get; set; } + + #endregion Attr + + public PtzInfo(double pan, double tilt, double zoom) + { + Pan = pan; + Tilt = tilt; + Zoom = zoom; + } + + public static PtzInfo Default + { + get { return new(0, 0, 0); } + } + + public static PtzInfo New(double pan, double tilt, double zoom) + { + return new PtzInfo(pan, tilt, zoom); + } +} + +/// +/// 相机异常 +/// +public class CameraException : Exception +{ + public CameraException() : base() + { + } + + public CameraException(string? message) : base(message) + { + } + + public CameraException(string? message, Exception? innerException) : base(message, innerException) + { + } + + protected class CameraExceptionObj + { + public CameraType Type { get; set; } + + public int ErrCode { get; set; } + + public string? ErrMsg { get; set; } + + public override string? ToString() + { + return $"Type:{Type}, ErrCode:{ErrCode}, ErrMsg:{ErrMsg}"; + } + } + + public static CameraException New(CameraType type, int errCode) + { + CameraExceptionObj obj = new() + { + Type = type, + ErrCode = errCode + }; + return new CameraException(obj.ToString()); + } + + public static CameraException New(CameraType type, int errCode, string errMsg) + { + CameraExceptionObj obj = new() + { + Type = type, + ErrCode = errCode, + ErrMsg = errMsg + }; + return new CameraException(obj.ToString()); + } +} \ No newline at end of file diff --git a/EC.Helper/CameraSDK/Common/ICameraSDK.cs b/EC.Helper/CameraSDK/Common/ICameraSDK.cs new file mode 100644 index 0000000..b23107a --- /dev/null +++ b/EC.Helper/CameraSDK/Common/ICameraSDK.cs @@ -0,0 +1,52 @@ +namespace EC.Helper.CameraSDK; + +public abstract class ICameraSDK +{ + #region Attr + + protected CameraInfo CameraInfo { get; set; } + + #endregion Attr + + public ICameraSDK(CameraInfo cameraInfo) + { + CameraInfo = cameraInfo; + } + + #region Base Method + + /// + /// 初始化资源 + /// + /// + public abstract bool Init(); + + /// + /// 释放资源 + /// + /// + public abstract bool Destory(); + + /// + /// 连接是否成功 + /// + /// + public abstract bool ConnectSuccess(); + + /// + /// 处理异常 + /// + public abstract void BuildException(); + + #endregion Base Method + + #region Main Method + + /// + /// 获取 ptz + /// + /// + public abstract PtzInfo GetPtzInfo(); + + #endregion Main Method +} \ No newline at end of file diff --git a/EC.Helper/CameraSDK/DaHua/DaHuaOriSDK.cs b/EC.Helper/CameraSDK/DaHua/DaHuaOriSDK.cs new file mode 100644 index 0000000..0d1154c --- /dev/null +++ b/EC.Helper/CameraSDK/DaHua/DaHuaOriSDK.cs @@ -0,0 +1,848 @@ +//#define Linux32 +//#define Linux64 +//#define Win32 +//#define Win64 + +using System.Runtime.InteropServices; + +namespace EC.Helper.CameraSDK; + +public static class DaHuaOriSDK +{ + #region Lib Attr + +#if (Linux32) + private const string LibDhNetSDK = @"./libs/dahua/linux32/libdhnetsdk.so"; +#elif (Linux64) + private const string LibDhNetSDK = @"./libs/dahua/linux64/libdhnetsdk.so"; +#elif (Win32) + private const string LibDhNetSDK = @"./libs/dahua/win32/dhnetsdk.dll"; +#elif (Win64) + private const string LibDhNetSDK = @"./libs/dahua/win64/dhnetsdk.dll"; +#endif + + #endregion Lib Attr + + static DaHuaOriSDK() + { + GlobalInit(); + } + + #region Global + + public static bool InitSuccess { get; private set; } + + public static bool GlobalInit() + { + if (InitSuccess) return true; + bool ret = CLIENT_InitEx(null, IntPtr.Zero, IntPtr.Zero); + InitSuccess = ret; + if (!ret) throw new Exception("DaHuaOriSDK global init failure."); + return ret; + } + + public static bool GlobalDestory() + { + if (!InitSuccess) return true; + CLIENT_Cleanup(); + InitSuccess = false; + return true; + } + + #endregion Global + + #region SDK Enum + + /// + /// login device mode enumeration + /// 登陆设备方式枚举 + /// + public enum EM_LOGIN_SPAC_CAP_TYPE + { + /// + /// TCP login, default + /// TCP登陆, 默认方式 + /// + TCP = 0, + + /// + /// No criteria login + /// 无条件登陆 + /// + ANY = 1, + + /// + /// auto sign up login + /// 主动注册的登入 + /// + SERVER_CONN = 2, + + /// + /// multicast login, default + /// 组播登陆 + /// + MULTICAST = 3, + + /// + /// UDP method login + /// UDP方式下的登入 + /// + UDP = 4, + + /// + /// only main connection login + /// 只建主连接下的登入 + /// + MAIN_CONN_ONLY = 6, + + /// + /// SSL encryption login + /// SSL加密方式登陆 + /// + SSL = 7, + + /// + /// login IVS box remote device + /// 登录智能盒远程设备 + /// + INTELLIGENT_BOX = 9, + + /// + /// login device do not config + /// 登录设备后不做取配置操作 + /// + NO_CONFIG = 10, + + /// + /// USB key device login + /// 用U盾设备的登入 + /// + U_LOGIN = 11, + + /// + /// LDAP login + /// LDAP方式登录 + /// + LDAP = 12, + + /// + /// AD login + /// AD(ActiveDirectory)登录方式 + /// + AD = 13, + + /// + /// Radius login + /// Radius 登录方式 + /// + RADIUS = 14, + + /// + /// Socks5 login + /// Socks5登陆方式 + /// + SOCKET_5 = 15, + + /// + /// cloud login + /// 云登陆方式 + /// + CLOUD = 16, + + /// + /// dual authentication loin + /// 二次鉴权登陆方式 + /// + AUTH_TWICE = 17, + + /// + /// TS stream client login + /// TS码流客户端登陆方式 + /// + TS = 18, + + /// + /// web private login + /// 为P2P登陆方式 + /// + P2P = 19, + + /// + /// mobile client login + /// 手机客户端登陆 + /// + MOBILE = 20, + + /// + /// invalid login + /// 无效的登陆方式 + /// + INVALID = 21, + } + + /// + /// device type enumeration + /// 设备类型枚举 + /// + public enum EM_NET_DEVICE_TYPE + { + /// + /// Unknow + // 未知 + /// + NET_PRODUCT_NONE = 0, + + /// + /// Non real-time MACE + /// 非实时MACE + /// + NET_DVR_NONREALTIME_MACE, + + /// + /// Non real-time + /// 非实时 + /// + NET_DVR_NONREALTIME, + + /// + /// Network video server + /// 网络视频服务器 + /// + NET_NVS_MPEG1, + + /// + /// MPEG1 2-ch DVR + /// MPEG1二路录像机 + /// + NET_DVR_MPEG1_2, + + /// + /// MPEG1 8-ch DVR + /// MPEG1八路录像机 + /// + NET_DVR_MPEG1_8, + + /// + /// MPEG4 8-ch DVR + /// MPEG4八路录像机 + /// + NET_DVR_MPEG4_8, + + /// + /// MPEG4 16-ch DVR + /// MPEG4 十六路录像机 + /// + NET_DVR_MPEG4_16, + + /// + /// LB series DVR + /// LB系列录像机 + /// + NET_DVR_MPEG4_SX2, + + /// + /// GB series DVR + /// GB系列录像机 + /// + NET_DVR_MEPG4_ST2, + + /// + /// HB series DVR + /// HB系列录像机 + /// + NET_DVR_MEPG4_SH2, + + /// + /// GBE series DVR + /// GBE系列录像机 + /// + NET_DVR_MPEG4_GBE, + + /// + /// II network video server + /// II代网络视频服务器 + /// + NET_DVR_MPEG4_NVSII, + + /// + /// New standard configuration protocol + /// 新标准配置协议 + /// + NET_DVR_STD_NEW, + + /// + /// DDNS server + /// DDNS服务器 + /// + NET_DVR_DDNS, + + /// + /// ATM series + /// ATM机 + /// + NET_DVR_ATM, + + /// + /// 2nd non real-time NB series DVR + /// 二代非实时NB系列机器 + /// + NET_NB_SERIAL, + + /// + /// LN series + /// LN系列产品 + /// + NET_LN_SERIAL, + + /// + /// BAV series + /// BAV系列产品 + /// + NET_BAV_SERIAL, + + /// + /// SDIP series + /// SDIP系列产品 + /// + NET_SDIP_SERIAL, + + /// + /// IPC series + /// IPC系列产品 + /// + NET_IPC_SERIAL, + + /// + /// NVS B series + /// NVS B系列 + /// + NET_NVS_B, + + /// + /// NVS H series + /// NVS H系列 + /// + NET_NVS_C, + + /// + /// NVS S series + /// NVS S系列 + /// + NET_NVS_S, + + /// + /// NVS E series + /// NVS E系列 + /// + NET_NVS_E, + + /// + /// Search device type from QueryDevState. it is in string format + /// 从QueryDevState中查询设备类型,以字符串格式 + /// + NET_DVR_NEW_PROTOCOL, + + /// + /// NVD + /// 解码器 + /// + NET_NVD_SERIAL, + + /// + /// N5 + /// N5 + /// + NET_DVR_N5, + + /// + /// HDVR + /// 混合DVR + /// + NET_DVR_MIX_DVR, + + /// + /// SVR series + /// SVR系列 + /// + NET_SVR_SERIAL, + + /// + /// SVR-BS + /// SVR-BS + /// + NET_SVR_BS, + + /// + /// NVR series + /// NVR系列 + /// + NET_NVR_SERIAL, + + /// + /// N51 + /// N51 + /// + NET_DVR_N51, + + /// + /// ITSE Intelligent Analysis Box + /// ITSE 智能分析盒 + /// + NET_ITSE_SERIAL, + + /// + /// Intelligent traffic camera equipment + /// 智能交通像机设备 + /// + NET_ITC_SERIAL, + + /// + /// radar speedometer HWS + /// 雷达测速仪HWS + /// + NET_HWS_SERIAL, + + /// + /// portable video record + /// 便携式音视频录像机 + /// + NET_PVR_SERIAL, + + /// + /// IVS(intelligent video server series) + /// IVS(智能视频服务器系列) + /// + NET_IVS_SERIAL, + + /// + /// universal intelligent detect video server series + /// 通用智能视频侦测服务器 + /// + NET_IVS_B, + + /// + /// face recognisation server + /// 人脸识别服务器 + /// + NET_IVS_F, + + /// + /// video quality diagnosis server + /// 视频质量诊断服务器 + /// + NET_IVS_V, + + /// + /// matrix + /// 矩阵 + /// + NET_MATRIX_SERIAL, + + /// + /// N52 + /// N52 + /// + NET_DVR_N52, + + /// + /// N56 + /// N56 + /// + NET_DVR_N56, + + /// + /// ESS + /// ESS + /// + NET_ESS_SERIAL, + + /// + /// 人数统计服务器 + /// + NET_IVS_PC, + + /// + /// pc-nvr + /// pc-nvr + /// + NET_PC_NVR, + + /// + /// screen controller + /// 大屏控制器 + /// + NET_DSCON, + + /// + /// network video storage server + /// 网络视频存储服务器 + /// + NET_EVS, + + /// + /// an embedded intelligent video analysis system + /// 嵌入式智能分析视频系统 + /// + NET_EIVS, + + /// + /// DVR-N6 + /// DVR-N6 + /// + NET_DVR_N6, + + /// + /// K-Lite Codec Pack + /// 万能解码器 + /// + NET_UDS, + + /// + /// Bank alarm host + /// 银行报警主机 + /// + NET_AF6016, + + /// + /// Video network alarm host + /// 视频网络报警主机 + /// + NET_AS5008, + + /// + /// Network alarm host + /// 网络报警主机 + /// + NET_AH2008, + + /// + /// Alarm host series + /// 报警主机系列 + /// + NET_A_SERIAL, + + /// + /// Access control series of products + /// 门禁系列产品 + /// + NET_BSC_SERIAL, + + /// + /// NVS series product + /// NVS系列产品 + /// + NET_NVS_SERIAL, + + /// + /// VTO series product + /// VTO系列产品 + /// + NET_VTO_SERIAL, + + /// + /// VTNC series product + /// VTNC系列产品 + /// + NET_VTNC_SERIAL, + + /// + /// TPC series product, it is the thermal device + /// TPC系列产品, 即热成像设备 + /// + NET_TPC_SERIAL, + + /// + /// ASM series product + /// 无线中继设备 + /// + NET_ASM_SERIAL, + + /// + /// VTS series product + /// 管理机 + /// + NET_VTS_SERIAL, + + /// + /// Alarm host-ARC2016C + /// 报警主机ARC2016C + /// + NET_ARC2016C, + + /// + /// ASA Attendance machine + /// 考勤机 + /// + NET_ASA, + + /// + /// Industry terminal walkie-talkie + /// 行业对讲终端 + /// + NET_VTT_SERIAL, + + /// + /// Alarm column + /// 报警柱 + /// + NET_VTA_SERIAL, + + /// + /// SIP Server + /// SIP服务器 + /// + NET_VTNS_SERIAL, + + /// + /// Indoor unit + /// 室内机 + /// + NET_VTH_SERIAL, + } + + /// + /// 查询设备信息参数 + /// + public enum EM_DEVICE_STATE + { + /// + /// Query device online state(return a DWORD value, 1-online, 0-offline) + /// 查询设备的在线状态(返回一个DWORD, 1表示在线, 0表示断线) + /// + ONLINE = 0x0035, + + /// + /// Query ptz state(struct DH_PTZ_LOCATION_INFO) + /// 查询云台状态信息(对应结构体 DH_PTZ_LOCATION_INFO) + /// + PTZ_LOCATION = 0x0036, + } + + /// + /// 预置点状态枚举 + /// + public enum EM_DH_PTZ_PRESET_STATUS + { + UNKNOWN, // 未知 + REACH, // 预置点到达 + UNREACH, // 预置点未到达 + } + + #endregion SDK Enum + + #region SDK Struct + + /// + /// CLIENT_LoginWithHighLevelSecurity 输入参数 + /// + public struct NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY + { + public uint dwSize;// 结构体大小 + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string szIP; // IP + + public int nPort; // 端口 + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string szUserName; // 用户名 + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string szPassword; // 密码 + + public EM_LOGIN_SPAC_CAP_TYPE emSpecCap; // 登录模式 + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] byReserved; // 字节对齐 + + public IntPtr pCapParam; // 见 CLIENT_LoginEx 接口 pCapParam 与 nSpecCap 关系 + } + + /// + /// device information structure + /// 设备信息结构体 + /// + public struct NET_DEVICEINFO_Ex + { + /// + /// serial number + /// 序列号 + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)] + public string sSerialNumber; + + /// + /// count of alarm input + /// 报警输入个数 + /// + public int nAlarmInPortNum; + + /// + /// count of alarm output + /// 报警输出个数 + /// + public int nAlarmOutPortNum; + + /// + /// number of disk + /// 硬盘个数 + /// + public int nDiskNum; + + /// + /// device type, refer to EM_NET_DEVICE_TYPE + /// 设备类型,见枚举NET_DEVICE_TYPE + /// + public EM_NET_DEVICE_TYPE nDVRType; + + /// + /// number of channel + /// 通道个数 + /// + public int nChanNum; + + /// + /// Online Timeout, Not Limited Access to 0, not 0 Minutes Limit Said + /// 在线超时时间,为0表示不限制登陆,非0表示限制的分钟数 + /// + public byte byLimitLoginTime; + + /// + /// When login failed due to password error, notice user by this parameter.This parameter is invalid when remaining login times is zero + /// 当登陆失败原因为密码错误时,通过此参数通知用户,剩余登陆次数,为0时表示此参数无效 + /// + public byte byLeftLogTimes; + + /// + /// keep bytes for aligned + /// 保留字节,字节对齐 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] bReserved; + + /// + /// when log in failed,the left time for users to unlock (seconds), -1 indicate the device haven't set the parameter + /// 当登陆失败,用户解锁剩余时间(秒数), -1表示设备未设置该参数 + /// + public int nLockLeftTime; + + /// + /// reserved + /// 保留字节 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] + public byte[] Reserved; + } + + /// + /// CLIENT_LoginWithHighLevelSecurity 输出参数 + /// + public struct NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY + { + public uint dwSize;// 结构体大小 + public NET_DEVICEINFO_Ex stuDeviceInfo; // 设备信息 + public int nError; // 错误码,见 CLIENT_Login 接口错误码 + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 132)] + public byte[] byReserved; // 保留字节 + } + + /// + /// 云台定位中非归一化坐标和变倍 + /// + public struct NET_PTZSPACE_UNNORMALIZED + { + public int nPosX; // x坐标 + public int nPosY; // y坐标 + public int nZoom; // 放大倍率 + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 52)] + public byte[] byReserved; // 预留字节 + } + + /// + /// 云台定位信息 + /// + //云台定位信息 + public struct DH_PTZ_LOCATION_INFO + { + public int nChannelID; // 通道号 + public int nPTZPan; // 云台水平运动位置,有效范围:[0,3600] + public int nPTZTilt; // 云台垂直运动位置,有效范围:[-1800,1800] + public int nPTZZoom; // 云台光圈变动位置,有效范围:[0,128] + public byte bState; // 云台运动状态, 0-未知 1-运动 2-空闲 + public byte bAction; // 云台动作,255-未知,0-预置点,1-线扫,2-巡航,3-巡迹,4-水平旋转,5-普通移动,6-巡迹录制,7-全景云台扫描,8-热度图 + + // 9-精确定位,10-设备校正,11-智能配置,12-云台重启 + public byte bFocusState; // 云台聚焦状态, 0-未知, 1-运动状态, 2-空闲 + + public byte bEffectiveInTimeSection; // 在时间段内预置点状态是否有效 + + //如果当前上报的预置点是时间段内的预置点,则为1,其他情况为0 + public int nPtzActionID; // 巡航ID号 + + public uint dwPresetID; // 云台所在预置点编号 + public float fFocusPosition; // 聚焦位置 + public byte bZoomState; // 云台ZOOM状态,0-未知,1-ZOOM,2-空闲 + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] bReserved; // 对齐 + + public uint dwSequence; // 包序号,用于校验是否丢包 + public uint dwUTC; // 对应的UTC(1970-1-1 00:00:00)秒数。 + public EM_DH_PTZ_PRESET_STATUS emPresetStatus; // 预置点位置 + + /// + /// 保留字段 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 248)] + public int[] reserved; + }; + + #endregion SDK Struct + + #region Common Method + + /// + /// network disconnection callback function original shape + /// 断线回调函数 + /// + /// user LoginID:Login's returns value 登陆ID + /// device IP 设备IP + /// device prot 设备端口 + /// user data from Init function 用户数据 + public delegate void fDisConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser); + + /// + /// network re-connection callback function original shape + /// 重连回调函数 + /// + /// user LoginID:Login's returns value 登陆ID + /// device IP,string type 设备IP + /// device prot 设备端口 + /// user data from SetAutoReconnect function 用户数据 + public delegate void fHaveReConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser); + + [DllImport(LibDhNetSDK)] + public static extern bool CLIENT_InitEx(fDisConnectCallBack? cbDisConnect, IntPtr dwUser, IntPtr lpInitParam); + + [DllImport(LibDhNetSDK)] + public static extern void CLIENT_Cleanup(); + + [DllImport(LibDhNetSDK)] + public static extern int CLIENT_GetLastError(); + + [DllImport(LibDhNetSDK)] + public static extern IntPtr CLIENT_LoginWithHighLevelSecurity(ref NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam, ref NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam); + + [DllImport(LibDhNetSDK)] + public static extern bool CLIENT_Logout(IntPtr lLoginID); + + [DllImport(LibDhNetSDK)] + public static extern void CLIENT_SetAutoReconnect(fHaveReConnectCallBack cbAutoConnect, IntPtr dwUser); + + [DllImport(LibDhNetSDK)] + public static extern bool CLIENT_QueryDevState(IntPtr lLoginID, int nType, IntPtr pBuf, int nBufLen, ref int pRetLen, int waittime); + + #endregion Common Method +} \ No newline at end of file diff --git a/EC.Helper/CameraSDK/DaHua/DaHuaSDK.cs b/EC.Helper/CameraSDK/DaHua/DaHuaSDK.cs new file mode 100644 index 0000000..478746e --- /dev/null +++ b/EC.Helper/CameraSDK/DaHua/DaHuaSDK.cs @@ -0,0 +1,111 @@ +using System.Runtime.InteropServices; + +namespace EC.Helper.CameraSDK; + +public class DaHuaSDK : ICameraSDK +{ + #region Attr + + private IntPtr LoginId { get; set; } = IntPtr.Zero; + + #endregion Attr + + public DaHuaSDK(CameraInfo cameraInfo) : base(cameraInfo) + { + } + + #region Base Method + + public override bool Init() + { + bool ret = ConnectSuccess(); + if (ret) return true; + + DaHuaOriSDK.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stuInParam = new(); + stuInParam.dwSize = (uint)Marshal.SizeOf(stuInParam); + stuInParam.szIP = CameraInfo.Ip; + stuInParam.nPort = CameraInfo.Port; + stuInParam.szUserName = CameraInfo.UserName; + stuInParam.szPassword = CameraInfo.Password; + stuInParam.emSpecCap = DaHuaOriSDK.EM_LOGIN_SPAC_CAP_TYPE.TCP; + stuInParam.pCapParam = IntPtr.Zero; + DaHuaOriSDK.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stuOutParam = new(); + stuOutParam.dwSize = (uint)Marshal.SizeOf(stuOutParam); + LoginId = DaHuaOriSDK.CLIENT_LoginWithHighLevelSecurity(ref stuInParam, ref stuOutParam); + ret = ConnectSuccess(); + if (ret) DaHuaOriSDK.CLIENT_SetAutoReconnect(delegate (IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser) + { + LoginId = lLoginID; + }, IntPtr.Zero); + + return ret; + } + + public override bool Destory() + { + bool ret = ConnectSuccess(); + if (!ret) return true; + + ret = DaHuaOriSDK.CLIENT_Logout(LoginId); + if (ret) LoginId = IntPtr.Zero; + + return ret; + } + + public override bool ConnectSuccess() + { + return LoginId != IntPtr.Zero; + } + + public override void BuildException() + { + uint errCode = (uint)DaHuaOriSDK.CLIENT_GetLastError(); + if (errCode == 0) return; + errCode -= 0x80000000; + throw CameraException.New(CameraType.DaHua, (int)errCode); + } + + #endregion Base Method + + #region Main Method + + private static class GPIParams + { + public static int Size { get; private set; } + public static Type Type { get; private set; } + + static GPIParams() + { + DaHuaOriSDK.DH_PTZ_LOCATION_INFO info = new(); + Size = Marshal.SizeOf(info); + Type = info.GetType(); + } + } + + public override PtzInfo GetPtzInfo() + { + bool ret = ConnectSuccess(); + if (!ret) return PtzInfo.Default; + + DaHuaOriSDK.DH_PTZ_LOCATION_INFO entity = new(); + int nBufLen = GPIParams.Size; + int pRetLen = 0; + IntPtr ptrBuf = Marshal.AllocHGlobal(GPIParams.Size); + Marshal.StructureToPtr(entity, ptrBuf, true); + try + { + ret = DaHuaOriSDK.CLIENT_QueryDevState(LoginId, (int)DaHuaOriSDK.EM_DEVICE_STATE.PTZ_LOCATION, ptrBuf, nBufLen, ref pRetLen, 3000); + if (!ret) { BuildException(); return PtzInfo.Default; } + object? objBuf = Marshal.PtrToStructure(ptrBuf, GPIParams.Type); + if (objBuf == null) return PtzInfo.Default; + entity = (DaHuaOriSDK.DH_PTZ_LOCATION_INFO)objBuf; + return PtzInfo.New(entity.nPTZPan, entity.nPTZTilt, entity.nPTZZoom); + } + finally + { + Marshal.FreeHGlobal(ptrBuf); + } + } + + #endregion Main Method +} \ No newline at end of file diff --git a/EC.Helper/CameraSDK/HiK/HiKOriSDK.cs b/EC.Helper/CameraSDK/HiK/HiKOriSDK.cs new file mode 100644 index 0000000..8d3a435 --- /dev/null +++ b/EC.Helper/CameraSDK/HiK/HiKOriSDK.cs @@ -0,0 +1,226 @@ +//#define Linux32 +//#define Linux64 +//#define Win32 +//#define Win64 + +using System.Runtime.InteropServices; + +namespace EC.Helper.CameraSDK; + +public static class HiKOriSDK +{ + #region Lib Attr + +#if (Linux32) + public const string LibHcNetSDK = @"./libs/hik/linux32/libhcnetsdk.so"; +#elif (Linux64) + public const string LibHcNetSDK = @"./libs/hik/linux64/libhcnetsdk.so"; +#elif (Win32) + public const string LibHcNetSDK = @"./libs/hik/win32/HCNetSDK.dll"; +#elif (Win64) + public const string LibHcNetSDK = @"./libs/hik/win64/HCNetSDK.dll"; +#endif + + #endregion Lib Attr + + static HiKOriSDK() + { + GlobalInit(); + } + + #region Global + + public static bool InitSuccess { get; private set; } + + public static bool GlobalInit() + { + if (InitSuccess) return true; + bool ret = NET_DVR_Init(); + InitSuccess = ret; + if (!ret) throw new Exception("HiKOriSDK global init failure."); + return ret; + } + + public static bool GlobalDestory() + { + if (!InitSuccess) return true; + bool ret = NET_DVR_Cleanup(); + if (ret) InitSuccess = false; + return ret; + } + + #endregion Global + + #region SDK Const + + public const int SERIALNO_LEN = 48; //序列号长度 + + #region 用于 NET_DVR_SetDVRConfig 和 NET_DVR_GetDVRConfig + + public const int NET_DVR_SET_PTZPOS = 292; //云台设置PTZ位置 + public const int NET_DVR_GET_PTZPOS = 293; //云台获取PTZ位置 + public const int NET_DVR_GET_PTZSCOPE = 294; //云台获取PTZ范围 + + #endregion 用于 NET_DVR_SetDVRConfig 和 NET_DVR_GetDVRConfig + + #endregion SDK Const + + #region SDK Struct + + //NET_DVR_Login()参数结构 + [StructLayoutAttribute(LayoutKind.Sequential)] + public struct NET_DVR_DEVICEINFO + { + [MarshalAsAttribute( + UnmanagedType.ByValArray, + SizeConst = SERIALNO_LEN, + ArraySubType = UnmanagedType.I1 + )] + public byte[] sSerialNumber; //序列号 + + public byte byAlarmInPortNum; //DVR报警输入个数 + public byte byAlarmOutPortNum; //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 + } + + //NET_DVR_Login_V30()参数结构 + [StructLayoutAttribute(LayoutKind.Sequential)] + public struct NET_DVR_DEVICEINFO_V30 + { + [MarshalAsAttribute( + UnmanagedType.ByValArray, + SizeConst = SERIALNO_LEN, + ArraySubType = UnmanagedType.I1 + )] + public byte[] sSerialNumber; //序列号 + + public byte byAlarmInPortNum; //报警输入个数 + public byte byAlarmOutPortNum; //报警输出个数 + public byte byDiskNum; //硬盘个数 + public byte byDVRType; //设备类型, 1:DVR 2:ATM DVR 3:DVS ...... + public byte byChanNum; //模拟通道个数 + public byte byStartChan; //起始通道号,例如DVS-1,DVR - 1 + public byte byAudioChanNum; //语音通道数 + public byte byIPChanNum; //最大数字通道个数,低位 + public byte byZeroChanNum; //零通道编码个数 //2010-01-16 + public byte byMainProto; //主码流传输协议类型 0-private, 1-rtsp,2-同时支持private和rtsp + public byte bySubProto; //子码流传输协议类型0-private, 1-rtsp,2-同时支持private和rtsp + 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 bySupport1; // 能力集扩充,位与结果为0表示不支持,1表示支持 + + //bySupport1 & 0x1, 表示是否支持snmp v30 + //bySupport1 & 0x2, 支持区分回放和下载 + //bySupport1 & 0x4, 是否支持布防优先级 + //bySupport1 & 0x8, 智能设备是否支持布防时间段扩展 + //bySupport1 & 0x10, 表示是否支持多磁盘数(超过33个) + //bySupport1 & 0x20, 表示是否支持rtsp over http + //bySupport1 & 0x80, 表示是否支持车牌新报警信息2012-9-28, 且还表示是否支持NET_DVR_IPPARACFG_V40结构体 + public byte bySupport2; /*能力,位与结果为0表示不支持,非0表示支持 + + bySupport2 & 0x1, 表示解码器是否支持通过URL取流解码 + bySupport2 & 0x2, 表示支持FTPV40 + bySupport2 & 0x4, 表示支持ANR + bySupport2 & 0x8, 表示支持CCD的通道参数配置 + bySupport2 & 0x10, 表示支持布防报警回传信息(仅支持抓拍机报警 新老报警结构) + bySupport2 & 0x20, 表示是否支持单独获取设备状态子项 + bySupport2 & 0x40, 表示是否是码流加密设备*/ + public ushort wDevType; //设备型号 + public byte bySupport3; //能力集扩展,位与结果为0表示不支持,1表示支持 + + //bySupport3 & 0x1, 表示是否多码流 + // bySupport3 & 0x4 表示支持按组配置, 具体包含 通道图像参数、报警输入参数、IP报警输入、输出接入参数、 + // 用户参数、设备工作状态、JPEG抓图、定时和时间抓图、硬盘盘组管理 + //bySupport3 & 0x8为1 表示支持使用TCP预览、UDP预览、多播预览中的"延时预览"字段来请求延时预览(后续都将使用这种方式请求延时预览)。而当bySupport3 & 0x8为0时,将使用 "私有延时预览"协议。 + //bySupport3 & 0x10 表示支持"获取报警主机主要状态(V40)"。 + //bySupport3 & 0x20 表示是否支持通过DDNS域名解析取流 + + public byte byMultiStreamProto; //是否支持多码流,按位表示,0-不支持,1-支持,bit1-码流3,bit2-码流4,bit7-主码流,bit-8子码流 + public byte byStartDChan; //起始数字通道号,0表示无效 + public byte byStartDTalkChan; //起始数字对讲通道号,区别于模拟对讲通道号,0表示无效 + public byte byHighDChanNum; //数字通道个数,高位 + public byte bySupport4; + public byte byLanguageType; // 支持语种能力,按位表示,每一位0-不支持,1-支持 + + // byLanguageType 等于0 表示 老设备 + // byLanguageType & 0x1表示支持中文 + // byLanguageType & 0x2表示支持英文 + [MarshalAsAttribute( + UnmanagedType.ByValArray, + SizeConst = 9, + ArraySubType = UnmanagedType.I1 + )] + public byte[] byRes2; //保留 + } + + //球机位置信息 + [StructLayoutAttribute(LayoutKind.Sequential)] + public struct NET_DVR_PTZPOS + { + public ushort wAction; //获取时该字段无效 + public ushort wPanPos; //水平参数 + public ushort wTiltPos; //垂直参数 + public ushort wZoomPos; //变倍参数 + } + + //球机范围信息 + [StructLayoutAttribute(LayoutKind.Sequential)] + public struct NET_DVR_PTZSCOPE + { + public ushort wPanPosMin; //水平参数min + public ushort wPanPosMax; //水平参数max + public ushort wTiltPosMin; //垂直参数min + public ushort wTiltPosMax; //垂直参数max + public ushort wZoomPosMin; //变倍参数min + public ushort wZoomPosMax; //变倍参数max + } + + #endregion SDK Struct + + #region Common Method + + [DllImport(LibHcNetSDK)] + public static extern bool NET_DVR_Init(); + + [DllImport(LibHcNetSDK)] + public static extern bool NET_DVR_Cleanup(); + + [DllImport(LibHcNetSDK)] + public static extern uint NET_DVR_GetLastError(); + + [DllImport(LibHcNetSDK)] + public static extern int NET_DVR_Login_V30( + string sDVRIP, + int wDVRPort, + string sUserName, + string sPassword, + ref NET_DVR_DEVICEINFO_V30 lpDeviceInfo + ); + + [DllImport(LibHcNetSDK)] + public static extern bool NET_DVR_Logout(int iUserID); + + //参数配置 begin + [DllImport(LibHcNetSDK)] + public static extern bool NET_DVR_GetDVRConfig( + int lUserID, + uint dwCommand, + int lChannel, + IntPtr lpOutBuffer, + uint dwOutBufferSize, + ref uint lpBytesReturned + ); + + #endregion Common Method +} \ No newline at end of file diff --git a/EC.Helper/CameraSDK/HiK/HiKSDK.cs b/EC.Helper/CameraSDK/HiK/HiKSDK.cs new file mode 100644 index 0000000..1185f37 --- /dev/null +++ b/EC.Helper/CameraSDK/HiK/HiKSDK.cs @@ -0,0 +1,97 @@ +using System.Runtime.InteropServices; + +namespace EC.Helper.CameraSDK; + +public class HiKSDK : ICameraSDK +{ + #region Attr + + private int LoginId { get; set; } = -1; + + #endregion Attr + + public HiKSDK(CameraInfo cameraInfo) : base(cameraInfo) + { + } + + #region Base Method + + public override bool Init() + { + bool ret = ConnectSuccess(); + if (ret) return true; + + HiKOriSDK.NET_DVR_DEVICEINFO_V30 deviceInfo = new(); + LoginId = HiKOriSDK.NET_DVR_Login_V30(CameraInfo.Ip, CameraInfo.Port, CameraInfo.UserName, CameraInfo.Password, ref deviceInfo); + ret = ConnectSuccess(); + + return ret; + } + + public override bool Destory() + { + bool ret = ConnectSuccess(); + if (!ret) return true; + + ret = HiKOriSDK.NET_DVR_Logout(LoginId); + if (ret) LoginId = -1; + + return ret; + } + + public override bool ConnectSuccess() + { + return LoginId >= 0; + } + + public override void BuildException() + { + uint errCode = HiKOriSDK.NET_DVR_GetLastError(); + if (errCode == 0) return; + throw CameraException.New(CameraType.HiK, (int)errCode); + } + + #endregion Base Method + + #region Main Method + + private static class GPIParams + { + public static int Size { get; private set; } + public static Type Type { get; private set; } + + static GPIParams() + { + HiKOriSDK.NET_DVR_PTZPOS ptzPos = new(); + Size = Marshal.SizeOf(ptzPos); + Type = ptzPos.GetType(); + } + } + + public override PtzInfo GetPtzInfo() + { + bool ret = ConnectSuccess(); + if (!ret) return PtzInfo.Default; + + HiKOriSDK.NET_DVR_PTZPOS entity = new(); + int dwSize = GPIParams.Size; + uint dwReturned = 0; + IntPtr ptrBuf = Marshal.AllocHGlobal(dwSize); + Marshal.StructureToPtr(entity, ptrBuf, true); + try + { + ret = HiKOriSDK.NET_DVR_GetDVRConfig(LoginId, HiKOriSDK.NET_DVR_GET_PTZPOS, 0, ptrBuf, (uint)dwSize, ref dwReturned); + if (!ret) { BuildException(); return PtzInfo.Default; } + object? objBuf = Marshal.PtrToStructure(ptrBuf, GPIParams.Type); + if (objBuf == null) return PtzInfo.Default; + entity = (HiKOriSDK.NET_DVR_PTZPOS)objBuf; + return PtzInfo.New(entity.wPanPos, entity.wTiltPos, entity.wZoomPos); + } + finally + { + Marshal.FreeHGlobal(ptrBuf); + } + } + + #endregion Main Method +} \ No newline at end of file diff --git a/EC.Helper/CameraSDK/YuShi/YuShiOriSDK.cs b/EC.Helper/CameraSDK/YuShi/YuShiOriSDK.cs new file mode 100644 index 0000000..140c86b --- /dev/null +++ b/EC.Helper/CameraSDK/YuShi/YuShiOriSDK.cs @@ -0,0 +1,150 @@ +//#define Linux32 +//#define Linux64 +//#define Win32 +//#define Win64 + +using System.Runtime.InteropServices; + +namespace EC.Helper.CameraSDK; + +public static class YuShiOriSDK +{ + #region Lib Attr + +#if (Linux32) + public const string LibYsNetSDK = @"./libs/yushi/linux64/libNetDEVSDK.so"; +#elif (Linux64) + public const string LibYsNetSDK = @"./libs/yushi/linux64/libNetDEVSDK.so"; +#elif (Win32) + public const string LibYsNetSDK = @"./libs/yushi/win32/NetDEVSDK.dll"; +#elif (Win64) + public const string LibYsNetSDK = @"./libs/yushi/win64/NetDEVSDK.dll"; +#endif + + #endregion Lib Attr + + static YuShiOriSDK() + { + GlobalInit(); + } + + #region Global + + public static bool InitSuccess { get; private set; } + + public static bool GlobalInit() + { + if (InitSuccess) return true; + bool ret = NETDEV_Init(); + InitSuccess = ret; + if (!ret) throw new Exception("YuShiOriSDK global init failure."); + return ret; + } + + public static bool GlobalDestory() + { + if (!InitSuccess) return true; + bool ret = NETDEV_Cleanup(); + if (ret) InitSuccess = false; + return ret; + } + + #endregion Global + + #region SDK Const + + /* Common length */ + public const int NETDEV_LEN_64 = 64; + public const int NETDEV_LEN_128 = 128; + public const int NETDEV_LEN_132 = 132; + public const int NETDEV_LEN_260 = 260; + + #endregion SDK Const + + #region SDK Struct + + [StructLayout(LayoutKind.Sequential)] + public struct NETDEV_DEVICE_LOGIN_INFO_S + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NETDEV_LEN_260)] + public string szIPAddr; /* IP地址/域名 */ + + public Int32 dwPort; /* 端口号 */ + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NETDEV_LEN_132)] + public string szUserName; /* 用户名 */ + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NETDEV_LEN_128)] + public string szPassword; /* 密码 */ + + public Int32 dwLoginProto; /* 登录协议, 参见NETDEV_LOGIN_PROTO_E */ + public Int32 dwDeviceType; /* 设备类型, 参见NETDEV_DEVICE_TYPE_E */ + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] + public byte[] byRes; /* Reserved */ + }; + + [StructLayout(LayoutKind.Sequential)] + public struct NETDEV_SELOG_INFO_S + { + public Int32 dwSELogCount; + public Int32 dwSELogTime; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public byte[] byRes; + }; + + [StructLayout(LayoutKind.Sequential)] + public struct NETDEV_VIDEO_CHL_DETAIL_INFO_S + { + public Int32 dwChannelID; + public Int32 bPtzSupported; /* Whether ptz is supported */ + public Int32 enStatus; /* Channel status */ + public Int32 dwStreamNum; /* Number of streams */ + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NETDEV_LEN_64)] + public string szChnName; /* Device serial number */ + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] szReserve; + } + + [StructLayout(LayoutKind.Sequential)] + public struct NETDEV_PTZ_STATUS_S + { + public float fPanTiltX; /* 绝对水平坐标 Absolute horizontal coordinates*/ + public float fPanTiltY; /* 绝对竖直坐标 Absolute vertical coordinates*/ + public float fZoomX; /* 绝对聚焦倍数 Absolute multiples*/ + public Int32 enPanTiltStatus;/* 云台状态 PTZ Status*/ + public Int32 enZoomStatus; /* 聚焦状态 Focus Status*/ + }; + + #endregion SDK Struct + + #region Common Method + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern bool NETDEV_Init(); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern bool NETDEV_Cleanup(); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern int NETDEV_GetLastError(); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern IntPtr NETDEV_Login_V30(ref NETDEV_DEVICE_LOGIN_INFO_S pstDevLoginInfo, ref NETDEV_SELOG_INFO_S pstSELogInfo); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern bool NETDEV_Logout(IntPtr lpUserID); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern Int32 NETDEV_QueryVideoChlDetailList(IntPtr lpUserID, ref int pdwChlCount, IntPtr pstVideoChlList); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern bool NETDEV_PTZGetStatus(IntPtr lpUserID, int dwChannelID, ref NETDEV_PTZ_STATUS_S pstPTZStaus); + + //public boolean NETDEV_GetDevConfig(Pointer lpUserID, int dwChannelID, int dwCommand, Pointer lpOutBuffer, int dwOutBufferSize, IntByReference pdwBytesReturned); + + #endregion Common Method +} \ No newline at end of file diff --git a/EC.Helper/CameraSDK/YuShi/YuShiSDK.cs b/EC.Helper/CameraSDK/YuShi/YuShiSDK.cs new file mode 100644 index 0000000..0d810d8 --- /dev/null +++ b/EC.Helper/CameraSDK/YuShi/YuShiSDK.cs @@ -0,0 +1,74 @@ +namespace EC.Helper.CameraSDK; + +public class YuShiSDK : ICameraSDK +{ + #region Attr + + private IntPtr LoginId { get; set; } = IntPtr.Zero; + + #endregion Attr + + public YuShiSDK(CameraInfo cameraInfo) : base(cameraInfo) + { + } + + #region Base Method + + public override bool Init() + { + bool ret = ConnectSuccess(); + if (ret) return true; + + YuShiOriSDK.NETDEV_DEVICE_LOGIN_INFO_S loginInfo = new(); + loginInfo.szIPAddr = CameraInfo.Ip; + loginInfo.dwPort = CameraInfo.Port; + loginInfo.szUserName = CameraInfo.UserName; + loginInfo.szPassword = CameraInfo.Password; + YuShiOriSDK.NETDEV_SELOG_INFO_S logInfo = new(); + LoginId = YuShiOriSDK.NETDEV_Login_V30(ref loginInfo, ref logInfo); + ret = ConnectSuccess(); + + return ret; + } + + public override bool Destory() + { + bool ret = ConnectSuccess(); + if (!ret) return true; + + ret = YuShiOriSDK.NETDEV_Logout(LoginId); + if (ret) LoginId = IntPtr.Zero; + + return ret; + } + + public override bool ConnectSuccess() + { + return LoginId != IntPtr.Zero; + } + + public override void BuildException() + { + int errCode = YuShiOriSDK.NETDEV_GetLastError(); + if (errCode == 0) return; + throw CameraException.New(CameraType.YuShi, (int)errCode); + } + + #endregion Base Method + + #region Main Method + + public override PtzInfo GetPtzInfo() + { + bool ret = ConnectSuccess(); + if (!ret) return PtzInfo.Default; + + YuShiOriSDK.NETDEV_PTZ_STATUS_S entity = new(); + ret = YuShiOriSDK.NETDEV_PTZGetStatus(LoginId, 1, ref entity); + if (!ret) { BuildException(); return PtzInfo.Default; } + + return PtzInfo.New(entity.fPanTiltX, entity.fPanTiltY, entity.fZoomX); + } + + #endregion Main Method +} \ No newline at end of file diff --git a/EC.Helper/EC.Helper.csproj b/EC.Helper/EC.Helper.csproj new file mode 100644 index 0000000..808b2db --- /dev/null +++ b/EC.Helper/EC.Helper.csproj @@ -0,0 +1,151 @@ + + + + net6.0 + enable + enable + + + + $(DefineConstants)TRACE;Win64 + + + + $(DefineConstants)TRACE;Win64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + diff --git a/EC.Helper/Test/CameraSDKTest.cs b/EC.Helper/Test/CameraSDKTest.cs new file mode 100644 index 0000000..b7d44ac --- /dev/null +++ b/EC.Helper/Test/CameraSDKTest.cs @@ -0,0 +1,124 @@ +using EC.Helper.CameraSDK; + +namespace EC.Helper.Test; + +public class CameraSDKTest +{ + public static void Test() + { + //HiKTest(); + //DaHuaTest(); + //YuShiTest(); + } + + public static void HiKTest() + { + Console.WriteLine("====HiK=========================="); + + try + { + string ip = "192.168.1.65"; + string username = "admin"; + string password = "hk123456"; + int type = (int)CameraType.HiK; + CameraInfo cameraInfo = CameraInfo.New(type, ip, username, password); + ICameraSDK sdk = new HiKSDK(cameraInfo); + ICameraSDK sdk2 = new HiKSDK(cameraInfo); + sdk.Init(); + sdk2.Init(); + + PtzInfo ptzInfo = sdk.GetPtzInfo(); + Console.WriteLine($"{ptzInfo.Pan}, {ptzInfo.Tilt}, {ptzInfo.Zoom}"); + + sdk.Destory(); + + Thread.Sleep(1000); + + ptzInfo = sdk.GetPtzInfo(); + Console.WriteLine($"{ptzInfo.Pan}, {ptzInfo.Tilt}, {ptzInfo.Zoom}"); + + ptzInfo = sdk2.GetPtzInfo(); + Console.WriteLine($"{ptzInfo.Pan}, {ptzInfo.Tilt}, {ptzInfo.Zoom}"); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + throw; + } + Console.WriteLine("================================="); + } + + public static void DaHuaTest() + { + Console.WriteLine("====DaHua========================"); + + try + { + string ip = "192.168.1.71"; + string username = "admin"; + string password = "hk123456"; + int type = (int)CameraType.DaHua; + CameraInfo cameraInfo = CameraInfo.New(type, ip, username, password); + ICameraSDK sdk = new DaHuaSDK(cameraInfo); + ICameraSDK sdk2 = new DaHuaSDK(cameraInfo); + sdk.Init(); + sdk2.Init(); + PtzInfo ptzInfo = sdk.GetPtzInfo(); + Console.WriteLine($"{ptzInfo.Pan}, {ptzInfo.Tilt}, {ptzInfo.Zoom}"); + + sdk.Destory(); + + Thread.Sleep(1000); + + ptzInfo = sdk.GetPtzInfo(); + Console.WriteLine($"{ptzInfo.Pan}, {ptzInfo.Tilt}, {ptzInfo.Zoom}"); + + ptzInfo = sdk2.GetPtzInfo(); + Console.WriteLine($"{ptzInfo.Pan}, {ptzInfo.Tilt}, {ptzInfo.Zoom}"); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + throw; + } + + Console.WriteLine("================================="); + } + + public static void YuShiTest() + { + Console.WriteLine("====YuShi========================"); + + try + { + string ip = "192.168.1.109"; + string username = "admin"; + string password = "hk123456"; + int type = (int)CameraType.YuShi; + CameraInfo cameraInfo = CameraInfo.New(type, ip, username, password); + ICameraSDK sdk = new YuShiSDK(cameraInfo); + ICameraSDK sdk2 = new YuShiSDK(cameraInfo); + sdk.Init(); + sdk2.Init(); + PtzInfo ptzInfo = sdk.GetPtzInfo(); + Console.WriteLine($"{ptzInfo.Pan}, {ptzInfo.Tilt}, {ptzInfo.Zoom}"); + + sdk.Destory(); + + Thread.Sleep(1000); + + ptzInfo = sdk.GetPtzInfo(); + Console.WriteLine($"{ptzInfo.Pan}, {ptzInfo.Tilt}, {ptzInfo.Zoom}"); + + ptzInfo = sdk2.GetPtzInfo(); + Console.WriteLine($"{ptzInfo.Pan}, {ptzInfo.Tilt}, {ptzInfo.Zoom}"); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + throw; + } + + Console.WriteLine("================================="); + } +} \ No newline at end of file diff --git a/EC.Helper/libs/dahua/linux32/libdhnetsdk.so b/EC.Helper/libs/dahua/linux32/libdhnetsdk.so new file mode 100644 index 0000000..785f8b7 Binary files /dev/null and b/EC.Helper/libs/dahua/linux32/libdhnetsdk.so differ diff --git a/EC.Helper/libs/dahua/linux64/libdhnetsdk.so b/EC.Helper/libs/dahua/linux64/libdhnetsdk.so new file mode 100644 index 0000000..2bae458 Binary files /dev/null and b/EC.Helper/libs/dahua/linux64/libdhnetsdk.so differ diff --git a/EC.Helper/libs/dahua/win32/dhnetsdk.dll b/EC.Helper/libs/dahua/win32/dhnetsdk.dll new file mode 100644 index 0000000..f6464d6 Binary files /dev/null and b/EC.Helper/libs/dahua/win32/dhnetsdk.dll differ diff --git a/EC.Helper/libs/dahua/win64/dhnetsdk.dll b/EC.Helper/libs/dahua/win64/dhnetsdk.dll new file mode 100644 index 0000000..aa3a5e4 Binary files /dev/null and b/EC.Helper/libs/dahua/win64/dhnetsdk.dll differ diff --git a/EC.Helper/libs/hik/linux32/HCNetSDKCom/libHCCoreDevCfg.so b/EC.Helper/libs/hik/linux32/HCNetSDKCom/libHCCoreDevCfg.so new file mode 100644 index 0000000..c0ba2c3 Binary files /dev/null and b/EC.Helper/libs/hik/linux32/HCNetSDKCom/libHCCoreDevCfg.so differ diff --git a/EC.Helper/libs/hik/linux32/HCNetSDKCom/libHCPreview.so b/EC.Helper/libs/hik/linux32/HCNetSDKCom/libHCPreview.so new file mode 100644 index 0000000..0266618 Binary files /dev/null and b/EC.Helper/libs/hik/linux32/HCNetSDKCom/libHCPreview.so differ diff --git a/EC.Helper/libs/hik/linux32/libHCCore.so b/EC.Helper/libs/hik/linux32/libHCCore.so new file mode 100644 index 0000000..a20f02d Binary files /dev/null and b/EC.Helper/libs/hik/linux32/libHCCore.so differ diff --git a/EC.Helper/libs/hik/linux32/libcrypto.so.1.1 b/EC.Helper/libs/hik/linux32/libcrypto.so.1.1 new file mode 100644 index 0000000..3a7f179 Binary files /dev/null and b/EC.Helper/libs/hik/linux32/libcrypto.so.1.1 differ diff --git a/EC.Helper/libs/hik/linux32/libhcnetsdk.so b/EC.Helper/libs/hik/linux32/libhcnetsdk.so new file mode 100644 index 0000000..88817a0 Binary files /dev/null and b/EC.Helper/libs/hik/linux32/libhcnetsdk.so differ diff --git a/EC.Helper/libs/hik/linux32/libssl.so.1.1 b/EC.Helper/libs/hik/linux32/libssl.so.1.1 new file mode 100644 index 0000000..3b5628e Binary files /dev/null and b/EC.Helper/libs/hik/linux32/libssl.so.1.1 differ diff --git a/EC.Helper/libs/hik/linux64/HCNetSDKCom/libHCCoreDevCfg.so b/EC.Helper/libs/hik/linux64/HCNetSDKCom/libHCCoreDevCfg.so new file mode 100644 index 0000000..402b4dc Binary files /dev/null and b/EC.Helper/libs/hik/linux64/HCNetSDKCom/libHCCoreDevCfg.so differ diff --git a/EC.Helper/libs/hik/linux64/HCNetSDKCom/libHCPreview.so b/EC.Helper/libs/hik/linux64/HCNetSDKCom/libHCPreview.so new file mode 100644 index 0000000..9df6065 Binary files /dev/null and b/EC.Helper/libs/hik/linux64/HCNetSDKCom/libHCPreview.so differ diff --git a/EC.Helper/libs/hik/linux64/libHCCore.so b/EC.Helper/libs/hik/linux64/libHCCore.so new file mode 100644 index 0000000..49ce40f Binary files /dev/null and b/EC.Helper/libs/hik/linux64/libHCCore.so differ diff --git a/EC.Helper/libs/hik/linux64/libcrypto.so.1.1 b/EC.Helper/libs/hik/linux64/libcrypto.so.1.1 new file mode 100644 index 0000000..88c3746 Binary files /dev/null and b/EC.Helper/libs/hik/linux64/libcrypto.so.1.1 differ diff --git a/EC.Helper/libs/hik/linux64/libhcnetsdk.so b/EC.Helper/libs/hik/linux64/libhcnetsdk.so new file mode 100644 index 0000000..89a8d7d Binary files /dev/null and b/EC.Helper/libs/hik/linux64/libhcnetsdk.so differ diff --git a/EC.Helper/libs/hik/linux64/libssl.so.1.1 b/EC.Helper/libs/hik/linux64/libssl.so.1.1 new file mode 100644 index 0000000..f3e4481 Binary files /dev/null and b/EC.Helper/libs/hik/linux64/libssl.so.1.1 differ diff --git a/EC.Helper/libs/hik/win32/HCCore.dll b/EC.Helper/libs/hik/win32/HCCore.dll new file mode 100644 index 0000000..997aba4 Binary files /dev/null and b/EC.Helper/libs/hik/win32/HCCore.dll differ diff --git a/EC.Helper/libs/hik/win32/HCNetSDK.dll b/EC.Helper/libs/hik/win32/HCNetSDK.dll new file mode 100644 index 0000000..4ab572c Binary files /dev/null and b/EC.Helper/libs/hik/win32/HCNetSDK.dll differ diff --git a/EC.Helper/libs/hik/win32/HCNetSDKCom/HCCoreDevCfg.dll b/EC.Helper/libs/hik/win32/HCNetSDKCom/HCCoreDevCfg.dll new file mode 100644 index 0000000..08ace5e Binary files /dev/null and b/EC.Helper/libs/hik/win32/HCNetSDKCom/HCCoreDevCfg.dll differ diff --git a/EC.Helper/libs/hik/win32/HCNetSDKCom/HCPreview.dll b/EC.Helper/libs/hik/win32/HCNetSDKCom/HCPreview.dll new file mode 100644 index 0000000..b8bf1f5 Binary files /dev/null and b/EC.Helper/libs/hik/win32/HCNetSDKCom/HCPreview.dll differ diff --git a/EC.Helper/libs/hik/win32/libcrypto-1_1.dll b/EC.Helper/libs/hik/win32/libcrypto-1_1.dll new file mode 100644 index 0000000..872a807 Binary files /dev/null and b/EC.Helper/libs/hik/win32/libcrypto-1_1.dll differ diff --git a/EC.Helper/libs/hik/win32/libssl-1_1.dll b/EC.Helper/libs/hik/win32/libssl-1_1.dll new file mode 100644 index 0000000..331f43b Binary files /dev/null and b/EC.Helper/libs/hik/win32/libssl-1_1.dll differ diff --git a/EC.Helper/libs/hik/win64/HCCore.dll b/EC.Helper/libs/hik/win64/HCCore.dll new file mode 100644 index 0000000..266afa3 Binary files /dev/null and b/EC.Helper/libs/hik/win64/HCCore.dll differ diff --git a/EC.Helper/libs/hik/win64/HCNetSDK.dll b/EC.Helper/libs/hik/win64/HCNetSDK.dll new file mode 100644 index 0000000..0c4ef60 Binary files /dev/null and b/EC.Helper/libs/hik/win64/HCNetSDK.dll differ diff --git a/EC.Helper/libs/hik/win64/HCNetSDKCom/HCCoreDevCfg.dll b/EC.Helper/libs/hik/win64/HCNetSDKCom/HCCoreDevCfg.dll new file mode 100644 index 0000000..63a8836 Binary files /dev/null and b/EC.Helper/libs/hik/win64/HCNetSDKCom/HCCoreDevCfg.dll differ diff --git a/EC.Helper/libs/hik/win64/HCNetSDKCom/HCPreview.dll b/EC.Helper/libs/hik/win64/HCNetSDKCom/HCPreview.dll new file mode 100644 index 0000000..92a3cf9 Binary files /dev/null and b/EC.Helper/libs/hik/win64/HCNetSDKCom/HCPreview.dll differ diff --git a/EC.Helper/libs/hik/win64/libcrypto-1_1-x64.dll b/EC.Helper/libs/hik/win64/libcrypto-1_1-x64.dll new file mode 100644 index 0000000..6731338 Binary files /dev/null and b/EC.Helper/libs/hik/win64/libcrypto-1_1-x64.dll differ diff --git a/EC.Helper/libs/hik/win64/libssl-1_1-x64.dll b/EC.Helper/libs/hik/win64/libssl-1_1-x64.dll new file mode 100644 index 0000000..ac5e8fd Binary files /dev/null and b/EC.Helper/libs/hik/win64/libssl-1_1-x64.dll differ diff --git a/EC.Helper/libs/yushi/linux64/libNetDEVSDK.so b/EC.Helper/libs/yushi/linux64/libNetDEVSDK.so new file mode 100644 index 0000000..6363434 Binary files /dev/null and b/EC.Helper/libs/yushi/linux64/libNetDEVSDK.so differ diff --git a/EC.Helper/libs/yushi/win32/NetDEVSDK.dll b/EC.Helper/libs/yushi/win32/NetDEVSDK.dll new file mode 100644 index 0000000..4d40904 Binary files /dev/null and b/EC.Helper/libs/yushi/win32/NetDEVSDK.dll differ diff --git a/EC.Helper/libs/yushi/win64/NetDEVSDK.dll b/EC.Helper/libs/yushi/win64/NetDEVSDK.dll new file mode 100644 index 0000000..b705019 Binary files /dev/null and b/EC.Helper/libs/yushi/win64/NetDEVSDK.dll differ