namespace SHH.CameraSdk.HikFeatures; public class HikPtzProvider : IPtzFeature { private readonly IHikContext _context; public HikPtzProvider(IHikContext context) { _context = context; } 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.Up => HikNativeMethods.TILT_UP, PtzAction.Down => HikNativeMethods.TILT_DOWN, PtzAction.Left => HikNativeMethods.PAN_LEFT, PtzAction.Right => HikNativeMethods.PAN_RIGHT, 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. 限制速度范围 (1-7) uint dwSpeed = (uint)Math.Clamp(speed, 1, 7); // 4. 调用 SDK await Task.Run(() => { // Channel 默认为 1 bool result = HikNativeMethods.NET_DVR_PTZControlWithSpeed_Other(userId, 1, hikCommand, dwStop, dwSpeed); if (!result) { // 这里通常不抛异常,因为云台繁忙或到头是常态,记录日志即可 // Console.WriteLine($"PTZ Error: {HikNativeMethods.NET_DVR_GetLastError()}"); } }); } 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); } }