具备界面基础功能

This commit is contained in:
2026-01-01 22:40:32 +08:00
parent 0c86b4dad3
commit d039559402
81 changed files with 8333 additions and 1905 deletions

View File

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

View File

@@ -326,6 +326,64 @@ public class CamerasController : ControllerBase
});
}
[HttpGet("{id}/subscriptions")]
public IActionResult GetSubscriptions(long id)
{
// 1. 检查设备是否存在
var camera = _manager.GetDevice(id);
if (camera == null)
{
return NotFound(new { error = $"Camera {id} not found." });
}
// 2. 从设备的 FrameController 获取当前活跃的订阅
// 注意FrameController.GetCurrentRequirements() 返回的是 List<FrameRequirement>
// 它可以直接被序列化为 JSON
var subs = camera.Controller.GetCurrentRequirements();
return Ok(subs);
}
// =============================================================
// 6. 新增:彻底删除/注销订阅 (RESTful DELETE)
// URL: DELETE /api/cameras/{id}/subscriptions/{appId}
// =============================================================
[HttpDelete("{id}/subscriptions/{appId}")]
public IActionResult RemoveSubscription(long id, string appId)
{
// 1. 检查设备是否存在
var device = _manager.GetDevice(id);
if (device == null)
{
return NotFound(new { error = $"Camera {id} not found." });
}
// 2. 获取流控控制器
var controller = device.Controller;
if (controller == null)
{
// 如果设备本身没有控制器(比如离线或不支持),也算删除成功
return Ok(new { success = true, message = "Device has no controller, nothing to remove." });
}
// 3. 执行注销逻辑 (核心)
// 从 FrameController 的分发列表中移除
controller.Unregister(appId);
// 4. 清理显示资源 (重要!)
// 参考您 UpdateSubscription 中的逻辑,必须同时停止 DisplayManager否则窗口关不掉
_displayManager.StopDisplay(appId);
// 5. 记录审计日志
device.AddAuditLog($"用户指令:彻底注销订阅 [{appId}]");
return Ok(new
{
success = true,
message = $"Subscription {appId} has been removed and display stopped."
});
}
// 1. 获取单个设备详情(用于编辑回填)
[HttpGet("{id}")]
public IActionResult GetDevice(int id)