Files
Ayay/SHH.CameraDashboard/Services/WebApis/CameraReps/CameraRepositoryImgSubscript.cs
2026-01-01 22:40:32 +08:00

233 lines
7.9 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 System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace SHH.CameraDashboard
{
public partial class CameraRepository
{
// 文件: Services\WebApis\CameraReps\CameraRepository.cs
public async Task<bool> UpdateSubscriptionAsync(long cameraId, SubscriptionDto dto)
{
var serviceNode = AppGlobal.UseServiceNode;
if (serviceNode == null) return false;
// URL: POST /api/Cameras/{id}/subscriptions
string requestUrl = $"http://{serviceNode.ServiceNodeIp}:{serviceNode.ServiceNodePort}{WebApiRoutes.Cameras.Root}/{cameraId}/subscriptions";
try
{
string jsonBody = JsonHelper.Serialize(dto);
// 发送 POST 请求
await WebApiService.Instance.PostAsync(requestUrl, jsonBody, "更新订阅配置");
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"更新订阅失败: {ex.Message}");
return false;
}
}
/// <summary>
/// [新增] 获取订阅列表
/// </summary>
public async Task<List<SubscriptionDto>> GetSubscriptionsAsync(long cameraId)
{
var serviceNode = AppGlobal.UseServiceNode;
if (serviceNode == null) return new List<SubscriptionDto>();
// URL: GET /api/Cameras/{id}/subscriptions
string requestUrl = $"http://{serviceNode.ServiceNodeIp}:{serviceNode.ServiceNodePort}{WebApiRoutes.Cameras.Root}/{cameraId}/subscriptions";
try
{
string json = await WebApiService.Instance.GetAsync(requestUrl, "获取订阅列表");
// 如果返回空或null返回空列表
if (string.IsNullOrEmpty(json)) return new List<SubscriptionDto>();
var list = JsonHelper.Deserialize<List<SubscriptionDto>>(json);
return list ?? new List<SubscriptionDto>();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"获取订阅列表失败: {ex.Message}");
return new List<SubscriptionDto>();
}
}
/// <summary>
/// [修改] 删除/注销订阅
/// 改为标准的 DELETE 请求
/// </summary>
public async Task<bool> DeleteSubscriptionAsync(long cameraId, string appId)
{
if (string.IsNullOrWhiteSpace(appId)) return false;
var serviceNode = AppGlobal.UseServiceNode;
if (serviceNode == null) return false;
// 拼接 URL: DELETE /api/Cameras/1001/subscriptions/Client_01
// 注意AppId 如果包含特殊字符,建议 UrlEncode但一般 ID 都是字母数字
string requestUrl = $"http://{serviceNode.ServiceNodeIp}:{serviceNode.ServiceNodePort}{WebApiRoutes.Cameras.Root}/{cameraId}/subscriptions/{appId}";
try
{
// 调用刚刚在 WebApiService 里加的 DeleteAsync
await WebApiService.Instance.DeleteAsync(requestUrl, "注销订阅");
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"注销订阅失败: {ex.Message}");
return false;
}
}
}
/// <summary>
/// 视频流订阅配置请求对象
/// 用于定义第三方应用或内部模块对指定相机流的消费需求
/// </summary>
public class SubscriptionDto
{
/// <summary>
/// 进程唯一标识 (如 "AI_Process_01"、"Main_Display_02")
/// </summary>
public string AppId { get; set; } = string.Empty;
/// <summary>
/// 订阅业务类型。
/// 决定了后端流控引擎后续的资源分配(如是否开启录像机或渲染器)。
/// </summary>
public int Type { get; set; }
/// <summary>
/// 显示帧率需求 (单位: fps)
/// <para>不需要显示则设为 0控制器会自动注销该类型需求</para>
/// </summary>
public int DisplayFps
{
get => TargetFps;
set => TargetFps = value;
}
public int TargetFps { get; set; }
/// <summary>
/// [新增] 实际显示/分发帧率
/// JSON: "realFps"
/// </summary>
[JsonPropertyName("realFps")]
public double RealFps { get; set; }
/// <summary>
/// 备注信息。
/// 用于记录订阅的用途、申请人或关联业务系统。
/// </summary>
public string Memo { get; set; }
= string.Empty;
/// <summary>
/// 窗口句柄HWND
/// 仅在 Type 为 HandleDisplay 时必填。格式通常为十六进制或十进制字符串。
/// </summary>
public string Handle { get; set; }
= string.Empty;
/// <summary>
/// 录像持续时长(分钟,范围 1-60
/// 仅在 Type 为 LocalRecord 时有效。
/// </summary>
public int RecordDuration { get; set; }
/// <summary>
/// 录像文件存放绝对路径。
/// 仅在 Type 为 LocalRecord 时有效例如C:\Recordings\Room01。
/// </summary>
public string SavePath { get; set; }
= string.Empty;
/// <summary>
/// 通讯方式协议。
/// 仅在 Type 为 NetworkTrans 或 WebPush 时有效,默认为 Network。
/// </summary>
public int Protocol { get; set; }
/// <summary>
/// 目标接收端 IP 地址。
/// 仅在 Type 为 NetworkTrans 或 WebPush 且 Protocol 为 Network 时必填。
/// </summary>
public string TargetIp { get; set; }
= string.Empty;
/// <summary>
/// 目标接收端端口号。
/// 仅在 Type 为 NetworkTrans 或 WebPush 时必填。
/// </summary>
public int TargetPort { get; set; }
}
/// <summary>
/// 订阅业务类型枚举
/// 描述视频流的最终去向和业务用途,用于帧分发策略的路由决策
/// </summary>
public enum SubscriptionType
{
/// <summary>
/// 本地窗口渲染
/// <para>直接在服务器端显示器绘制(如 OpenCV Window、WinForm 控件)</para>
/// </summary>
[Description("本地窗口显示")]
LocalWindow = 0,
/// <summary>
/// 本地录像存储
/// <para>写入磁盘文件(如 MP4/AVI 格式,支持定时切割、循环覆盖)</para>
/// </summary>
[Description("本地录像存储")]
LocalRecord = 1,
/// <summary>
/// 句柄绑定显示
/// <para>渲染到指定 HWND 窗口句柄(如 SDK 硬件解码渲染到客户端控件)</para>
/// </summary>
[Description("句柄绑定显示")]
HandleDisplay = 2,
/// <summary>
/// 自定义网络传输
/// <para>通过私有协议转发给第三方系统(如工控机、告警服务器)</para>
/// </summary>
[Description("自定义网络传输")]
NetworkTrans = 3,
/// <summary>
/// 网页端推流
/// <para>转码为 Web 标准协议(如 WebRTC、HLS、RTMP供浏览器播放</para>
/// </summary>
[Description("网页端推流")]
WebPush = 4
}
/// <summary>
/// 网络传输协议类型
/// </summary>
public enum TransportProtocol
{
/// <summary> 可靠传输 (默认) </summary>
Tcp = 0,
/// <summary> 快速传输 (可能丢包/花屏) </summary>
Udp = 1,
/// <summary> 组播 (节省带宽) </summary>
Multicast = 2,
/// <summary> 内存交互 </summary>
Memory = 99,
}
}