Files
Ayay/SHH.CameraSdk/Drivers/HikVision/Features/HikPtzProvider.cs

99 lines
3.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Serilog;
namespace SHH.CameraSdk.HikFeatures;
public class HikPtzProvider : IPtzFeature
{
private readonly IHikContext _context;
public HikPtzProvider(IHikContext context)
{
_context = context;
}
/// <summary>
/// 判断该动作是否支持速度参数
/// </summary>
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);
}
}