4 Kategorien (TV/Radio x FritzBox/Online), Source-Badge, XMLTV-Jetzt fuer Online
This commit is contained in:
parent
a129f9b98e
commit
735ab0b489
2 changed files with 70 additions and 22 deletions
|
|
@ -138,10 +138,15 @@
|
||||||
</Grid>
|
</Grid>
|
||||||
<StackPanel DockPanel.Dock="Top">
|
<StackPanel DockPanel.Dock="Top">
|
||||||
<Button x:Name="BtnAll" Content="📺 Alle Sender" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="all"/>
|
<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"/>
|
<Separator Margin="8" Background="#333"/>
|
||||||
<Button x:Name="BtnRadio" Content="📡 Radio" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="radio"/>
|
<Button x:Name="BtnTvFritz" Content="🎬 TV (FritzBox)" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="tv-fritz"
|
||||||
<Button x:Name="BtnOnline" Content="🌐 Online" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="online"
|
ToolTip="DVB-C über die FritzBox"/>
|
||||||
ToolTip="ÖR-TV und Webradio (Internet-Streams)"/>
|
<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"/>
|
<Separator Margin="8" Background="#333"/>
|
||||||
<Button x:Name="BtnFav" Content="⭐ Favoriten" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="fav"/>
|
<Button x:Name="BtnFav" Content="⭐ Favoriten" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="fav"/>
|
||||||
<Separator Margin="8" Background="#333"/>
|
<Separator Margin="8" Background="#333"/>
|
||||||
|
|
@ -363,8 +368,13 @@
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<StackPanel Grid.Column="0">
|
<StackPanel Grid.Column="0">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock x:Name="TxtCurrentChannel"
|
<TextBlock x:Name="TxtCurrentChannel"
|
||||||
Foreground="White" FontSize="18" FontWeight="Bold"/>
|
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"
|
<TextBlock x:Name="TxtEpgNow"
|
||||||
Foreground="#DDD" FontSize="12" Margin="0,4,0,0"
|
Foreground="#DDD" FontSize="12" Margin="0,4,0,0"
|
||||||
TextWrapping="Wrap"/>
|
TextWrapping="Wrap"/>
|
||||||
|
|
|
||||||
|
|
@ -254,13 +254,15 @@ public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
IEnumerable<Channel> q = _allChannels;
|
IEnumerable<Channel> q = _allChannels;
|
||||||
|
|
||||||
|
// Kategorie-Filter
|
||||||
q = _currentCategory switch
|
q = _currentCategory switch
|
||||||
{
|
{
|
||||||
"tv" => MergeHdSd(q.Where(c => c.Kind != ChannelKind.Radio)),
|
"tv-fritz" => MergeHdSd(q.Where(c => c.Kind != ChannelKind.Radio && c.Source == ChannelSource.FritzBox)),
|
||||||
"radio" => q.Where(c => c.Kind == ChannelKind.Radio),
|
"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)),
|
"fav" => MergeHdSd(q.Where(c => c.IsFavorite)),
|
||||||
"online" => MergeHdSd(q.Where(c => c.Source == ChannelSource.Online)),
|
_ => MergeHdSd(q) // "all"
|
||||||
_ => MergeHdSd(q)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(_searchTerm))
|
if (!string.IsNullOrEmpty(_searchTerm))
|
||||||
|
|
@ -337,6 +339,11 @@ public partial class MainWindow : Window
|
||||||
_player.Play();
|
_player.Play();
|
||||||
|
|
||||||
TxtCurrentChannel.Text = ch.Name;
|
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…";
|
TxtEpgNow.Text = "EPG wird geladen…";
|
||||||
TxtEpgNext.Text = "";
|
TxtEpgNext.Text = "";
|
||||||
TxtNoChannel.Visibility = Visibility.Collapsed;
|
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)
|
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
|
// EPG noch nicht geladen? Hintergrund-Load anstossen, kommt später wieder
|
||||||
if (!_epgService.IsCurrent)
|
if (!_epgService.IsCurrent)
|
||||||
|
|
@ -369,15 +381,33 @@ public partial class MainWindow : Window
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var events = _epgService.GetEvents(ch.Name, hoursAhead: 12)
|
var allEvents = _epgService.GetEvents(ch.Name, hoursAhead: 12);
|
||||||
.Where(e => e.StartTime > DateTime.Now)
|
|
||||||
.Take(3)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
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(" · ",
|
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)
|
private void EpgTimer_Tick(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (_currentMedia == null) { _epgTimer.Stop(); return; }
|
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 (_epgTimer.Tag is (DateTime started, Channel ch))
|
||||||
{
|
{
|
||||||
if ((DateTime.Now - started).TotalSeconds > 30)
|
if ((DateTime.Now - started).TotalSeconds > 30)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue