using System.Runtime.InteropServices; using static EC.Util.CameraSDK.YuShiOriSdk; namespace EC.Util.CameraSDK; public class YuShiSdk : ICameraSdk { #region Fields private IntPtr LoginId { get; set; } = IntPtr.Zero; private int Channel { get; } = 1; #endregion Fields 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() { szIPAddr = CameraInfo.Ip, dwPort = CameraInfo.Port, szUserName = CameraInfo.UserName, szPassword = CameraInfo.Password }; YuShiOriSdk.NETDEV_SELOG_INFO_S logInfo = new(); LoginId = YuShiOriSdk.NETDEV_Login_V30(ref loginInfo, ref logInfo); ret = ConnectSuccess(); if (!ret) BuildException(); //别删 NETDEV_QueryVideoChlDetailList,否则 NETDEV_PTZPreset_Other 教做人 int pdwChlCount = 16; IntPtr pstVideoChlList = Marshal.AllocHGlobal(pdwChlCount * Marshal.SizeOf(typeof(NETDEV_VIDEO_CHL_DETAIL_INFO_S))); YuShiOriSdk.NETDEV_QueryVideoChlDetailList(LoginId, ref pdwChlCount, pstVideoChlList); return ret; } public override bool Destory() { bool ret = ConnectSuccess(); if (!ret) return true; ret = YuShiOriSdk.NETDEV_Logout(LoginId); if (ret) LoginId = IntPtr.Zero; else BuildException(); return ret; } public override bool ConnectSuccess() { return LoginId != IntPtr.Zero; } internal override void BuildException() { int errCode = YuShiOriSdk.NETDEV_GetLastError(); if (errCode == 0) return; throw CameraException.New(CameraInfo, errCode); } #endregion Base Method #region Ptz 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, Channel, ref entity); if (!ret) { BuildException(); return PtzInfo.Default; } return PtzInfo.New(entity.fPanTiltX, entity.fPanTiltY, entity.fZoomX); } public override bool TryGetPtzInfo(out PtzInfo ptzInfo) { bool ret = ConnectSuccess(); if (!ret) { ptzInfo = PtzInfo.Default; return false; } YuShiOriSdk.NETDEV_PTZ_STATUS_S entity = new(); ret = YuShiOriSdk.NETDEV_PTZGetStatus(LoginId, Channel, ref entity); if (!ret) { BuildException(); ptzInfo = PtzInfo.Default; return false; } ptzInfo = PtzInfo.New(entity.fPanTiltX, entity.fPanTiltY, entity.fZoomX); return true; } public override bool PtzMove(int cmd, int stop, int speed) { if (!ConnectSuccess()) return false; if (stop == 1) cmd = YuShiOriSdk.ALLSTOP; int retNum = YuShiOriSdk.NETDEV_PTZControl_Other(LoginId, Channel, cmd, speed); bool ret = retNum == YuShiOriSdk.TRUE; if (!ret) BuildException(); return ret; } public override bool PtzPreset(int cmd, int presetId) { if (!ConnectSuccess()) return false; int retNum = YuShiOriSdk.NETDEV_PTZPreset_Other(LoginId, Channel, cmd, Array.Empty(), presetId); bool ret = retNum == YuShiOriSdk.TRUE; if (!ret) BuildException(); return ret; } #endregion Ptz Method #region Video Method private IntPtr Hwnd { get; set; } private IntPtr RealplayHandle { get; set; } = IntPtr.Zero; private int RealplayPort { get; set; } = -1; public override void StartPlay(IntPtr hwnd) { if (!ConnectSuccess() || IsPlaying()) return; Hwnd = hwnd; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) StartPlayWindows(); else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) StartPlayLinux(); else Hwnd = IntPtr.Zero; } private void StartPlayWindows() { YuShiOriSdk.NETDEV_PREVIEWINFO_S stPreviewInfo = new() { hPlayWnd = Hwnd, dwChannelID = Channel, dwStreamType = 0, // YuShiOriSdk.NETDEV_LIVE_STREAM_INDEX_E dwLinkMode = 1, // YuShiOriSdk.NETDEV_PROTOCAL_E dwFluency = 0, // YuShiOriSdk.NETDEV_PICTURE_FLUENCY_E }; RealplayHandle = YuShiOriSdk.NETDEV_RealPlay(LoginId, ref stPreviewInfo, null, IntPtr.Zero); if (RealplayHandle == IntPtr.Zero) BuildException(); } private void StartPlayLinux() { YuShiOriSdk.NETDEV_PREVIEWINFO_S stPreviewInfo = new() { hPlayWnd = Hwnd, dwChannelID = Channel, dwStreamType = 0, // YuShiOriSdk.NETDEV_LIVE_STREAM_INDEX_E dwLinkMode = 1, // YuShiOriSdk.NETDEV_PROTOCAL_E dwFluency = 0, // YuShiOriSdk.NETDEV_PICTURE_FLUENCY_E }; RealplayHandle = YuShiOriSdk.NETDEV_RealPlay(LoginId, ref stPreviewInfo, null, IntPtr.Zero); if (RealplayHandle == IntPtr.Zero) BuildException(); } public override void StopPlay() { if (!IsPlaying()) return; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) StopPlayWindows(); else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) StopPlayLinux(); Hwnd = IntPtr.Zero; } private void StopPlayWindows() { int ret = YuShiOriSdk.NETDEV_StopRealPlay(RealplayHandle); RealplayHandle = IntPtr.Zero; if (ret == YuShiOriSdk.FALSE) BuildException(); } private void StopPlayLinux() { int ret = YuShiOriSdk.NETDEV_StopRealPlay(RealplayHandle); RealplayHandle = IntPtr.Zero; RealDataCallBack = null; if (ret == YuShiOriSdk.FALSE) BuildException(); } public YuShiOriSdk.RealDataCallBack? RealDataCallBack { get; set; } private void DefaultRealDataCallBack(IntPtr lpPlayHandle, IntPtr pucBuffer, uint dwBufSize, uint dwMediaDataType, IntPtr lpUserParam) { if (RealplayPort < 0 || dwBufSize <= 0) return; Console.WriteLine($"{lpPlayHandle},{pucBuffer},{dwBufSize},{dwMediaDataType},{lpUserParam}"); } public override bool IsPlaying() { return RealplayHandle != IntPtr.Zero; } #endregion Video Method }