增加摄像头中控台项目

This commit is contained in:
2025-12-30 10:53:02 +08:00
parent 471b8c50b6
commit de3adf0339
31 changed files with 2736 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
using System.Windows.Media;
namespace SHH.CameraDashboard
{
// 日志实体,用于在事件中传递详细信息
public class ApiLogEntry
{
public DateTime Time { get; set; } = DateTime.Now;
public string Method { get; set; } // GET, POST
public string Url { get; set; }
public int StatusCode { get; set; }
public long DurationMs { get; set; } // 耗时(毫秒)
public string RequestBody { get; set; } // 发送的内容
public string ResponseBody { get; set; } // 接收的内容
public string ErrorMessage { get; set; } // 异常信息
// 辅助属性:是否成功
public bool IsSuccess => StatusCode >= 200 && StatusCode < 300;
// 辅助属性:显示颜色
public Brush StatusColor => IsSuccess
? new SolidColorBrush(Color.FromRgb(78, 201, 176)) // 绿色
: new SolidColorBrush(Color.FromRgb(244, 71, 71)); // 红色
}
}

View File

@@ -0,0 +1,31 @@
namespace SHH.CameraDashboard;
public class CameraInfo
{
// --- 原始 JSON 属性 ---
public int Id { get; set; }
public string Name { get; set; }
public string IpAddress { get; set; }
public DeviceBrand Brand { get; set; }
public string Status { get; set; } // "Playing", "Disconnected" 等
public bool IsPhysicalOnline { get; set; } // 物理在线 (网络)
public bool IsOnline { get; set; } // 业务在线 (登录)
public bool IsRunning { get; set; } // 正在运行 (拉流)
public int RealFps { get; set; }
public int Width { get; set; }
public int Height { get; set; }
// --- UI 分离状态逻辑 ---
// 状态 1: 登录状态 (在线/离线)
public string OnlineStatusText => (IsPhysicalOnline && IsOnline) ? "在线" : "离线";
// 状态 2: 运行状态 (运行/停止)
public string RunningStatusText => IsRunning ? "运行中" : "已停止";
// 品牌信息
public string BrandName => Brand.ToString();
public string DisplayName => string.IsNullOrEmpty(Name) ? IpAddress : Name;
public string MediaDetail => IsRunning && Width > 0 ? $"{Width}x{Height} | {RealFps}fps" : "无信号";
}

View File

@@ -0,0 +1,63 @@
namespace SHH.CameraDashboard
{
/// <summary>
/// 视频源物理/逻辑品牌类型
/// 职责:用于工厂模式匹配具体的 IVideoSource 实现类,并定义基础通信协议栈
/// </summary>
public enum DeviceBrand
{
/// <summary>
/// 未知
/// </summary>
Unknown = 0,
/// <summary>
/// 海康威视 (HikVision)
/// 技术路径:基于海康私有 SDK (HCNetSDK.dll / PlayCtrl.dll)。
/// 特性支持全功能控制PTZ、对讲、配置、报警回传
/// </summary>
HikVision,
/// <summary>
/// 大华 (Dahua)
/// 技术路径:基于大华私有 SDK (dhnetsdk.dll / dhplay.dll)。
/// 特性:支持全功能控制,与海康私有协议不兼容。
/// </summary>
Dahua,
/// <summary>
/// USB 摄像头 / 虚拟摄像头
/// 技术路径:基于 DirectShow 或 Windows Media Foundation。
/// 特性:通常通过 OpenCV (VideoCapture) 或 DirectShowLib 直接读取本地硬件引用。
/// </summary>
Usb,
/// <summary>
/// 标准 RTSP 流媒体
/// 技术路径:基于标准 RTSP/RTP 协议 (RFC 2326)。
/// 特性:跨品牌兼容,通常使用 FFmpeg 或 GStreamer 库取流,仅支持音视频,不支持云台控制。
/// </summary>
RtspGeneral,
/// <summary>
/// 三恒自研 WebSocket 流
/// 技术路径:基于 WebSocket 传输的自定义二进制或 Base64 帧。
/// 特性:专用于 Web 或云端推送场景的私有流媒体格式。
/// </summary>
WebSocketShine,
/// <summary>
/// 本地视频文件
/// 技术路径:基于文件 IO 的离线解码。
/// 特性:常用于算法演示、回放模拟,支持 Mp4, Avi, Mkv 等容器格式。
/// </summary>
File,
/// <summary>
/// 未知/通用标准 (ONVIF)
/// 技术路径:基于标准 ONVIF WebService。
/// 特性:用于接入非主流厂商但符合 ONVIF 标准的设备,支持基础 PTZ。
/// </summary>
OnvifGeneral
}
}

View File

@@ -0,0 +1,87 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Media;
namespace SHH.CameraDashboard
{
// 1. 单个节点的数据模型
public class ServerNode : INotifyPropertyChanged
{
private string _name = "新节点"; // 默认名称
public string Name
{
get => _name;
set { _name = value; OnPropertyChanged(); }
}
private string _ip = "127.0.0.1";
public string Ip
{
get => _ip;
set
{
if (_ip != value)
{
_ip = value;
OnPropertyChanged(); // 通知界面更新
}
}
}
private int _port = 5000;
public int Port
{
get => _port;
set
{
if (_port != value)
{
_port = value;
OnPropertyChanged();
}
}
}
private string _status = "未检测";
public string Status
{
get => _status;
set
{
_status = value;
OnPropertyChanged();
OnPropertyChanged(nameof(StatusColor)); // 状态变了,颜色也要跟着变
}
}
public Brush StatusColor
{
get
{
switch (Status)
{
case "✅ 连接成功":
return new SolidColorBrush(Color.FromRgb(78, 201, 176)); // 绿色
case "❌ 状态码异常":
return new SolidColorBrush(Color.FromRgb(255, 140, 0)); // 橙色 (警告)
case "❌ 无法连接":
return new SolidColorBrush(Color.FromRgb(244, 71, 71)); // 红色 (故障)
case "⏳ 检测中...":
return new SolidColorBrush(Color.FromRgb(86, 156, 214)); // 蓝色
default:
return new SolidColorBrush(Color.FromRgb(153, 153, 153)); // 灰色
}
}
}
public void SetResult(bool success, string msg)
{
Status = msg;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}

View File

@@ -0,0 +1,60 @@

namespace SHH.CameraDashboard
{
/// <summary>
/// 视频源逻辑状态枚举
/// 描述了从配置加载到视频流稳定输出的完整生命周期
/// </summary>
public enum VideoSourceStatus
{
/// <summary>
/// 已断开/初始状态。
/// 此时资源已释放,尚未执行 Login 或 Start 操作。
/// </summary>
Disconnected,
/// <summary>
/// 正在尝试建立网络连接。
/// 此时正在进行 Socket 握手或探测设备 IP 是否可达。
/// </summary>
Connecting,
/// <summary>
/// 正在进行身份验证。
/// 连接已建立,正在提交 UserName/Password 调用 SDK 的 Login 接口。
/// </summary>
Authorizing,
/// <summary>
/// 已登录/待机。
/// 登录成功并获取到了设备元数据Metadata但尚未启动预览RealPlay
/// 适用于“仅管理,不看画面”的场景。
/// </summary>
Connected,
/// <summary>
/// 正常取流播放中
/// </summary>
Playing,
/// <summary>
/// 正在取流/正常运行中。
/// 预览句柄已开启,取流回调函数正在持续接收数据帧并进行解码。
/// </summary>
Streaming,
/// <summary>
/// 自动重连中。
/// 检测到网络抖动或心跳丢失SDK 正在尝试内部恢复,此时视频流可能处于停滞状态。
/// </summary>
Reconnecting,
/// <summary>
/// 故障/异常状态。
/// 发生了不可恢复的错误(如密码错误、最大连接数限制、设备强制离线)。
/// 进入此状态通常需要人工干预或调用 Stop 后重新 Start。
/// </summary>
Faulted
}
}