From 75526a7d437e37783da709642d2571f845fd5299 Mon Sep 17 00:00:00 2001 From: dimedtec Date: Thu, 21 May 2026 23:01:21 +0200 Subject: [PATCH] Aufnahme: sout-duplicate - Livebild laeuft weiter waehrend Aufnahme --- MainWindow.xaml.cs | 59 ++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index bb851d4..56f58be 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -43,8 +43,7 @@ public partial class MainWindow : Window private bool _webViewReady = false; // Aufnahme - private MediaPlayer? _recordPlayer; - private Media? _recordMedia; + private string? _recordingFilePath; private bool _isRecording = false; // WndProc-Hook für globale Tastatureingaben (auch wenn WebView2 Fokus hat) @@ -709,33 +708,45 @@ public partial class MainWindow : Window "HomeStream", MessageBoxButton.OK, MessageBoxImage.Information); return; } + if (_player == null || _currentMedia == null) return; try { - // Zieldatei: Sendername + Zeitstempel.ts var dir = _settings.RecordingPath; Directory.CreateDirectory(dir); var safeName = string.Join("_", _currentChannel.Name.Split(Path.GetInvalidFileNameChars())); var fileName = $"{safeName}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.ts"; var filePath = Path.Combine(dir, fileName); - // Separater MediaPlayer nur für Aufnahme (kein Video-Output) - // Stream wird direkt von der Quelle aufgenommen, nicht vom laufenden Player - _recordMedia = new Media(_libVLC!, new Uri(_currentChannel.Url), - $":sout=#file{{dst={filePath}}}", - ":sout-keep", - ":network-caching=300"); + // Laufenden Player stoppen, neue Media mit sout-duplicate starten + // #duplicate: gleichzeitig Display (Abspielen) UND File (Aufnahme) + _player.Stop(); - _recordPlayer = new MediaPlayer(_libVLC!); - _recordPlayer.Media = _recordMedia; - _recordPlayer.Play(); + var sout = $":sout=#duplicate{{dst=display,dst=file{{dst={filePath}}}}}"; + var media = new Media(_libVLC!, new Uri(_currentChannel.Url), + sout, + ":sout-keep", + "--network-caching=1000", + "--no-video-title-show", + "--no-osd", + "--rtsp-tcp"); + + media.MetaChanged += OnMediaMetaChanged; + + var oldMedia = _currentMedia; + _currentMedia = media; + _player.Media = media; + _player.Play(); + + try { oldMedia?.Dispose(); } catch { } _isRecording = true; + _recordingFilePath = filePath; BtnRecord.Foreground = new System.Windows.Media.SolidColorBrush( System.Windows.Media.Colors.Red); BtnRecord.ToolTip = $"Aufnahme läuft: {fileName} — Klicken zum Stoppen"; - TxtChannelSource.Text = (_currentChannel.Source == ChannelSource.Online ? "● Online" : "● FritzBox") - + " 🔴 REC"; + TxtChannelSource.Text = (_currentChannel.Source == ChannelSource.Online + ? "● Online" : "● FritzBox") + " 🔴 REC"; } catch (Exception ex) { @@ -746,22 +757,30 @@ public partial class MainWindow : Window private void StopRecording() { + if (!_isRecording) return; try { - _recordPlayer?.Stop(); - _recordPlayer?.Dispose(); - _recordMedia?.Dispose(); + // Player mit normalem Stream neu starten (ohne sout) + if (_currentChannel != null && _player != null && _libVLC != null) + { + _player.Stop(); + var media = new Media(_libVLC, new Uri(_currentChannel.Url)); + media.MetaChanged += OnMediaMetaChanged; + var oldMedia = _currentMedia; + _currentMedia = media; + _player.Media = media; + _player.Play(); + try { oldMedia?.Dispose(); } catch { } + } } catch { } finally { - _recordPlayer = null; - _recordMedia = null; _isRecording = false; + _recordingFilePath = null; BtnRecord.Foreground = new System.Windows.Media.SolidColorBrush( System.Windows.Media.Color.FromRgb(0x88, 0x88, 0x88)); BtnRecord.ToolTip = "Aufnahme starten"; - // Source-Badge wiederherstellen if (_currentChannel != null) { TxtChannelSource.Text = _currentChannel.Source == ChannelSource.Online