24ca481b64
Added support for loading M3U playlists from both web URLs and local file paths, with logic to resolve relative paths. Improved exception handling in M3UParser. Enabled toggling of window border style in fullscreen mode, with data binding for WindowStyle. Removed IsValidUrl check to allow local file sources in settings. Cleaned up usings and formatting. Removed .NET SDK version from global.json.
98 lines
4.3 KiB
C#
98 lines
4.3 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reactive;
|
|
using System.Reactive.Subjects;
|
|
using System.Threading.Tasks;
|
|
using System.Collections.Generic;
|
|
|
|
namespace TV_Player
|
|
{
|
|
public class ProgramsData
|
|
{
|
|
private readonly ReplaySubject<List<M3UInfo>> programsSubject = new ReplaySubject<List<M3UInfo>>();
|
|
private readonly ReplaySubject<List<GroupInfo>> groupsSubject = new ReplaySubject<List<GroupInfo>>();
|
|
private readonly ReplaySubject<Unit> programGuideSubject = new ReplaySubject<Unit>();
|
|
public IObservable<List<M3UInfo>> AllPrograms => programsSubject;
|
|
public IObservable<List<GroupInfo>> GroupsInformation => groupsSubject;
|
|
public IObservable<Unit> ProgramGuideInfo => programGuideSubject;
|
|
|
|
private readonly string _programName;
|
|
public ProgramsData(string name,string playlistURL)
|
|
{
|
|
_programName = name;
|
|
Task.Run(() => GetPrograms(name,playlistURL));
|
|
}
|
|
|
|
private async Task GetPrograms(string name,string m3uLink)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine($"[ProgramsData] Starting download of: {m3uLink}");
|
|
//string m3uLink = "http://pl.da-tv.vip/a71e77fa/835b3216/tv.m3u";
|
|
try
|
|
{
|
|
// if link is a well-formed absolute URI load from web, otherwise treat as a local file path
|
|
// for relative paths try resolving against the application's base directory
|
|
var result = (programList: new List<M3UInfo>(), programGuide: string.Empty);
|
|
if (Uri.IsWellFormedUriString(m3uLink, UriKind.Absolute))
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("[ProgramsData] Detected URL, downloading from web");
|
|
result = await M3UParser.DownloadM3UFromWebAsync(m3uLink);
|
|
}
|
|
else
|
|
{
|
|
// try as provided path first
|
|
var candidate = m3uLink;
|
|
if (!Path.IsPathRooted(candidate))
|
|
{
|
|
candidate = Path.Combine(AppContext.BaseDirectory ?? string.Empty, candidate);
|
|
}
|
|
|
|
if (File.Exists(candidate))
|
|
{
|
|
System.Diagnostics.Debug.WriteLine($"[ProgramsData] Detected local file, loading from disk: {candidate}");
|
|
result = await M3UParser.DownloadM3UFromWebAsync(candidate);
|
|
}
|
|
else
|
|
{
|
|
throw new FileNotFoundException($"M3U file not found: {m3uLink}");
|
|
}
|
|
}
|
|
System.Diagnostics.Debug.WriteLine($"[ProgramsData] Downloaded {result.programList.Count} programs");
|
|
|
|
programsSubject.OnNext(result.programList);
|
|
|
|
var groupping = result.programList.GroupBy(item => item.GroupTitle)
|
|
.Select(group => new GroupInfo() { Name = group.Key, Count = group.Count() })
|
|
.OrderBy(g => g.Name)
|
|
.ToList();
|
|
System.Diagnostics.Debug.WriteLine($"[ProgramsData] Publishing {groupping.Count} groups: {string.Join(", ", groupping.Select(g => $"{g.Name}({g.Count})"))}");
|
|
if (groupping.Count == 0)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("[ProgramsData] WARNING: No groups found! Check if programs have 'group-title' metadata.");
|
|
}
|
|
groupsSubject.OnNext(groupping);
|
|
|
|
await Task.Run(() => GetProgramGuide(name, result.programGuide));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine($"[ProgramsData] ERROR downloading programs: {ex.Message}");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public Task<ProgramGuide> GetGuideByProgram(string channelID)
|
|
{
|
|
return M3UParser.ParseEpg(_programName,channelID);
|
|
}
|
|
|
|
private async Task GetProgramGuide(string name, string guideLink)
|
|
{
|
|
//guideLink = "http://epg.da-tv.vip/107-light.xml";
|
|
await M3UParser.DownloadGuideFromWebAsync(name,guideLink);
|
|
programGuideSubject.OnNext(Unit.Default);
|
|
}
|
|
|
|
}
|
|
}
|