diff --git a/MainWindow.xaml b/MainWindow.xaml
index 301c323..5e76b52 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -137,15 +137,20 @@
ToolTip="Kategorien einklappen"/>
-
-
-
-
+
-
+
+
+
+
-
+
+
@@ -363,8 +368,13 @@
-
+
+
+
+
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 9536223..03fa53b 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -254,13 +254,15 @@ public partial class MainWindow : Window
{
IEnumerable q = _allChannels;
+ // Kategorie-Filter
q = _currentCategory switch
{
- "tv" => MergeHdSd(q.Where(c => c.Kind != ChannelKind.Radio)),
- "radio" => q.Where(c => c.Kind == ChannelKind.Radio),
- "fav" => MergeHdSd(q.Where(c => c.IsFavorite)),
- "online" => MergeHdSd(q.Where(c => c.Source == ChannelSource.Online)),
- _ => MergeHdSd(q)
+ "tv-fritz" => MergeHdSd(q.Where(c => c.Kind != ChannelKind.Radio && c.Source == ChannelSource.FritzBox)),
+ "tv-online" => MergeHdSd(q.Where(c => c.Kind != ChannelKind.Radio && c.Source == ChannelSource.Online)),
+ "radio-fritz" => q.Where(c => c.Kind == ChannelKind.Radio && c.Source == ChannelSource.FritzBox),
+ "radio-online" => q.Where(c => c.Kind == ChannelKind.Radio && c.Source == ChannelSource.Online),
+ "fav" => MergeHdSd(q.Where(c => c.IsFavorite)),
+ _ => MergeHdSd(q) // "all"
};
if (!string.IsNullOrEmpty(_searchTerm))
@@ -337,6 +339,11 @@ public partial class MainWindow : Window
_player.Play();
TxtCurrentChannel.Text = ch.Name;
+ // Quelle-Badge anzeigen (FritzBox/Online)
+ TxtChannelSource.Text = ch.Source == ChannelSource.Online ? "● Online" : "● FritzBox";
+ TxtChannelSource.Foreground = ch.Source == ChannelSource.Online
+ ? new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0x00, 0x78, 0xD4)) // Blau für Online
+ : new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0x66, 0xBB, 0x6A)); // Grün für FritzBox
TxtEpgNow.Text = "EPG wird geladen…";
TxtEpgNext.Text = "";
TxtNoChannel.Visibility = Visibility.Collapsed;
@@ -357,10 +364,15 @@ public partial class MainWindow : Window
}
}
- /// Zeigt die nächsten 3 Sendungen aus dem XMLTV-EPG in TxtEpgNext.
+ ///
+ /// Füllt Jetzt+Danach aus dem XMLTV-EPG.
+ ///
+ /// Online-Streams (HLS) haben kein EIT, daher müssen wir hier auch das AKTUELLE
+ /// Programm aus XMLTV setzen. FritzBox-TV nutzt primär EIT, XMLTV nur als "Danach"-Vorschau.
+ ///
private void UpdateNextFromEpgService(Channel ch)
{
- if (ch.Kind == ChannelKind.Radio) return; // Radio: kein EPG
+ if (ch.Kind == ChannelKind.Radio) return; // Radio: kein TV-EPG
// EPG noch nicht geladen? Hintergrund-Load anstossen, kommt später wieder
if (!_epgService.IsCurrent)
@@ -369,15 +381,33 @@ public partial class MainWindow : Window
return;
}
- var events = _epgService.GetEvents(ch.Name, hoursAhead: 12)
- .Where(e => e.StartTime > DateTime.Now)
- .Take(3)
- .ToList();
+ var allEvents = _epgService.GetEvents(ch.Name, hoursAhead: 12);
- if (events.Count > 0)
+ // Aktuelle Sendung aus XMLTV: nur für Online-TV setzen (FritzBox: EIT überschreibt)
+ if (ch.Source == ChannelSource.Online)
+ {
+ var current = allEvents.FirstOrDefault(e => e.IsCurrent);
+ if (current != null)
+ {
+ var jetzt = current.Title;
+ if (!string.IsNullOrWhiteSpace(current.Description))
+ jetzt += $" · {current.Description.Trim()}";
+ TxtEpgNow.Text = $"▶ Jetzt: {jetzt}";
+ _epgTimer.Stop(); // keine EIT-Updates erwarten
+ }
+ else if (TxtEpgNow.Text == "EPG wird geladen\u2026")
+ {
+ TxtEpgNow.Text = "(kein EPG verf\u00fcgbar)";
+ _epgTimer.Stop();
+ }
+ }
+
+ // Danach-Liste (gleich für beide Quellen)
+ var next = allEvents.Where(e => e.StartTime > DateTime.Now).Take(3).ToList();
+ if (next.Count > 0)
{
TxtEpgNext.Text = string.Join(" · ",
- events.Select(e => $"{e.StartTime:HH:mm} {e.Title}"));
+ next.Select(e => $"{e.StartTime:HH:mm} {e.Title}"));
}
}
@@ -452,6 +482,14 @@ public partial class MainWindow : Window
private void EpgTimer_Tick(object? sender, EventArgs e)
{
if (_currentMedia == null) { _epgTimer.Stop(); return; }
+
+ // Online-Streams haben kein EIT — EpgService liefert Daten, EIT-Polling unnötig
+ if (_currentChannel?.Source == ChannelSource.Online)
+ {
+ _epgTimer.Stop();
+ return;
+ }
+
if (_epgTimer.Tag is (DateTime started, Channel ch))
{
if ((DateTime.Now - started).TotalSeconds > 30)