diff --git a/TV Player WPF/MainWindow.xaml b/TV Player WPF/MainWindow.xaml
index 86713db..bba0fc8 100644
--- a/TV Player WPF/MainWindow.xaml
+++ b/TV Player WPF/MainWindow.xaml
@@ -5,7 +5,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TV_Player"
mc:Ignorable="d" WindowStyle="None" WindowState="{Binding CurrentWindowState}"
- Title="TV" Height="450" Width="800">
+ Title="TV" Height="450" Width="800"
+ KeyDown="UserControl_KeyDown">
diff --git a/TV Player WPF/MainWindow.xaml.cs b/TV Player WPF/MainWindow.xaml.cs
index c412cfd..d319b3a 100644
--- a/TV Player WPF/MainWindow.xaml.cs
+++ b/TV Player WPF/MainWindow.xaml.cs
@@ -1,4 +1,5 @@
using System.Windows;
+using System.Windows.Input;
namespace TV_Player
{
@@ -8,5 +9,13 @@ namespace TV_Player
{
InitializeComponent();
}
+
+ private void UserControl_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (DataContext is MainViewModel viewModel)
+ {
+ viewModel.OnKeyDownCommand.Execute(e);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/TV Player WPF/PlaylistWorker/M3UParser.cs b/TV Player WPF/PlaylistWorker/M3UParser.cs
index b36d0b4..0cb1371 100644
--- a/TV Player WPF/PlaylistWorker/M3UParser.cs
+++ b/TV Player WPF/PlaylistWorker/M3UParser.cs
@@ -31,11 +31,11 @@ namespace TV_Player
public static class M3UParser
{
- public static async Task DownloadGuideFromWebAsync(string url)
+ public static async Task DownloadGuideFromWebAsync(string name, string url)
{
- var fileName = "guide.xml";
+ var fileName = name+"_guide.xml";
string programDataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
- string filePath = Path.Combine(programDataPath, "TV_Player", fileName);
+ string filePath = Path.Combine(programDataPath, "TVPlayer", fileName);
if (File.Exists(filePath))
@@ -247,8 +247,8 @@ namespace TV_Player
private static bool TryParseM3ULine(string m3uLine, out M3UInfo? info)
{
info = null;
- //string pattern = @"#EXTINF:\d+ CUID=""(?.*?)"" number=""(?.*?)"" tvg-id=""(?.*?)"" tvg-name=""(?.*?)"".*?tvg-logo=""(?.*?)"" group-title=""(?.*?)""[^,]*,(?.*)[^\r](?.*)$";
- string pattern = @"#EXTINF:(-?\d+)\s+?(?:timeshift=""(?.*?)""\s+)?(?:catchup-days=""(?.*?)""\s+)?(?:catchup-type=""(?.*?)""\s+)?(?:CUID=""(?.*?)""\s+)?(?:number=""(?.*?)""\s+)?(?:tvg-id=""(?.*?)""\s+)?(?:tvg-name=""(?.*?)""\s+)?(?:group-title=""(?.*?)""\s+)?(?:tvg-logo=""(?.*?)"")?,(?.*?)\s*\r?\n(?.*)";
+ string pattern = @"#EXTINF:(-?\d+)\s+?(?:timeshift=""(?.*?)""\s+)?(?:catchup-days=""(?.*?)""\s+)?(?:catchup-type=""(?.*?)""\s+)?(?:CUID=""(?.*?)""\s+)?(?:number=""(?.*?)""\s+)?(?:tvg-id=""(?.*?)""\s+)?(?:tvg-name=""(?.*?)""\s+)?(?:group-title=""(?.*?)""\s+)?(?:tvg-logo=""(?.*?)""\s*)?(?:group-title=""(?.*?)"")?(?:,(?.*?)\s*\r?\n(?.*))";
+ //string pattern = @"#EXTINF:(-?\d+)\s+?(?:timeshift=""(?.*?)""\s+)?(?:catchup-days=""(?.*?)""\s+)?(?:catchup-type=""(?.*?)""\s+)?(?:CUID=""(?.*?)""\s+)?(?:number=""(?.*?)""\s+)?(?:tvg-id=""(?.*?)""\s+)?(?:tvg-name=""(?.*?)""\s+)?(?:group-title=""(?.*?)""\s+)?(?:tvg-logo=""(?.*?)"")?,(?.*?)\s*\r?\n(?.*)";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
Match match = regex.Match(m3uLine);
diff --git a/TV Player WPF/PlaylistsGroup.xaml b/TV Player WPF/PlaylistsGroup.xaml
new file mode 100644
index 0000000..6e2e17f
--- /dev/null
+++ b/TV Player WPF/PlaylistsGroup.xaml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TV Player WPF/PlaylistsGroup.xaml.cs b/TV Player WPF/PlaylistsGroup.xaml.cs
new file mode 100644
index 0000000..0708304
--- /dev/null
+++ b/TV Player WPF/PlaylistsGroup.xaml.cs
@@ -0,0 +1,23 @@
+using System.Windows.Controls;
+
+namespace TV_Player
+{
+ ///
+ /// Interaction logic for ProgramsGroupGrid.xaml
+ ///
+ public partial class PlaylistsGroup : UserControl
+ {
+ public PlaylistsGroup()
+ {
+ InitializeComponent();
+ }
+
+ private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (DataContext is PlaylistsGroupViewModel viewModel)
+ {
+ viewModel.ItemSelectedCommand.Execute(null);
+ }
+ }
+ }
+}
diff --git a/TV Player WPF/Settings.xaml b/TV Player WPF/Settings.xaml
index 531433b..c5d8432 100644
--- a/TV Player WPF/Settings.xaml
+++ b/TV Player WPF/Settings.xaml
@@ -6,14 +6,18 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
+
+
+
+
+
Откывать во весь экран
Запоминать последний выбор
-
diff --git a/TV Player WPF/ViewModels/MainViewModel.cs b/TV Player WPF/ViewModels/MainViewModel.cs
index a9ef975..dcd3094 100644
--- a/TV Player WPF/ViewModels/MainViewModel.cs
+++ b/TV Player WPF/ViewModels/MainViewModel.cs
@@ -36,6 +36,7 @@ namespace TV_Player
get => _currentWindowState;
set => SetProperty(ref _currentWindowState, value);
}
+ public ICommand OnKeyDownCommand { get; }
public ICommand FullscreenCommand { get; }
public ICommand CloseAppCommand { get; }
@@ -47,7 +48,7 @@ namespace TV_Player
public MainViewModel()
{
-
+ OnKeyDownCommand = new RelayCommand(OnKeyDown);
BackCommand = new RelayCommand(OnButtonBackClick);
FullscreenCommand = new RelayCommand(OnFullSctreenButtonClick);
SettingsCommand = new RelayCommand(OnSettingsButtonClick);
@@ -81,5 +82,17 @@ namespace TV_Player
{
TVPlayerViewModel.Instance.ShowSettingsScreen();
}
+
+ private void OnKeyDown(KeyEventArgs e)
+ {
+ if (e.Key == Key.Escape)
+ {
+ Environment.Exit(0);
+ }
+ if (e.Key == Key.Back)
+ {
+ ButtonBackAction?.Invoke();
+ }
+ }
}
}
diff --git a/TV Player WPF/ViewModels/PlayerViewModel.cs b/TV Player WPF/ViewModels/PlayerViewModel.cs
index 63f0cf4..da3532c 100644
--- a/TV Player WPF/ViewModels/PlayerViewModel.cs
+++ b/TV Player WPF/ViewModels/PlayerViewModel.cs
@@ -98,7 +98,7 @@ namespace TV_Player
ShowProgramListCommand = new RelayCommand(ShowProgramList);
ProgramGuideVisible = false;
- _programSubscriber = TVPlayerViewModel.Instance.PlaylistData.AllPrograms.Subscribe(x =>
+ _programSubscriber = TVPlayerViewModel.Instance.CurrentProgrmsData.AllPrograms.Subscribe(x =>
{
_programs = x.Where(p => p.GroupTitle == _currentProgram.GroupTitle).ToList();
_currentProgramIndex = _programs.Select((program, index) => new { program, index })
@@ -116,11 +116,11 @@ namespace TV_Player
TopPanelTitle = _currentProgram.Name;
SourceUrlChangedEvent?.Invoke(_currentProgram.Url);
- _programGuideDisposable = TVPlayerViewModel.Instance.PlaylistData.ProgramGuideInfo.Subscribe(async x =>
+ _programGuideDisposable = TVPlayerViewModel.Instance.CurrentProgrmsData.ProgramGuideInfo.Subscribe(async x =>
{
try
{
- _currentGuide = await TVPlayerViewModel.Instance.PlaylistData.GetGuideByProgram(_currentProgram.TvgID);
+ _currentGuide = await TVPlayerViewModel.Instance.CurrentProgrmsData.GetGuideByProgram(_currentProgram.TvgID);
UpdateScreenInfo();
diff --git a/TV Player WPF/ViewModels/PlaylistsGroupViewModel.cs b/TV Player WPF/ViewModels/PlaylistsGroupViewModel.cs
new file mode 100644
index 0000000..66a762a
--- /dev/null
+++ b/TV Player WPF/ViewModels/PlaylistsGroupViewModel.cs
@@ -0,0 +1,39 @@
+using CommunityToolkit.Mvvm.Input;
+using System.Windows.Input;
+using TV_Player.ViewModels;
+
+namespace TV_Player
+{
+ public class PlaylistsGroupViewModel : ObservableViewModelBase, IDisposable
+ {
+ private List _programs;
+
+ public List Programs
+ {
+ get => _programs;
+ set => SetProperty(ref _programs, value);
+ }
+
+ public GroupInfo SelectedItem { get; set; }
+ public ICommand ItemSelectedCommand { get; }
+ public IDisposable _groupInformationSubscriber;
+
+ public PlaylistsGroupViewModel()
+ {
+ ItemSelectedCommand = new RelayCommand(OnItemSelected);
+ Programs = TVPlayerViewModel.Instance.PlayListsData.Select(x=>new GroupInfo() { Name =x.Key,Count=0}).ToList();
+
+ TVPlayerViewModel.Instance.TopPanelVisible(true, "Группы");
+ }
+
+ private void OnItemSelected()
+ {
+ TVPlayerViewModel.Instance.ShowProgramsGroupScreen(SelectedItem.Name);
+ }
+
+ public void Dispose()
+ {
+ _groupInformationSubscriber.Dispose();
+ }
+ }
+}
diff --git a/TV Player WPF/ViewModels/ProgramsData.cs b/TV Player WPF/ViewModels/ProgramsData.cs
index 05ab133..d2c792d 100644
--- a/TV Player WPF/ViewModels/ProgramsData.cs
+++ b/TV Player WPF/ViewModels/ProgramsData.cs
@@ -12,11 +12,12 @@ namespace TV_Player
public IObservable> GroupsInformation => groupsSubject;
public IObservable ProgramGuideInfo => programGuideSubject;
- public ProgramsData()
- {
+ public ProgramsData(string name,string playlistURL)
+ {
+ Task.Run(() => GetPrograms(name,playlistURL));
}
- private async Task GetPrograms(string m3uLink)
+ private async Task GetPrograms(string name,string m3uLink)
{
//string m3uLink = "http://pl.da-tv.vip/a71e77fa/835b3216/tv.m3u";
var result = await M3UParser.DownloadM3UFromWebAsync(m3uLink);
@@ -28,7 +29,7 @@ namespace TV_Player
.ToList();
groupsSubject.OnNext(groupping);
- await Task.Run(() => GetProgramGuide(result.programGuide));
+ await Task.Run(() => GetProgramGuide(name,result.programGuide));
}
public Task GetGuideByProgram(string channelID)
@@ -36,16 +37,12 @@ namespace TV_Player
return M3UParser.ParseEpg(channelID);
}
- private async Task GetProgramGuide(string guideLink)
+ private async Task GetProgramGuide(string name, string guideLink)
{
//guideLink = "http://epg.da-tv.vip/107-light.xml";
- await M3UParser.DownloadGuideFromWebAsync(guideLink);
+ await M3UParser.DownloadGuideFromWebAsync(name,guideLink);
programGuideSubject.OnNext(Unit.Default);
}
-
- internal void GetData(string playlistURL)
- {
- Task.Run(() => GetPrograms(playlistURL));
- }
+
}
}
diff --git a/TV Player WPF/ViewModels/ProgramsGroupViewModel.cs b/TV Player WPF/ViewModels/ProgramsGroupViewModel.cs
index 95eb914..ce07baf 100644
--- a/TV Player WPF/ViewModels/ProgramsGroupViewModel.cs
+++ b/TV Player WPF/ViewModels/ProgramsGroupViewModel.cs
@@ -21,9 +21,14 @@ namespace TV_Player
public ProgramsGroupViewModel()
{
ItemSelectedCommand = new RelayCommand(OnItemSelected);
- _groupInformationSubscriber = TVPlayerViewModel.Instance.PlaylistData.GroupsInformation.Subscribe(x => Programs = SettingsModel.HiddenGroups == null ? x : x.Where(g => !SettingsModel.HiddenGroups.Contains(g.Name.ToLower())).ToList());
+ _groupInformationSubscriber = TVPlayerViewModel.Instance.CurrentProgrmsData.GroupsInformation.Subscribe(x => Programs = SettingsModel.HiddenGroups == null ? x : x.Where(g => !SettingsModel.HiddenGroups.Contains(g.Name.ToLower())).ToList());
TVPlayerViewModel.Instance.TopPanelVisible(true, "Группы");
+
+ TVPlayerViewModel.Instance.SetBackButtonAction(new Action(() =>
+ {
+ TVPlayerViewModel.Instance.ShowPlaylistsGroupScreen();
+ }));
}
private void OnItemSelected()
diff --git a/TV Player WPF/ViewModels/ProgramsListViewModel.cs b/TV Player WPF/ViewModels/ProgramsListViewModel.cs
index 21cf630..6dd94e6 100644
--- a/TV Player WPF/ViewModels/ProgramsListViewModel.cs
+++ b/TV Player WPF/ViewModels/ProgramsListViewModel.cs
@@ -17,15 +17,15 @@ namespace TV_Player
public ICommand ItemSelectedCommand { get; }
private IDisposable _programSubscriber;
- public ProgramsListViewModel(GroupInfo groupInfo)
+ public ProgramsListViewModel(string playlistName,GroupInfo groupInfo)
{
TVPlayerViewModel.Instance.TopPanelVisible(true, groupInfo.Name);
ItemSelectedCommand = new RelayCommand(OnItemSelected);
- _programSubscriber = TVPlayerViewModel.Instance.PlaylistData.AllPrograms.Subscribe(x => Programs = x.Where(p => p.GroupTitle == groupInfo.Name).ToList());
+ _programSubscriber = TVPlayerViewModel.Instance.CurrentProgrmsData.AllPrograms.Subscribe(x => Programs = x.Where(p => p.GroupTitle == groupInfo.Name).ToList());
TVPlayerViewModel.Instance.SetBackButtonAction(new Action(() =>
{
- TVPlayerViewModel.Instance.ShowProgramsGroupScreen();
+ TVPlayerViewModel.Instance.ShowProgramsGroupScreen(playlistName);
}));
}
diff --git a/TV Player WPF/ViewModels/SettingsModel.cs b/TV Player WPF/ViewModels/SettingsModel.cs
index 322ce23..6bd9710 100644
--- a/TV Player WPF/ViewModels/SettingsModel.cs
+++ b/TV Player WPF/ViewModels/SettingsModel.cs
@@ -5,10 +5,10 @@ namespace TV_Player.ViewModels
{
public static class SettingsModel
{
- private static readonly string AppDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TVPlayer");
+ private static readonly string AppDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "TVPlayer");
private static readonly string SettingsFilePath = Path.Combine(AppDataFolder, "settings.json");
- public static string PlaylistURL { get; set; }
+ public static Dictionary Playlists { get; set; }
public static bool StartFullScreen { get; set; }
public static bool StartFromLastScreen { get; set; }
public static string LastScreen { get; set; }
@@ -21,7 +21,7 @@ namespace TV_Player.ViewModels
// Create an anonymous object to hold the properties
var dataToSerialize = new
{
- PlaylistURL,
+ Playlists,
StartFromLastScreen,
StartFullScreen,
LastScreen,
@@ -43,7 +43,7 @@ namespace TV_Player.ViewModels
{
var loadedData = new
{
- PlaylistURL = default(string),
+ Playlists = default(Dictionary),
LastScreen = default(string),
Group = default(GroupInfo),
Program = default(M3UInfo),
@@ -58,7 +58,7 @@ namespace TV_Player.ViewModels
loadedData = JsonConvert.DeserializeAnonymousType(json, loadedData);
}
// Assign the values to the properties
- PlaylistURL = loadedData.PlaylistURL;
+ Playlists = loadedData.Playlists;
LastScreen = loadedData.LastScreen;
Group = loadedData.Group;
Program = loadedData.Program;
diff --git a/TV Player WPF/ViewModels/SettingsViewModel.cs b/TV Player WPF/ViewModels/SettingsViewModel.cs
index 4e3ba47..419fe54 100644
--- a/TV Player WPF/ViewModels/SettingsViewModel.cs
+++ b/TV Player WPF/ViewModels/SettingsViewModel.cs
@@ -38,7 +38,7 @@ namespace TV_Player.ViewModels
StartFullScreen = SettingsModel.StartFullScreen;
StartLastScreen = SettingsModel.StartFromLastScreen;
- PlaylistURL = SettingsModel.PlaylistURL;
+ // PlaylistURL = SettingsModel.PlaylistURL;
}
private void OnBackCommand()
@@ -50,7 +50,7 @@ namespace TV_Player.ViewModels
{
SettingsModel.StartFullScreen = StartFullScreen;
SettingsModel.StartFromLastScreen = StartLastScreen;
- SettingsModel.PlaylistURL = PlaylistURL;
+ //SettingsModel.PlaylistURL = PlaylistURL;
SettingsModel.SaveSetttings();
TVPlayerViewModel.Instance.InitializeTVWithData();
diff --git a/TV Player WPF/ViewModels/TVPlayerViewModel.cs b/TV Player WPF/ViewModels/TVPlayerViewModel.cs
index a9cbe65..0f61446 100644
--- a/TV Player WPF/ViewModels/TVPlayerViewModel.cs
+++ b/TV Player WPF/ViewModels/TVPlayerViewModel.cs
@@ -5,10 +5,15 @@ namespace TV_Player.ViewModels
public class TVPlayerViewModel : IDisposable
{
private readonly MainViewModel _mainViewModel;
- public ProgramsData PlaylistData { get; private set; }
+
+ public ProgramsData CurrentProgrmsData { get; private set; }
+
+ public Dictionary PlayListsData { get; private set; }
public Action ButtonBackAction { get; set; }
+ private string _currentPlaylistName;
+
private static TVPlayerViewModel? _instance;
public static TVPlayerViewModel Instance
{
@@ -22,7 +27,7 @@ namespace TV_Player.ViewModels
public TVPlayerViewModel()
{
- PlaylistData = new ProgramsData();
+ PlayListsData=new Dictionary();
_mainViewModel = new MainViewModel();
var mainWindow = new MainWindow();
@@ -37,15 +42,20 @@ namespace TV_Player.ViewModels
public void InitializeTVWithData()
{
- if (!string.IsNullOrEmpty(SettingsModel.PlaylistURL))
+ if (SettingsModel.Playlists!=null && SettingsModel.Playlists.Any())
{
+ foreach(var playlist in SettingsModel.Playlists)
+ {
+ PlayListsData.Add(playlist.Key, new ProgramsData(playlist.Key,playlist.Value));
+ }
+
if (SettingsModel.StartFullScreen)
FullScreenToggle();
- PlaylistData.GetData(SettingsModel.PlaylistURL);
+
if (SettingsModel.StartFromLastScreen)
SelectScreen();
else
- ShowProgramsGroupScreen();
+ ShowPlaylistsGroupScreen();
}
else
{
@@ -64,13 +74,28 @@ namespace TV_Player.ViewModels
ShowPlayerScreen(SettingsModel.Program);
break;
default:
- ShowProgramsGroupScreen();
+ ShowPlaylistsGroupScreen();
break;
}
}
- public void ShowProgramsGroupScreen()
+ public void ShowPlaylistsGroupScreen()
{
+ var vm = new PlaylistsGroupViewModel();
+ var control = new PlaylistsGroup();
+ control.DataContext = vm;
+
+ SettingsModel.LastScreen = nameof(ProgramsGroupViewModel);
+ SetPageContext(control, vm);
+ }
+
+
+ public void ShowProgramsGroupScreen(string groupName)
+ {
+ var selectedData = PlayListsData.First(x => x.Key == groupName);
+ _currentPlaylistName = selectedData.Key;
+ CurrentProgrmsData = selectedData.Value;
+
var vm = new ProgramsGroupViewModel();
var control = new ProgramsGroupGrid();
@@ -83,7 +108,7 @@ namespace TV_Player.ViewModels
public void ShowProgramsListScreen(GroupInfo group)
{
SettingsModel.Group = group;
- var programListViewModel = new ProgramsListViewModel(group);
+ var programListViewModel = new ProgramsListViewModel(_currentPlaylistName,group);
var conrtrol = new ProgramsList();
SettingsModel.LastScreen = nameof(ProgramsListViewModel);
SetPageContext(conrtrol, programListViewModel);