Add project files.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
namespace TV_Player
|
||||
{
|
||||
public class GroupInfo
|
||||
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Count { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public class MainViewModel : 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 MainViewModel()
|
||||
{
|
||||
ItemSelectedCommand = new Command(OnItemSelected);
|
||||
ProgramsData.Instance.GroupsInformation.Subscribe(x=>Programs = x);
|
||||
}
|
||||
|
||||
private void OnItemSelected()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,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 Subject<List<M3UInfo>> programsSubject = new Subject<List<M3UInfo>>();
|
||||
private readonly Subject<List<GroupInfo>> groupsSubject = new Subject<List<GroupInfo>>();
|
||||
public IObservable<List<M3UInfo>> AllPrograms => programsSubject;
|
||||
public Subject<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user