97 lines
3.2 KiB
C#
97 lines
3.2 KiB
C#
using System.Windows;
|
|
using System.Windows.Media.Imaging;
|
|
using SHH.Contracts; // ★★★ 引用契约库 (VideoPayload) ★★★
|
|
|
|
namespace SHH.CameraDashboard;
|
|
|
|
public class VideoTileViewModel : ViewModelBase
|
|
{
|
|
private readonly string _boundCameraId;
|
|
|
|
// --- 属性定义 (保持不变) ---
|
|
private string _cameraName;
|
|
public string CameraName
|
|
{
|
|
get => _cameraName;
|
|
set { _cameraName = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
private string _statusInfo;
|
|
public string StatusInfo
|
|
{
|
|
get => _statusInfo;
|
|
set { _statusInfo = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
private BitmapImage _videoSource;
|
|
public BitmapImage VideoSource
|
|
{
|
|
get => _videoSource;
|
|
set { _videoSource = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
// --- 构造函数 ---
|
|
public VideoTileViewModel(string cameraId, string name)
|
|
{
|
|
_boundCameraId = cameraId;
|
|
CameraName = name;
|
|
StatusInfo = "等待信号...";
|
|
|
|
// ★★★ 变更 1: 订阅新的 OnPayloadReceived 事件 ★★★
|
|
// 旧的 OnFrameReceived(string, byte[]) 已经无法满足需求
|
|
StreamReceiverService.Instance.OnPayloadReceived += OnPayloadReceived;
|
|
}
|
|
|
|
// --- 事件回调 (后台线程) ---
|
|
// ★★★ 变更 2: 参数变为 VideoPayload 实体对象 ★★★
|
|
private void OnPayloadReceived(VideoPayload payload)
|
|
{
|
|
// 1. 过滤:校验 Payload 中的 CameraId
|
|
if (payload.CameraId != _boundCameraId) return;
|
|
|
|
// 2. ★★★ 智能选图策略 ★★★
|
|
// 优先显示 AI 处理后的图 (TargetImageBytes)
|
|
// 如果没有处理图,则降级显示原始图 (OriginalImageBytes)
|
|
byte[] dataToShow = null;
|
|
|
|
if (payload.HasTargetImage && payload.TargetImageBytes != null)
|
|
{
|
|
dataToShow = payload.TargetImageBytes;
|
|
}
|
|
else if (payload.HasOriginalImage && payload.OriginalImageBytes != null)
|
|
{
|
|
dataToShow = payload.OriginalImageBytes;
|
|
}
|
|
|
|
// 如果两张图都没有,直接返回
|
|
if (dataToShow == null || dataToShow.Length == 0) return;
|
|
|
|
// 3. 解码图片 (耗时操作在后台完成)
|
|
var bitmap = BitmapHelper.ToBitmapImage(dataToShow);
|
|
if (bitmap == null) return;
|
|
|
|
// 4. ★★★ 计算端到端延迟 ★★★
|
|
// 当前时间(接收端) - 采集时间(发送端) = 真实的网络+处理延迟
|
|
long latency = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - payload.CaptureTimestamp;
|
|
|
|
// 5. UI 更新
|
|
Application.Current.Dispatcher.InvokeAsync(() =>
|
|
{
|
|
VideoSource = bitmap;
|
|
|
|
// 显示更丰富的信息:延迟毫秒数、数据量、当前时间
|
|
// 工业监控中,"延迟(ms)" 是比 "当前时间" 更重要的指标
|
|
StatusInfo = $"延迟: {latency}ms | {dataToShow.Length / 1024} KB | {DateTime.Now:HH:mm:ss}";
|
|
});
|
|
}
|
|
|
|
// --- 资源清理 ---
|
|
public void Unload()
|
|
{
|
|
// ★★★ 变更 3: 取消订阅新的事件 ★★★
|
|
StreamReceiverService.Instance.OnPayloadReceived -= OnPayloadReceived;
|
|
|
|
// 清空图片引用,帮助 GC 回收内存
|
|
VideoSource = null;
|
|
}
|
|
} |