using Serilog; namespace SHH.CameraSdk.HikFeatures; public class HikPtzProvider : IPtzFeature { private readonly IHikContext _context; public HikPtzProvider(IHikContext context) { _context = context; } /// /// 判断该动作是否支持速度参数 /// private static bool IsSpeedSupported(PtzAction action) { // Optimized: 方向和缩放支持速度,其余(雨刷/聚焦/光圈)为开关量或标准调节 return action <= PtzAction.ZoomOut; } public async Task PtzControlAsync(PtzAction action, bool stop, int speed) { int userId = _context.GetUserId(); if (userId < 0) throw new InvalidOperationException("设备离线"); // 1. 映射指令 uint hikCommand = action switch { PtzAction.Left => HikNativeMethods.PAN_LEFT, PtzAction.Up => HikNativeMethods.TILT_UP, PtzAction.Right => HikNativeMethods.PAN_RIGHT, PtzAction.Down => HikNativeMethods.TILT_DOWN, PtzAction.LeftUp => HikNativeMethods.UP_LEFT, // 海康 SDK: 左上 PtzAction.LeftDown => HikNativeMethods.DOWN_LEFT, // 海康 SDK: 左下 PtzAction.RightUp => HikNativeMethods.UP_RIGHT, // 海康 SDK: 右上 PtzAction.RightDown => HikNativeMethods.DOWN_RIGHT, // 海康 SDK: 右下 PtzAction.Auto => HikNativeMethods.PAN_AUTO, PtzAction.ZoomIn => HikNativeMethods.ZOOM_IN, PtzAction.ZoomOut => HikNativeMethods.ZOOM_OUT, PtzAction.FocusNear => HikNativeMethods.FOCUS_NEAR, PtzAction.FocusFar => HikNativeMethods.FOCUS_FAR, PtzAction.IrisOpen => HikNativeMethods.IRIS_OPEN, PtzAction.IrisClose => HikNativeMethods.IRIS_CLOSE, PtzAction.Wiper => HikNativeMethods.WIPER_PWRON, _ => 0 }; if (hikCommand == 0) return; // 2. 转换停止标志 (海康: 0=开始, 1=停止) uint dwStop = stop ? 1u : 0u; // 3. 调用 SDK await Task.Run(() => { bool result; // Optimized: 接口分流逻辑,确保不同类型的动作调用正确的 SDK 接口 if (IsSpeedSupported(action)) { uint dwSpeed = (uint)Math.Clamp(speed, 1, 7); result = HikNativeMethods.NET_DVR_PTZControlWithSpeed_Other(userId, 1, hikCommand, dwStop, dwSpeed); } else { // 对于雨刷、聚焦、光圈,使用不带速度的接口 result = HikNativeMethods.NET_DVR_PTZControl_Other(userId, 1, hikCommand, dwStop); } if (!result) { // Modified: 统一记录到 D:\Logs uint errorCode = HikNativeMethods.NET_DVR_GetLastError(); Log.Warning("Ayay.AiVideo: PTZ {Action} failed. Stop: {Stop}, ErrorCode: {ErrorCode}", action, stop, errorCode); } }); } public async Task PtzStepAsync(PtzAction action, int durationMs, int speed) { // 1. 开始转动 (调用已有的逻辑,stop=false) await PtzControlAsync(action, false, speed); // 2. 等待指定时间 (非阻塞等待) // 注意:这里使用 Task.Delay,精度对云台控制来说足够了 if (durationMs > 0) { await Task.Delay(durationMs); } // 3. 停止转动 (调用已有的逻辑,stop=true) await PtzControlAsync(action, true, speed); } }