4 Kategorien (TV/Radio x FritzBox/Online), Source-Badge, XMLTV-Jetzt fuer Online

This commit is contained in:
administrator 2026-05-11 10:27:35 +02:00
parent a129f9b98e
commit 735ab0b489
2 changed files with 70 additions and 22 deletions

View file

@ -137,15 +137,20 @@
ToolTip="Kategorien einklappen"/>
</Grid>
<StackPanel DockPanel.Dock="Top">
<Button x:Name="BtnAll" Content="📺 Alle Sender" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="all"/>
<Button x:Name="BtnTv" Content="🎬 TV" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="tv"/>
<Button x:Name="BtnRadio" Content="📡 Radio" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="radio"/>
<Button x:Name="BtnOnline" Content="🌐 Online" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="online"
ToolTip="ÖR-TV und Webradio (Internet-Streams)"/>
<Button x:Name="BtnAll" Content="📺 Alle Sender" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="all"/>
<Separator Margin="8" Background="#333"/>
<Button x:Name="BtnFav" Content="⭐ Favoriten" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="fav"/>
<Button x:Name="BtnTvFritz" Content="🎬 TV (FritzBox)" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="tv-fritz"
ToolTip="DVB-C über die FritzBox"/>
<Button x:Name="BtnTvOnline" Content="🎬 TV (Online)" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="tv-online"
ToolTip="ÖR-TV über Internet (HLS)"/>
<Button x:Name="BtnRadioFritz" Content="📡 Radio (FritzBox)" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="radio-fritz"
ToolTip="DVB-C-Radio über die FritzBox"/>
<Button x:Name="BtnRadioOnline" Content="📡 Radio (Online)" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="radio-online"
ToolTip="Webradio (ÖR-Streams)"/>
<Separator Margin="8" Background="#333"/>
<Button x:Name="BtnEpgGrid" Content="📅 Programm" Style="{StaticResource SidebarButton}" Click="BtnEpgGrid_Click"
<Button x:Name="BtnFav" Content="⭐ Favoriten" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="fav"/>
<Separator Margin="8" Background="#333"/>
<Button x:Name="BtnEpgGrid" Content="📅 Programm" Style="{StaticResource SidebarButton}" Click="BtnEpgGrid_Click"
ToolTip="Programmübersicht aller Sender"/>
</StackPanel>
@ -363,8 +368,13 @@
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock x:Name="TxtCurrentChannel"
Foreground="White" FontSize="18" FontWeight="Bold"/>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="TxtCurrentChannel"
Foreground="White" FontSize="18" FontWeight="Bold"/>
<TextBlock x:Name="TxtChannelSource"
Foreground="#888" FontSize="11" FontWeight="SemiBold"
VerticalAlignment="Center" Margin="10,0,0,0"/>
</StackPanel>
<TextBlock x:Name="TxtEpgNow"
Foreground="#DDD" FontSize="12" Margin="0,4,0,0"
TextWrapping="Wrap"/>

View file

@ -254,13 +254,15 @@ public partial class MainWindow : Window
{
IEnumerable<Channel> 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
}
}
/// <summary>Zeigt die nächsten 3 Sendungen aus dem XMLTV-EPG in TxtEpgNext.</summary>
/// <summary>
/// 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.
/// </summary>
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)