more design

This commit is contained in:
Vova
2024-01-21 17:39:07 +02:00
parent e36554eeab
commit 7d00619d14
9 changed files with 271 additions and 20 deletions
+98
View File
@@ -1,11 +1,109 @@
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
using System.Xml;
namespace TV_Player
{
public class ProgramInfo : ObservableViewModelBase
{
private string _title;
private int _durationValue;
public string Title { get => _title; set => SetProperty(ref _title, value); }
public DateTime StartTime { get; set; }
public DateTime StopTime { get; set; }
public int DurationValue { get => _durationValue; set => SetProperty(ref _durationValue , value); }
}
public class ProgramGuide
{
public string Id { get; set; }
public string DisplayName { get; set; }
public List<ProgramInfo> Programs { get; set; } = new List<ProgramInfo>();
}
public static class M3UParser
{
public static async Task<List<ProgramGuide>> DownloadGuideFromWebAsync(string url)
{
List<ProgramGuide> epgChannels = new List<ProgramGuide>(); ;
using (var client = new HttpClient())
using (var request = new HttpRequestMessage())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/text"));
request.Method = HttpMethod.Get;
request.RequestUri = new Uri(url);
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
epgChannels = ParseEpg(responseBody);
}
return epgChannels;
}
private static List<ProgramGuide> ParseEpg(string epgData)
{
List<ProgramGuide> epgChannels = new List<ProgramGuide>();
using (XmlReader reader = XmlReader.Create(new System.IO.StringReader(epgData)))
{
ProgramGuide currentChannel = null;
XmlDocument doc = new XmlDocument();
doc.LoadXml(epgData);
XmlNodeList channelNodes = doc.SelectNodes("//channel");
foreach (XmlNode channelNode in channelNodes)
{
ProgramGuide channel = new ProgramGuide();
channel.Id = channelNode.Attributes["id"].Value;
channel.DisplayName = channelNode.SelectSingleNode("display-name").InnerText;
XmlNodeList programNodes = doc.SelectNodes($"//programme[@channel='{channel.Id}']");
foreach (XmlNode programNode in programNodes)
{
ProgramInfo program = new ProgramInfo();
program.Title = programNode.SelectSingleNode("title").InnerText;
program.StartTime = DateTime.ParseExact(programNode.Attributes["start"].Value, "yyyyMMddHHmmss zzz", null);
program.StopTime = DateTime.ParseExact(programNode.Attributes["stop"].Value, "yyyyMMddHHmmss zzz", null);
channel.Programs.Add(program);
}
epgChannels.Add(channel);
}
//while (reader.Read())
//{
// if (reader.NodeType == XmlNodeType.Element)
// {
// if (reader.Name == "channel")
// {
// currentChannel = new ProgramGuide();
// currentChannel.Id = reader.GetAttribute("id");
// currentChannel.DisplayName = reader.ReadElementContentAsString();
// epgChannels.Add(currentChannel);
// }
// else if (reader.Name == "programme" && currentChannel != null)
// {
// ProgramInfo program = new ProgramInfo();
// program.Title = reader.ReadElementContentAsString();
// program.StartTime = DateTime.ParseExact(reader.GetAttribute("start"), "yyyyMMddHHmmss zzz", null);
// program.StopTime = DateTime.ParseExact(reader.GetAttribute("stop"), "yyyyMMddHHmmss zzz", null);
// currentChannel.Programs.Add(program);
// }
// }
//}
}
return epgChannels;
}
public static async Task<List<M3UInfo>> DownloadM3UFromWebAsync(string url)
{
List<M3UInfo> playlistItems = new List<M3UInfo>();
+40 -2
View File
@@ -1,4 +1,5 @@
using CommunityToolkit.Mvvm.Input;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@@ -14,7 +15,8 @@ namespace TV_Player
}
private bool _isTopPanelVisible;
public bool IsTopPanelVisible{
public bool IsTopPanelVisible
{
get => _isTopPanelVisible;
set => SetProperty(ref _isTopPanelVisible, value);
}
@@ -26,15 +28,51 @@ namespace TV_Player
set => SetProperty(ref _topPaneTitle, value);
}
private WindowState _currentWindowState;
public WindowState CurrentWindowState
{
get => _currentWindowState;
set => SetProperty(ref _currentWindowState, value);
}
private WindowStyle _currentWindowStyle;
public WindowStyle CurrentWindowStyle
{
get => _currentWindowStyle;
set => SetProperty(ref _currentWindowStyle, value);
}
public ICommand FullscreenCommand { get; }
public Action ButtonBackAction { get; set; }
public ICommand BackCommand { get; }
public MainViewModel()
{
{
BackCommand = new RelayCommand(OnButtonBackClick);
FullscreenCommand = new RelayCommand(OnFullSctreenButtonClick);
CurrentWindowStyle = WindowStyle.SingleBorderWindow;
}
private void OnFullSctreenButtonClick()
{
if (CurrentWindowStyle == WindowStyle.SingleBorderWindow)
{
CurrentWindowStyle = WindowStyle.None;
CurrentWindowState = WindowState.Maximized;
}
else
{
CurrentWindowStyle = WindowStyle.SingleBorderWindow;
CurrentWindowState = WindowState.Normal;
}
}
private void OnButtonBackClick()
{
ButtonBackAction?.Invoke();
}
}
+73 -4
View File
@@ -1,14 +1,13 @@
using CommunityToolkit.Mvvm.Input;
using System.Reactive.Linq;
using System.Windows.Input;
using TV_Player.ViewModels;
namespace TV_Player
{
public class PlayerViewModel: ObservableViewModelBase
public class PlayerViewModel : ObservableViewModelBase, IDisposable
{
private M3UInfo _currentProgram;
public M3UInfo SelectedProgram
{
@@ -23,17 +22,82 @@ namespace TV_Player
set => SetProperty(ref _topPaneTitle, value);
}
private int _durationValue;
public int DurationValue
{
get => _durationValue;
set => SetProperty(ref _durationValue, value);
}
private string _programGuide;
public string ProgramGuideText
{
get => _programGuide;
set => SetProperty(ref _programGuide, value);
}
private string _startProgram;
public string StartProgram
{
get => _startProgram;
set => SetProperty(ref _startProgram, value);
}
private string _endProgram;
public string EndProgram
{
get => _endProgram;
set => SetProperty(ref _endProgram, value);
}
public M3UInfo SelectedItem { get; set; }
public ICommand BackCommand { get; }
private ProgramGuide _currentGuide;
private ProgramInfo _currentProgramInfo;
private IDisposable _programGuideDisposable;
private IDisposable _timer;
public PlayerViewModel(M3UInfo selectedProgram)
{
_currentProgram = selectedProgram;
BackCommand = new RelayCommand(OnButtonBackClick);
TVPlayerViewModel.Instance.TopPanelVisible(false, selectedProgram.Name);
TopPanelTitle = selectedProgram.Name;
_programGuideDisposable = ProgramsData.Instance.ProgramGuideInfo.Subscribe(x =>
{
try
{
_currentGuide = x.FirstOrDefault(p => p.Id == selectedProgram.TvgID);
UpdateScreenInfo();
_timer = Observable.Interval(TimeSpan.FromMinutes(1)).Subscribe(x =>
{
UpdateScreenInfo();
});
}
catch { }
});
}
private void UpdateScreenInfo()
{
_currentProgramInfo = _currentGuide.Programs.FirstOrDefault(d => d.StartTime <= DateTime.Now && d.StopTime >= DateTime.Now);
if (_currentProgramInfo.Title != ProgramGuideText)
{
ProgramGuideText = _currentProgramInfo.Title;
StartProgram = _currentProgramInfo.StartTime.ToShortTimeString();
EndProgram = _currentProgramInfo.StopTime.ToShortTimeString();
}
var programMinutes = (_currentProgramInfo.StopTime - _currentProgramInfo.StartTime).TotalMinutes;
DurationValue = (int)((DateTime.Now - _currentProgramInfo.StartTime).TotalMinutes / programMinutes * 100);
}
private void OnButtonBackClick()
{
var groupInfo = new GroupInfo() { Name = _currentProgram.GroupTitle, Count = 0 };
@@ -43,5 +107,10 @@ namespace TV_Player
TVPlayerViewModel.Instance.SetPageContext(conrtrol, programListViewModel);
}
public void Dispose()
{
_programGuideDisposable.Dispose();
_timer.Dispose();
}
}
}
+12 -2
View File
@@ -16,14 +16,17 @@ namespace TV_Player
private readonly ReplaySubject<List<M3UInfo>> programsSubject = new ReplaySubject<List<M3UInfo>>();
private readonly ReplaySubject<List<GroupInfo>> groupsSubject = new ReplaySubject<List<GroupInfo>>();
private readonly ReplaySubject<List<ProgramGuide>> programGuideSubject = new ReplaySubject<List<ProgramGuide>>();
public IObservable<List<M3UInfo>> AllPrograms => programsSubject;
public IObservable<List<GroupInfo>> GroupsInformation => groupsSubject;
public IObservable<List<ProgramGuide>> ProgramGuideInfo => programGuideSubject;
private ProgramsData()
{
_=Initialize();
Task.Run(() => GetPrograms());
Task.Run(() => GetProgramGuide());
}
private async Task Initialize()
private async Task GetPrograms()
{
string m3uLink = "http://pl.da-tv.vip/a71e77fa/835b3216/tv.m3u";
var programs = await M3UParser.DownloadM3UFromWebAsync(m3uLink);
@@ -35,5 +38,12 @@ namespace TV_Player
.ToList();
groupsSubject.OnNext(groupping);
}
private async Task GetProgramGuide()
{
string guideLink = "http://epg.da-tv.vip/107-light.xml";
var programGuide = await M3UParser.DownloadGuideFromWebAsync(guideLink);
programGuideSubject.OnNext(programGuide);
}
}
}
@@ -54,6 +54,8 @@ namespace TV_Player.ViewModels
public void SetPageContext(ContentControl control, object viewModel)
{
if (_mainViewModel.Control is IDisposable disposable)
disposable.Dispose();
control.DataContext = viewModel;
_mainViewModel.Control = control;
}