diff --git a/EC.Util/CameraSDK/HiK/HiKOriSDK.cs b/EC.Util/CameraSDK/HiK/HiKOriSDK.cs index 47dbb2f..99a55f5 100644 --- a/EC.Util/CameraSDK/HiK/HiKOriSDK.cs +++ b/EC.Util/CameraSDK/HiK/HiKOriSDK.cs @@ -188,6 +188,46 @@ public static class HiKOriSDK public ushort wZoomPosMax; //变倍参数max } + //邦诺CVR + public const int MAX_ID_COUNT = 256; + + public const int MAX_STREAM_ID_COUNT = 1024; + public const int STREAM_ID_LEN = 32; + public const int PLAN_ID_LEN = 32; + + //预览V40接口 + [StructLayoutAttribute(LayoutKind.Sequential)] + public struct NET_DVR_PREVIEWINFO + { + public Int32 lChannel; //通道号 + public uint dwStreamType; // 码流类型,0-主码流,1-子码流,2-码流3,3-码流4 等以此类推 + public uint dwLinkMode; // 0:TCP方式,1:UDP方式,2:多播方式,3 - RTP方式,4-RTP/RTSP,5-RSTP/HTTP + public IntPtr hPlayWnd; //播放窗口的句柄,为NULL表示不播放图象 + public bool bBlocked; //0-非阻塞取流, 1-阻塞取流, 如果阻塞SDK内部connect失败将会有5s的超时才能够返回,不适合于轮询取流操作. + public bool bPassbackRecord; //0-不启用录像回传,1启用录像回传 + public byte byPreviewMode; //预览模式,0-正常预览,1-延迟预览 + + [MarshalAsAttribute( + UnmanagedType.ByValArray, + SizeConst = STREAM_ID_LEN, + ArraySubType = UnmanagedType.I1 + )] + public byte[] byStreamID; //流ID,lChannel为0xffffffff时启用此参数 + + public byte byProtoType; //应用层取流协议,0-私有协议,1-RTSP协议 + public byte byRes1; + public byte byVideoCodingType; //码流数据编解码类型 0-通用编码数据 1-热成像探测器产生的原始数据(温度数据的加密信息,通过去加密运算,将原始数据算出真实的温度值) + public uint dwDisplayBufNum; //播放库播放缓冲区最大缓冲帧数,范围1-50,置0时默认为1 + public byte byNPQMode; //NPQ是直连模式,还是过流媒体 0-直连 1-过流媒体 + + [MarshalAsAttribute( + UnmanagedType.ByValArray, + SizeConst = 215, + ArraySubType = UnmanagedType.I1 + )] + public byte[] byRes; + } + #endregion SDK Struct #region Common Method @@ -241,5 +281,57 @@ public static class HiKOriSDK uint dwPresetIndex ); + /********************************************************* + Function: REALDATACALLBACK + Desc: 预览回调 + Input: lRealHandle 当前的预览句柄 + dwDataType 数据类型 + pBuffer 存放数据的缓冲区指针 + dwBufSize 缓冲区大小 + pUser 用户数据 + Output: + Return: void + **********************************************************/ + + public delegate void REALDATACALLBACK( + Int32 lRealHandle, + UInt32 dwDataType, + IntPtr pBuffer, + UInt32 dwBufSize, + IntPtr pUser + ); + + /********************************************************* + Function: NET_DVR_RealPlay_V40 + Desc: 实时预览扩展接口。 + Input: lUserID [in] NET_DVR_Login()或NET_DVR_Login_V30()的返回值 + lpPreviewInfo [in] 预览参数 + fRealDataCallBack_V30 [in] 码流数据回调函数 + pUser [in] 用户数据 + Output: + Return: 1表示失败,其他值作为NET_DVR_StopRealPlay等函数的句柄参数 + **********************************************************/ + + [DllImport(LibHcNetSDK)] + public static extern int NET_DVR_RealPlay_V40( + int iUserID, + ref NET_DVR_PREVIEWINFO lpPreviewInfo, + REALDATACALLBACK fRealDataCallBack_V30, + IntPtr pUser + ); + + // [DllImport(@".\HCNetSDK.dll")] + // public static extern int NET_DVR_GetRealPlayerIndex(int lRealHandle); + /********************************************************* + Function: NET_DVR_StopRealPlay + Desc: 停止预览。 + Input: lRealHandle [in] 预览句柄,NET_DVR_RealPlay或者NET_DVR_RealPlay_V30的返回值 + Output: + Return: + **********************************************************/ + + [DllImport(LibHcNetSDK)] + public static extern bool NET_DVR_StopRealPlay(int iRealHandle); + #endregion Common Method } \ No newline at end of file diff --git a/EC.Util/CameraSDK/HiK/HiKSDK.cs b/EC.Util/CameraSDK/HiK/HiKSDK.cs index a90a01a..7489568 100644 --- a/EC.Util/CameraSDK/HiK/HiKSDK.cs +++ b/EC.Util/CameraSDK/HiK/HiKSDK.cs @@ -8,6 +8,8 @@ public class HiKSDK : ICameraSDK private int LoginId { get; set; } = -1; + private int realplayHandle { get; set; } = -1; + #endregion Attr public HiKSDK(CameraInfo cameraInfo) : base(cameraInfo) @@ -140,4 +142,37 @@ public class HiKSDK : ICameraSDK } #endregion Ptz Method + + #region Video Method + + public void StartPlay(IntPtr hwnd) + { + bool ret = ConnectSuccess(); + if (!ret) return; + HiKOriSDK.NET_DVR_PREVIEWINFO previewInfo = new() + { + hPlayWnd = hwnd, //预览窗口 + lChannel = 1, //预览的设备通道 + dwStreamType = 0, //码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推 + dwLinkMode = 0, //连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP + bBlocked = true, //0- 非阻塞取流,1- 阻塞取流 + dwDisplayBufNum = 1, //播放库播放缓冲区最大缓冲帧数 + byProtoType = 0, + byPreviewMode = 0 + }; + IntPtr pUser = new(); //用户数据 + realplayHandle = HiKOriSDK.NET_DVR_RealPlay_V40(LoginId, ref previewInfo, null, pUser); + if (realplayHandle < 0) BuildException(); + } + + public void StopPlay() + { + if (realplayHandle >= 0) + { + HiKOriSDK.NET_DVR_StopRealPlay(realplayHandle); + realplayHandle = -1; + } + } + + #endregion Video Method } \ No newline at end of file diff --git a/EC.Util/EC.Util.csproj b/EC.Util/EC.Util.csproj index 3ab8825..3ac9eb4 100644 --- a/EC.Util/EC.Util.csproj +++ b/EC.Util/EC.Util.csproj @@ -7,15 +7,29 @@ + + + + + + + PreserveNewest + + + + + + PreserveNewest + PreserveNewest @@ -28,12 +42,21 @@ PreserveNewest + + PreserveNewest + PreserveNewest PreserveNewest + + PreserveNewest + + + PreserveNewest + diff --git a/EC.Util/libs/hik-win64/AudioRender.dll b/EC.Util/libs/hik-win64/AudioRender.dll new file mode 100644 index 0000000..438acf5 Binary files /dev/null and b/EC.Util/libs/hik-win64/AudioRender.dll differ diff --git a/EC.Util/libs/hik-win64/HXVA.dll b/EC.Util/libs/hik-win64/HXVA.dll new file mode 100644 index 0000000..37a5bb7 Binary files /dev/null and b/EC.Util/libs/hik-win64/HXVA.dll differ diff --git a/EC.Util/libs/hik-win64/HmMerge.dll b/EC.Util/libs/hik-win64/HmMerge.dll new file mode 100644 index 0000000..d46a6ac Binary files /dev/null and b/EC.Util/libs/hik-win64/HmMerge.dll differ diff --git a/EC.Util/libs/hik-win64/PlayCtrl.dll b/EC.Util/libs/hik-win64/PlayCtrl.dll new file mode 100644 index 0000000..4672356 Binary files /dev/null and b/EC.Util/libs/hik-win64/PlayCtrl.dll differ diff --git a/EC.Util/libs/hik-win64/SuperRender.dll b/EC.Util/libs/hik-win64/SuperRender.dll new file mode 100644 index 0000000..5c94d02 Binary files /dev/null and b/EC.Util/libs/hik-win64/SuperRender.dll differ diff --git a/JiLinApp.Biz/TransmitAlarm/Common/Config.cs b/JiLinApp.Biz/TransmitAlarm/Common/Config.cs index e426901..1dc5ee0 100644 --- a/JiLinApp.Biz/TransmitAlarm/Common/Config.cs +++ b/JiLinApp.Biz/TransmitAlarm/Common/Config.cs @@ -2,6 +2,8 @@ public class TransmitAlarmConfig { + public bool RealPlay { get; set; } + public string Type { get; set; } public MqttConfig Mqtt { get; set; } diff --git a/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs b/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs index d690dc0..6a32df8 100644 --- a/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs +++ b/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs @@ -104,8 +104,4 @@ public class AlarmMqttService : IAlarmService } #endregion Server Event - - #region - - #endregion } \ No newline at end of file diff --git a/JiLinApp.Docking/Ptz/PtzCmd.cs b/JiLinApp.Docking/Ptz/PtzCmd.cs index 5962239..2e7789c 100644 --- a/JiLinApp.Docking/Ptz/PtzCmd.cs +++ b/JiLinApp.Docking/Ptz/PtzCmd.cs @@ -1,13 +1,12 @@ using EC.Util.CameraSDK; -using System; namespace JiLinApp.Docking.Ptz; public class PtzCmd { - public static PtzControlType GetControlType(string ctrlStr) + public static PtzControlType GetControlType(string ctrlType) { - return ctrlStr switch + return ctrlType switch { "PelcoD" => PtzControlType.PelcoD, "PelcoP" => PtzControlType.PelcoP, diff --git a/JiLinApp.Docking/Ptz/PtzConfig.cs b/JiLinApp.Docking/Ptz/PtzConfig.cs new file mode 100644 index 0000000..6bad4ae --- /dev/null +++ b/JiLinApp.Docking/Ptz/PtzConfig.cs @@ -0,0 +1,37 @@ +namespace JiLinApp.Docking.Ptz; + +public class PtzControlTypeConfig +{ + public string Type { get; set; } + + public string Name { get; set; } +} + +public class PtzControlTypeConfigHelper +{ + private static Dictionary PctConfigDict { get; set; } + + public static void Init(List ptzCtrlTypes) + { + if (PctConfigDict != null) return; + Dictionary dict = new(); + foreach (var cfg in ptzCtrlTypes) + { + dict.Add(cfg.Name, cfg); + } + PctConfigDict ??= dict; + } + + public static PtzControlType GetControlType(string ctrlName) + { + PctConfigDict.TryGetValue(ctrlName, out var cfg); + string ctrlType = cfg != null ? cfg.Type : ""; + return ctrlType switch + { + "PelcoD" => PtzControlType.PelcoD, + "PelcoP" => PtzControlType.PelcoP, + "HikSdk" => PtzControlType.HikSdk, + _ => PtzControlType.None + }; + } +} \ No newline at end of file diff --git a/JiLinApp.sln b/JiLinApp.sln index 11d07ac..30cace0 100644 --- a/JiLinApp.sln +++ b/JiLinApp.sln @@ -11,11 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiLinApp.Docking", "JiLinAp EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiLinApp.Biz", "JiLinApp.Biz\JiLinApp.Biz.csproj", "{7CE63A50-C92C-4554-8E0C-F7BED355C1FD}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{97F952A2-D735-42D6-A21B-DCEA87C2D6C9}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/JiLinApp/Components/HikRealPlay.xaml b/JiLinApp/Components/HikRealPlay.xaml new file mode 100644 index 0000000..045d75c --- /dev/null +++ b/JiLinApp/Components/HikRealPlay.xaml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/JiLinApp/Components/HikRealPlay.xaml.cs b/JiLinApp/Components/HikRealPlay.xaml.cs new file mode 100644 index 0000000..50cf8ee --- /dev/null +++ b/JiLinApp/Components/HikRealPlay.xaml.cs @@ -0,0 +1,88 @@ +using EC.Util.CameraSDK; +using System; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Interop; + +namespace JiLinApp.Components; + +/// +/// HikRealPlay.xaml 的交互逻辑 +/// +public partial class HikRealPlay : Window +{ + #region + + private HiKSDK hikSdk { get; } + + #endregion + + public HikRealPlay(HiKSDK hikSdk) + { + InitializeComponent(); + this.hikSdk = hikSdk; + } + + ~HikRealPlay() + { + StopPlay(); + } + + #region Base + + public void StartPlay() + { + IntPtr hwnd = ((HwndSource)PresentationSource.FromVisual(player)).Handle; + hikSdk.StartPlay(hwnd); + } + + public void StopPlay() + { + hikSdk.StopPlay(); + } + + #endregion + private const int GWL_STYLE = -16; + private const int WS_MAXIMIZEBOX = 0x10000; + private const int WS_MINIMIZEBOX = 0x20000; + private const int SWP_NOSIZE = 0x0001; + private const int SWP_NOMOVE = 0x0002; + private const int SWP_NOZORDER = 0x0004; + private const int SWP_FRAMECHANGED = 0x0020; + + [DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)] + private static extern int GetWindowLong32(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll")] + private static extern int GetWindowLongPtr(IntPtr hwnd, int index); + + [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)] + private static extern int SetWindowLong32(IntPtr hwnd, int index, int value); + + [DllImport("user32.dll")] + private static extern int SetWindowLongPtr(IntPtr hwnd, int index, int value); + + [DllImport("user32.dll")] + private static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags); + + #region Util + + public void HideMinButton() + { + IntPtr hwnd = new WindowInteropHelper(this).Handle; + if (IntPtr.Size == 4) + { + var currentStyle = GetWindowLong32(hwnd, GWL_STYLE); + _ = SetWindowLong32(hwnd, GWL_STYLE, (currentStyle & ~WS_MINIMIZEBOX)); + } + else + { + var currentStyle = GetWindowLongPtr(hwnd, GWL_STYLE); + _ = SetWindowLongPtr(hwnd, GWL_STYLE, (currentStyle & ~WS_MINIMIZEBOX)); + } + //call SetWindowPos to make sure the SetWindowLongPtr take effect according to MSDN + SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); + } + + #endregion +} \ No newline at end of file diff --git a/JiLinApp/Core/Config.cs b/JiLinApp/Core/Config.cs index 94a2e17..9961713 100644 --- a/JiLinApp/Core/Config.cs +++ b/JiLinApp/Core/Config.cs @@ -1,5 +1,6 @@ using EC.Util.CameraSDK; using JiLinApp.Biz.TransmitAlarm; +using JiLinApp.Docking.Ptz; using System.Collections.Generic; namespace JiLinApp.Core; @@ -8,9 +9,11 @@ public class AppConfig { public BaseConfig Base { get; set; } - public TransmitAlarmConfig TransmitAlarm { get; set; } + public List ptzCtrlTypes { get; set; } public List CameraList { get; set; } + + public TransmitAlarmConfig TransmitAlarm { get; set; } } public class BaseConfig diff --git a/JiLinApp/Core/Global.cs b/JiLinApp/Core/Global.cs index 330eaff..48ab7e0 100644 --- a/JiLinApp/Core/Global.cs +++ b/JiLinApp/Core/Global.cs @@ -1,6 +1,7 @@ using EC.Util.Common; using JiLinApp.Biz.TransmitAlarm; using JiLinApp.Docking.Alarm; +using JiLinApp.Docking.Ptz; using NewLife.Configuration; using System; using System.IO; @@ -30,6 +31,8 @@ public static class Global // 控制台 if (AppConfig.Base.Console) SystemUtil.AllocConsole(); + // ptzCtrlTypes + PtzControlTypeConfigHelper.Init(AppConfig.ptzCtrlTypes); AlarmService = AlarmServiceFactory.CreateService(AppConfig.TransmitAlarm); AlarmService?.Start(); diff --git a/JiLinApp/Pages/FenceServerManage/Main.xaml.cs b/JiLinApp/Pages/FenceServerManage/Main.xaml.cs index 6d6c0f6..27c023d 100644 --- a/JiLinApp/Pages/FenceServerManage/Main.xaml.cs +++ b/JiLinApp/Pages/FenceServerManage/Main.xaml.cs @@ -1,4 +1,5 @@ -using JiLinApp.Docking.FenceAlarm; +using JiLinApp.Core; +using JiLinApp.Docking.FenceAlarm; using System; using System.Windows; using System.Windows.Controls; diff --git a/JiLinApp/Pages/PtzManage/Main.xaml b/JiLinApp/Pages/PtzManage/Main.xaml index 652a0ee..f6ce88a 100644 --- a/JiLinApp/Pages/PtzManage/Main.xaml +++ b/JiLinApp/Pages/PtzManage/Main.xaml @@ -94,11 +94,7 @@ - - - - - + @@ -165,10 +161,11 @@ - +