namespace SHH.CameraSdk; /// /// 视频源基础配置对象 (V3.3.1 修复版) /// 核心职责:定义建立相机物理连接所需的所有标准化参数与厂商扩展参数 /// 关键修复: /// 1. [Fix Bug U: 配置漂移] 驱动层接收配置时需创建副本,防止外部修改导致的连接异常 /// 2. 强化配置有效性校验,提前拦截非法参数 /// 注意事项:此类为引用类型,传递时建议使用深拷贝 /// public class VideoSourceConfig { #region --- 1. 核心连接配置 (Core Connection Configurations) --- /// 业务系统唯一标识(对应数据库自增ID,全局唯一) public long Id { get; set; } /// 设备显示名称(如:北大门-枪机01,用于前端展示) public string Name { get; set; } = string.Empty; /// 设备品牌(决定加载对应的驱动实现类) [JsonConverter(typeof(JsonStringEnumConverter))] public DeviceBrand Brand { get; set; } = DeviceBrand.Unknown; /// 设备 IP 地址或域名(如 192.168.1.100 或 camera.example.com) public string IpAddress { get; set; } = string.Empty; /// 设备端口号(厂商默认值:海康8000、大华37777、RTSP 554) public ushort Port { get; set; } /// 设备登录用户名(默认值:admin) public string Username { get; set; } = "admin"; /// 设备登录密码(默认空字符串,需根据实际设备配置) public string Password { get; set; } = string.Empty; /// 渲染句柄(可选):用于硬解码时直接绑定显示窗口,提升渲染性能 public long RenderHandle { get; set; } /// 物理通道号(IPC 通常为 1;NVR 对应接入的摄像头通道索引) public int ChannelIndex { get; set; } = 1; /// 默认码流类型(0 = 主码流(高清),1 = 子码流(低带宽)) public int StreamType { get; set; } = 0; /// 关联的主板IP public string MainboardIp { get; set; } = string.Empty; /// 关联的主板端口 public int MainboardPort { get; set; } /// Rtsp 播放路径 public string RtspPath { get; set; } = string.Empty; /// 传输协议(TCP/UDP/Multicast,默认 TCP 保证可靠性) [JsonConverter(typeof(JsonStringEnumConverter))] public TransportProtocol Transport { get; set; } = TransportProtocol.Tcp; /// 连接超时时间(毫秒,默认 5000ms = 5秒) public int ConnectionTimeoutMs { get; set; } = 5000; #endregion #region --- 2. 厂商扩展配置 (Vendor-Specific Extensions) --- /// /// 厂商扩展参数字典 /// 用途:存储无法标准化的品牌专属参数 /// 示例: /// /// { /// "RtspPath": "/h264/ch1/main/av_stream", /// "HikLoginMode": "ISAPI", /// "DaHuaStreamProtocol": "HTTP" /// } /// /// public Dictionary VendorArguments { get; set; } = new(); #endregion #region --- 3. 配置工具方法 (Configuration Utility Methods) --- /// /// 配置有效性校验:检查核心参数是否合法,非法则抛出异常 /// 作用:提前拦截无效配置,避免驱动层连接时出现未知错误 /// /// 核心参数非法时抛出 public void Validate() { if (Id <= 0) throw new ArgumentException("配置ID必须为正整数", nameof(Id)); if (string.IsNullOrWhiteSpace(IpAddress)) throw new ArgumentException("IP地址不能为空", nameof(IpAddress)); if (Port == 0) throw new ArgumentException("端口号必须为有效数值", nameof(Port)); if (Brand == DeviceBrand.Unknown) throw new ArgumentException("必须指定设备品牌", nameof(Brand)); if (ChannelIndex <= 0) throw new ArgumentException("通道号必须为正整数", nameof(ChannelIndex)); if (ConnectionTimeoutMs <= 0) throw new ArgumentException("连接超时时间必须大于0", nameof(ConnectionTimeoutMs)); } /// /// 生成设备唯一连接指纹 /// 用途:用于连接池去重、缓存键、日志标识等场景 /// 格式:{Brand}://{Username}@{IpAddress}:{Port}/{ChannelIndex} /// /// 唯一连接指纹字符串 public string GetConnectionKey() { // 使用 StringBuilder 提升拼接性能,避免频繁创建字符串 return new StringBuilder() .Append(Brand) .Append("://") .Append(Username) .Append('@') .Append(IpAddress) .Append(':') .Append(Port) .Append('/') .Append(ChannelIndex) .ToString(); } /// /// 创建配置对象的深拷贝(防止外部修改导致配置漂移) /// /// 新的配置副本 public VideoSourceConfig DeepCopy() { var copy = new VideoSourceConfig { Id = this.Id, Name = this.Name, Brand = this.Brand, IpAddress = this.IpAddress, Port = this.Port, Username = this.Username, Password = this.Password, RenderHandle = this.RenderHandle, ChannelIndex = this.ChannelIndex, MainboardIp = this.MainboardIp, MainboardPort = this.MainboardPort, RtspPath = this.RtspPath, StreamType = this.StreamType, Transport = this.Transport, ConnectionTimeoutMs = this.ConnectionTimeoutMs }; // 深拷贝扩展参数字典 foreach (var kvp in this.VendorArguments) { copy.VendorArguments.Add(kvp.Key, kvp.Value); } return copy; } #endregion }