Got WPF version work

This commit is contained in:
Vova
2024-01-18 17:42:44 +02:00
parent df51ee3ad6
commit 10b4146772
64 changed files with 866 additions and 411 deletions
+8
View File
@@ -0,0 +1,8 @@
namespace TV_Player
{
public class GroupInfo
{
public string Name { get; set; }
public int Count { get; set; }
}
}
+14
View File
@@ -0,0 +1,14 @@
namespace TV_Player
{
public class M3UInfo
{
public string CUID { get; set; }
public string Number { get; set; }
public string TvgID { get; set; }
public string TvgName { get; set; }
public string GroupTitle { get; set; }
public string Logo { get; set; }
public string Name{ get; set; }
public string Url { get; set; }
}
}
+101
View File
@@ -0,0 +1,101 @@
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
namespace TV_Player
{
public static class M3UParser
{
public static async Task<List<M3UInfo>> DownloadM3UFromWebAsync(string url)
{
List<M3UInfo> playlistItems = new List<M3UInfo>();
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();
// Parse M3U content
playlistItems = ParseM3UFromString(responseBody);
}
return playlistItems;
}
static string[] SplitStringBeforeSeparator(string input, string separator)
{
string[] parts = input.Split(separator);
// Reconstruct the string until the separator is reached
int separatorIndex = input.IndexOf(separator);
if (separatorIndex != -1)
{
parts[0] = input.Substring(0, separatorIndex + 1);
for (int i = 1; i < parts.Length; i++)
{
parts[i] = separator + parts[i];
}
}
return parts;
}
static List<M3UInfo> ParseM3UFromString(string content)
{
List<M3UInfo> playlistItems = new List<M3UInfo>();
try
{
var m3u = SplitStringBeforeSeparator(content, "#EXT");
foreach (var line in m3u)
{
if (line.StartsWith("#EXTINF:"))
{
if (TryParseM3ULine(line, out var m3uInfo))
{
playlistItems.Add(m3uInfo);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error reading M3U file: " + ex.Message);
}
return playlistItems;
}
static bool TryParseM3ULine(string m3uLine, out M3UInfo? info)
{
info = null;
string pattern = @"#EXTINF:\d+ CUID=""(?<CUID>.*?)"" number=""(?<Number>.*?)"" tvg-id=""(?<TvgID>.*?)"" tvg-name=""(?<TvgName>.*?)"".*?tvg-logo=""(?<Logo>.*?)"" group-title=""(?<GroupTitle>.*?)""[^,]*,(?<Name>.*)[^\r](?<URL>.*)$";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
Match match = regex.Match(m3uLine);
if (match.Success)
{
info = new M3UInfo
{
CUID = match.Groups["CUID"].Value,
Number = match.Groups["Number"].Value,
TvgID = match.Groups["TvgID"].Value,
TvgName = match.Groups["TvgName"].Value,
GroupTitle = match.Groups["GroupTitle"].Value,
Logo = match.Groups["Logo"].Value,
Name = match.Groups["Name"].Value,
Url = match.Groups["URL"].Value
};
return true;
}
return false;
}
}
}
+23
View File
@@ -0,0 +1,23 @@
using System.Windows.Controls;
namespace TV_Player
{
public class MainViewModel : ObservableViewModelBase
{
private ContentControl _control;
public ContentControl Control
{
get => _control;
set => SetProperty(ref _control, value);
}
public MainViewModel()
{
var vm = new ProgramsGroupViewModel();
var control = new ProgramsGroupGrid();
control.DataContext = vm;
Control = control;
}
}
}
@@ -0,0 +1,28 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace TV_Player
{
public abstract class ObservableViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
/// <summary>
/// Set a property and raise a property changed event if it has changed
/// </summary>
protected bool SetProperty<T>(ref T property, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(property, value))
{
return false;
}
property = value;
RaisePropertyChanged(propertyName);
return true;
}
}
}
@@ -0,0 +1,48 @@
using System.Windows.Input;
namespace TV_Player
{
public class PlayerViewModel: ObservableViewModelBase
{
private readonly M3UInfo _currentProgram;
private string _urlSource;
public string URLSource
{
get => _urlSource;
set => SetProperty(ref _urlSource, value);
}
public GroupInfo SelectedItem { get; set; }
public ICommand PlayCommand { get; }
public PlayerViewModel(M3UInfo selectedProgram)
{
_currentProgram = selectedProgram;
//PlayM3U8(_currentProgram.Url);
//_libVLC = new LibVLC();
//_mediaPlayer = new MediaPlayer(new Media(_libVLC, new Uri(_currentProgram.Url)));
//_mediaPlayer.Play();
//PlayCommand = new Command(OnPlayButtonClicked);
}
private void OnPlayButtonClicked()
{
PlayM3U8(_currentProgram.Url);
}
private void PlayM3U8(string url)
{
try
{
URLSource = _currentProgram.Url;
}
catch (Exception ex)
{
// Handle exceptions
}
}
}
}
+39
View File
@@ -0,0 +1,39 @@
using System.Reactive.Subjects;
namespace TV_Player
{
public class ProgramsData
{
private static ProgramsData _instance;
public static ProgramsData Instance
{
get
{
_instance ??= new ProgramsData();
return _instance;
}
}
private readonly ReplaySubject<List<M3UInfo>> programsSubject = new ReplaySubject<List<M3UInfo>>();
private readonly ReplaySubject<List<GroupInfo>> groupsSubject = new ReplaySubject<List<GroupInfo>>();
public IObservable<List<M3UInfo>> AllPrograms => programsSubject;
public IObservable<List<GroupInfo>> GroupsInformation => groupsSubject;
private ProgramsData()
{
_=Initialize();
}
private async Task Initialize()
{
string m3uLink = "http://pl.da-tv.vip/a71e77fa/835b3216/tv.m3u";
var programs = await M3UParser.DownloadM3UFromWebAsync(m3uLink);
programsSubject.OnNext(programs);
var groupping = programs.GroupBy(item => item.GroupTitle)
.Select(group => new GroupInfo() { Name = group.Key, Count = group.Count() })
.ToList();
groupsSubject.OnNext(groupping);
}
}
}
@@ -0,0 +1,36 @@
using CommunityToolkit.Mvvm.Input;
using System.Windows.Input;
using TV_Player.ViewModels;
namespace TV_Player
{
public class ProgramsGroupViewModel : ObservableViewModelBase
{
private List<GroupInfo> _programs;
public List<GroupInfo> Programs
{
get => _programs;
set => SetProperty(ref _programs, value);
}
public GroupInfo SelectedItem { get; set; }
public ICommand ItemSelectedCommand { get; }
public ProgramsGroupViewModel()
{
ItemSelectedCommand = new RelayCommand(OnItemSelected);
ProgramsData.Instance.GroupsInformation.Subscribe(x=>Programs = x);
}
private void OnItemSelected()
{
//var navigation = (INavigation)Application.Current.MainPage.Navigation;
var programListViewModel = new ProgramsListViewModel(SelectedItem);
var conrtrol = new ProgramsList();
TVPlayerViewModel.Instance.SetPageContext(conrtrol, programListViewModel);
}
}
}
@@ -0,0 +1,45 @@
using CommunityToolkit.Mvvm.Input;
using System.Windows.Input;
using TV_Player.ViewModels;
namespace TV_Player
{
public class ProgramsListViewModel : ObservableViewModelBase
{
private List<M3UInfo> _programs;
public List<M3UInfo> Programs
{
get => _programs;
set => SetProperty(ref _programs, value);
}
public M3UInfo SelectedItem { get; set; }
public ICommand ItemSelectedCommand { get; }
public ProgramsListViewModel(GroupInfo groupInfo)
{
ItemSelectedCommand = new RelayCommand(OnItemSelected);
ProgramsData.Instance.AllPrograms.Subscribe(x=>Programs = x.Where(p=>p.GroupTitle== groupInfo.Name).ToList());
}
private void OnItemSelected()
{
var playerViewModel = new PlayerViewModel(SelectedItem);
var conrtrol = new VideoPlayer();
conrtrol.SourceUrl = SelectedItem.Url;
TVPlayerViewModel.Instance.SetPageContext(conrtrol, playerViewModel);
//var navigation = (INavigation)Application.Current.MainPage.Navigation;
//var playerViewModel = new PlayerViewModel(SelectedItem);
//// Create a new SecondPage and set its BindingContext to the ViewModel
//var playerPage = new PlayerPage
//{
// BindingContext = playerViewModel
//};
//// Navigate to the OtherPage
//navigation.PushAsync(playerPage);
}
}
}
+33
View File
@@ -0,0 +1,33 @@
using System.Windows.Input;
namespace TV_Player.ViewModels
{
//public class RelayCommand : ICommand
//{
// private readonly Action _execute;
// private readonly Func<bool> _canExecute;
// public event EventHandler CanExecuteChanged;
// public RelayCommand(Action execute, Func<bool> canExecute = null)
// {
// _execute = execute ?? throw new ArgumentNullException(nameof(execute));
// _canExecute = canExecute;
// }
// public bool CanExecute(object parameter)
// {
// return _canExecute == null || _canExecute();
// }
// public void Execute(object parameter)
// {
// _execute();
// }
// public void RaiseCanExecuteChanged()
// {
// CanExecuteChanged?.Invoke(this, EventArgs.Empty);
// }
//}
}
@@ -0,0 +1,37 @@
using System.Windows.Controls;
namespace TV_Player.ViewModels
{
public class TVPlayerViewModel
{
private readonly MainViewModel _mainViewModel;
private static TVPlayerViewModel _instance;
public static TVPlayerViewModel Instance
{
get
{
if(_instance==null)
_instance = new TVPlayerViewModel();
return _instance;
}
}
public TVPlayerViewModel()
{
_mainViewModel = new MainViewModel();
var mainWindow=new MainWindow();
mainWindow.DataContext = _mainViewModel;
mainWindow.Show();
_instance = this;
}
public void SetPageContext(ContentControl control, object viewModel)
{
control.DataContext = viewModel;
_mainViewModel.Control = control;
}
}
}