diff --git a/Wpf_AiSportsMicrospace/Views/Main.xaml.cs b/Wpf_AiSportsMicrospace/Views/Main.xaml.cs index f541293..d61718e 100644 --- a/Wpf_AiSportsMicrospace/Views/Main.xaml.cs +++ b/Wpf_AiSportsMicrospace/Views/Main.xaml.cs @@ -32,6 +32,13 @@ namespace Wpf_AiSportsMicrospace.Views public WebcamClient WebcamClient { get; private set; } private readonly ConcurrentQueue _frameQueue = new(); private readonly CancellationTokenSource _cts = new(); + private DateTime _lastFrameTime = DateTime.Now; + private const int HeartbeatTimeoutMs = 5000; // 5秒内未收到帧则视为断线 + private const int RetryIntervalMs = 3000; // 每3秒重试一次 + private const int MaxRetryCount = 5; + private bool _isReconnecting = false; + private readonly object _reconnectLock = new(); + public Main() { InitializeComponent(); @@ -51,7 +58,8 @@ namespace Wpf_AiSportsMicrospace.Views // 开始抽帧线程 StartFrameProcessing(); - + // 启动心跳检测线程 + StartHeartbeatMonitor(); // 默认显示首页 MainContent.Content = new Home(); } @@ -115,6 +123,84 @@ namespace Wpf_AiSportsMicrospace.Views public event EventHandler> HumanFrameUpdated; + private void StartHeartbeatMonitor() + { + Task.Run(async () => + { + while (!_cts.Token.IsCancellationRequested) + { + try + { + var elapsed = (DateTime.Now - _lastFrameTime).TotalMilliseconds; + if (elapsed > HeartbeatTimeoutMs && !_isReconnecting) + { + Console.WriteLine("检测到摄像头断线,准备重连..."); + await TryReconnectAsync(); + } + } + catch (Exception ex) + { + Console.WriteLine($"HeartbeatMonitor error: {ex.Message}"); + } + + await Task.Delay(HeartbeatTimeoutMs / 2, _cts.Token); + } + }, _cts.Token); + } + private async Task TryReconnectAsync() + { + lock (_reconnectLock) + { + if (_isReconnecting) + return; + _isReconnecting = true; + } + + int retryCount = 0; + bool success = false; + + while (retryCount < MaxRetryCount && !_cts.Token.IsCancellationRequested) + { + retryCount++; + Console.WriteLine($"尝试第 {retryCount} 次重连摄像头..."); + + try + { + WebcamClient?.StopExtract(); + WebcamClient = SportOperate.CreateRTSP(); + + if (WebcamClient != null) + { + WebcamClient.OnExtractFrame += frame => + { + _lastFrameTime = DateTime.Now; + _frameQueue.Enqueue(frame); + }; + WebcamClient.StartExtract(); + success = true; + Console.WriteLine("摄像头重连成功!"); + break; + } + } + catch (Exception ex) + { + Console.WriteLine($"重连失败: {ex.Message}"); + } + + await Task.Delay(RetryIntervalMs); + } + + if (!success) + { + Application.Current.Dispatcher.Invoke(() => + { + HandyControl.Controls.MessageBox.Show("摄像头连接失败,请检查网络或设备!"); + }); + } + + _isReconnecting = false; + } + public void SwitchPage(UserControl newPage, bool fromRight) { if (MainContent.Content == newPage) return;