aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/LiveTv
diff options
context:
space:
mode:
authorNick <20588554+nicknsy@users.noreply.github.com>2023-10-18 19:27:05 -0700
committerNick <20588554+nicknsy@users.noreply.github.com>2023-10-18 19:27:05 -0700
commitcd662506a1f63f9b20e7f5caa9b671eb3d71ea5a (patch)
treeb58f7158e21e7ed21d77b0f0abfce23d796b3fe3 /Emby.Server.Implementations/LiveTv
parentc7feea27fde8af60984c8fe41444dc245dbde395 (diff)
parentde08d38a6f2a6e773fa1000574e08322605b56d3 (diff)
Merge branch 'master' into trickplay
Diffstat (limited to 'Emby.Server.Implementations/LiveTv')
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs14
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs25
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs12
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs79
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs12
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/LegacyHdHomerunChannelCommands.cs7
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs7
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs18
8 files changed, 79 insertions, 95 deletions
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index b9d0f170a..74b62ca3f 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1851,7 +1851,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return;
}
- await using (var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None))
+ var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None);
+ await using (stream.ConfigureAwait(false))
{
var settings = new XmlWriterSettings
{
@@ -1860,7 +1861,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
Async = true
};
- await using (var writer = XmlWriter.Create(stream, settings))
+ var writer = XmlWriter.Create(stream, settings);
+ await using (writer.ConfigureAwait(false))
{
await writer.WriteStartDocumentAsync(true).ConfigureAwait(false);
await writer.WriteStartElementAsync(null, "tvshow", null).ConfigureAwait(false);
@@ -1914,7 +1916,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return;
}
- await using (var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None))
+ var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None);
+ await using (stream.ConfigureAwait(false))
{
var settings = new XmlWriterSettings
{
@@ -1927,7 +1930,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
var isSeriesEpisode = timer.IsProgramSeries;
- await using (var writer = XmlWriter.Create(stream, settings))
+ var writer = XmlWriter.Create(stream, settings);
+ await using (writer.ConfigureAwait(false))
{
await writer.WriteStartDocumentAsync(true).ConfigureAwait(false);
@@ -1965,7 +1969,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
else
{
- await writer.WriteStartElementAsync(null, "movie", null);
+ await writer.WriteStartElementAsync(null, "movie", null).ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(item.Name))
{
diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
index 7645c6c52..6b0520ad0 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
@@ -106,8 +106,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
options.Content = JsonContent.Create(requestList, options: _jsonOptions);
options.Headers.TryAddWithoutValidation("token", token);
using var response = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
- await using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- var dailySchedules = await JsonSerializer.DeserializeAsync<IReadOnlyList<DayDto>>(responseStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ var dailySchedules = await response.Content.ReadFromJsonAsync<IReadOnlyList<DayDto>>(_jsonOptions, cancellationToken).ConfigureAwait(false);
if (dailySchedules is null)
{
return Array.Empty<ProgramInfo>();
@@ -122,8 +121,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
programRequestOptions.Content = JsonContent.Create(programIds, options: _jsonOptions);
using var innerResponse = await Send(programRequestOptions, true, info, cancellationToken).ConfigureAwait(false);
- await using var innerResponseStream = await innerResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- var programDetails = await JsonSerializer.DeserializeAsync<IReadOnlyList<ProgramDetailsDto>>(innerResponseStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ var programDetails = await innerResponse.Content.ReadFromJsonAsync<IReadOnlyList<ProgramDetailsDto>>(_jsonOptions, cancellationToken).ConfigureAwait(false);
if (programDetails is null)
{
return Array.Empty<ProgramInfo>();
@@ -482,8 +480,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
try
{
using var innerResponse2 = await Send(message, true, info, cancellationToken).ConfigureAwait(false);
- await using var response = await innerResponse2.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- return await JsonSerializer.DeserializeAsync<IReadOnlyList<ShowImagesDto>>(response, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ return await innerResponse2.Content.ReadFromJsonAsync<IReadOnlyList<ShowImagesDto>>(_jsonOptions, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -510,10 +507,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
try
{
using var httpResponse = await Send(options, false, info, cancellationToken).ConfigureAwait(false);
- await using var response = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-
- var root = await JsonSerializer.DeserializeAsync<IReadOnlyList<HeadendsDto>>(response, _jsonOptions, cancellationToken).ConfigureAwait(false);
-
+ var root = await httpResponse.Content.ReadFromJsonAsync<IReadOnlyList<HeadendsDto>>(_jsonOptions, cancellationToken).ConfigureAwait(false);
if (root is not null)
{
foreach (HeadendsDto headend in root)
@@ -649,8 +643,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
using var response = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
- await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- var root = await JsonSerializer.DeserializeAsync<TokenDto>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ var root = await response.Content.ReadFromJsonAsync<TokenDto>(_jsonOptions, cancellationToken).ConfigureAwait(false);
if (string.Equals(root?.Message, "OK", StringComparison.Ordinal))
{
_logger.LogInformation("Authenticated with Schedules Direct token: {Token}", root.Token);
@@ -691,10 +684,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
using var httpResponse = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
httpResponse.EnsureSuccessStatusCode();
- await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- using var response = httpResponse.Content;
- var root = await JsonSerializer.DeserializeAsync<LineupsDto>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
-
+ var root = await httpResponse.Content.ReadFromJsonAsync<LineupsDto>(_jsonOptions, cancellationToken).ConfigureAwait(false);
return root?.Lineups.Any(i => string.Equals(info.ListingsId, i.Lineup, StringComparison.OrdinalIgnoreCase)) ?? false;
}
catch (HttpRequestException ex)
@@ -748,8 +738,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
options.Headers.TryAddWithoutValidation("token", token);
using var httpResponse = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
- await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- var root = await JsonSerializer.DeserializeAsync<ChannelDto>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ var root = await httpResponse.Content.ReadFromJsonAsync<ChannelDto>(_jsonOptions, cancellationToken).ConfigureAwait(false);
if (root is null)
{
return new List<ChannelInfo>();
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
index 7b6c8b80a..ff25ee585 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
@@ -3,6 +3,7 @@
#pragma warning disable CS1591
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -16,21 +17,20 @@ using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv;
-using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
public abstract class BaseTunerHost
{
- private readonly IMemoryCache _memoryCache;
+ private readonly ConcurrentDictionary<string, List<ChannelInfo>> _cache;
- protected BaseTunerHost(IServerConfigurationManager config, ILogger<BaseTunerHost> logger, IFileSystem fileSystem, IMemoryCache memoryCache)
+ protected BaseTunerHost(IServerConfigurationManager config, ILogger<BaseTunerHost> logger, IFileSystem fileSystem)
{
Config = config;
Logger = logger;
- _memoryCache = memoryCache;
FileSystem = fileSystem;
+ _cache = new ConcurrentDictionary<string, List<ChannelInfo>>();
}
protected IServerConfigurationManager Config { get; }
@@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
var key = tuner.Id;
- if (enableCache && !string.IsNullOrEmpty(key) && _memoryCache.TryGetValue(key, out List<ChannelInfo> cache))
+ if (enableCache && !string.IsNullOrEmpty(key) && _cache.TryGetValue(key, out List<ChannelInfo> cache))
{
return cache;
}
@@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
if (!string.IsNullOrEmpty(key) && list.Count > 0)
{
- _memoryCache.Set(key, list);
+ _cache[key] = list;
}
return list;
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index 98bbc1540..8cd0c4ffb 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -9,6 +9,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
+using System.Net.Http.Json;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@@ -27,7 +28,6 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net;
-using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
@@ -50,9 +50,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
IHttpClientFactory httpClientFactory,
IServerApplicationHost appHost,
ISocketFactory socketFactory,
- IStreamHelper streamHelper,
- IMemoryCache memoryCache)
- : base(config, logger, fileSystem, memoryCache)
+ IStreamHelper streamHelper)
+ : base(config, logger, fileSystem)
{
_httpClientFactory = httpClientFactory;
_appHost = appHost;
@@ -77,13 +76,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(model.LineupURL ?? model.BaseURL + "/lineup.json", HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- var lineup = await JsonSerializer.DeserializeAsync<List<Channels>>(stream, _jsonOptions, cancellationToken)
- .ConfigureAwait(false) ?? new List<Channels>();
-
+ var lineup = await response.Content.ReadFromJsonAsync<IEnumerable<Channels>>(_jsonOptions, cancellationToken).ConfigureAwait(false) ?? Enumerable.Empty<Channels>();
if (info.ImportFavoritesOnly)
{
- lineup = lineup.Where(i => i.Favorite).ToList();
+ lineup = lineup.Where(i => i.Favorite);
}
return lineup.Where(i => !i.DRM).ToList();
@@ -130,9 +126,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
.GetAsync(GetApiUrl(info) + "/discover.json", HttpCompletionOption.ResponseHeadersRead, cancellationToken)
.ConfigureAwait(false);
response.EnsureSuccessStatusCode();
- await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- var discoverResponse = await JsonSerializer.DeserializeAsync<DiscoverResponse>(stream, _jsonOptions, cancellationToken)
- .ConfigureAwait(false);
+ var discoverResponse = await response.Content.ReadFromJsonAsync<DiscoverResponse>(_jsonOptions, cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrEmpty(cacheKey))
{
@@ -176,34 +170,37 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}/tuners.html", GetApiUrl(info)), HttpCompletionOption.ResponseHeadersRead, cancellationToken)
.ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
var tuners = new List<LiveTvTunerInfo>();
- await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false))
+ var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
+ await using (stream.ConfigureAwait(false))
{
- string stripedLine = StripXML(line);
- if (stripedLine.Contains("Channel", StringComparison.Ordinal))
+ using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
+ await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false))
{
- LiveTvTunerStatus status;
- var index = stripedLine.IndexOf("Channel", StringComparison.OrdinalIgnoreCase);
- var name = stripedLine.Substring(0, index - 1);
- var currentChannel = stripedLine.Substring(index + 7);
- if (string.Equals(currentChannel, "none", StringComparison.Ordinal))
+ string stripedLine = StripXML(line);
+ if (stripedLine.Contains("Channel", StringComparison.Ordinal))
{
- status = LiveTvTunerStatus.LiveTv;
- }
- else
- {
- status = LiveTvTunerStatus.Available;
- }
+ LiveTvTunerStatus status;
+ var index = stripedLine.IndexOf("Channel", StringComparison.OrdinalIgnoreCase);
+ var name = stripedLine.Substring(0, index - 1);
+ var currentChannel = stripedLine.Substring(index + 7);
+ if (string.Equals(currentChannel, "none", StringComparison.Ordinal))
+ {
+ status = LiveTvTunerStatus.LiveTv;
+ }
+ else
+ {
+ status = LiveTvTunerStatus.Available;
+ }
- tuners.Add(new LiveTvTunerInfo
- {
- Name = name,
- SourceType = string.IsNullOrWhiteSpace(model.ModelNumber) ? Name : model.ModelNumber,
- ProgramName = currentChannel,
- Status = status
- });
+ tuners.Add(new LiveTvTunerInfo
+ {
+ Name = name,
+ SourceType = string.IsNullOrWhiteSpace(model.ModelNumber) ? Name : model.ModelNumber,
+ ProgramName = currentChannel,
+ Status = status
+ });
+ }
}
}
@@ -661,18 +658,18 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
// Need a way to set the Receive timeout on the socket otherwise this might never timeout?
try
{
- await udpClient.SendToAsync(discBytes, 0, discBytes.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 65001), cancellationToken).ConfigureAwait(false);
+ await udpClient.SendToAsync(discBytes, new IPEndPoint(IPAddress.Broadcast, 65001), cancellationToken).ConfigureAwait(false);
var receiveBuffer = new byte[8192];
while (!cancellationToken.IsCancellationRequested)
{
- var response = await udpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, cancellationToken).ConfigureAwait(false);
- var deviceIp = response.RemoteEndPoint.Address.ToString();
+ var response = await udpClient.ReceiveMessageFromAsync(receiveBuffer, new IPEndPoint(IPAddress.Any, 0), cancellationToken).ConfigureAwait(false);
+ var deviceIP = ((IPEndPoint)response.RemoteEndPoint).Address.ToString();
- // check to make sure we have enough bytes received to be a valid message and make sure the 2nd byte is the discover reply byte
- if (response.ReceivedBytes > 13 && response.Buffer[1] == 3)
+ // Check to make sure we have enough bytes received to be a valid message and make sure the 2nd byte is the discover reply byte
+ if (response.ReceivedBytes > 13 && receiveBuffer[1] == 3)
{
- var deviceAddress = "http://" + deviceIp;
+ var deviceAddress = "http://" + deviceIP;
var info = await TryGetTunerHostInfo(deviceAddress, cancellationToken).ConfigureAwait(false);
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs
index 7bc209d6b..68383a554 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs
@@ -44,14 +44,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
StopStreaming(socket).GetAwaiter().GetResult();
}
}
-
- GC.SuppressFinalize(this);
}
- public async Task<bool> CheckTunerAvailability(IPAddress remoteIp, int tuner, CancellationToken cancellationToken)
+ public async Task<bool> CheckTunerAvailability(IPAddress remoteIP, int tuner, CancellationToken cancellationToken)
{
using var client = new TcpClient();
- await client.ConnectAsync(remoteIp, HdHomeRunPort, cancellationToken).ConfigureAwait(false);
+ await client.ConnectAsync(remoteIP, HdHomeRunPort, cancellationToken).ConfigureAwait(false);
using var stream = client.GetStream();
return await CheckTunerAvailability(stream, tuner, cancellationToken).ConfigureAwait(false);
@@ -75,9 +73,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
- public async Task StartStreaming(IPAddress remoteIp, IPAddress localIp, int localPort, IHdHomerunChannelCommands commands, int numTuners, CancellationToken cancellationToken)
+ public async Task StartStreaming(IPAddress remoteIP, IPAddress localIP, int localPort, IHdHomerunChannelCommands commands, int numTuners, CancellationToken cancellationToken)
{
- _remoteEndPoint = new IPEndPoint(remoteIp, HdHomeRunPort);
+ _remoteEndPoint = new IPEndPoint(remoteIP, HdHomeRunPort);
_tcpClient = new TcpClient();
await _tcpClient.ConnectAsync(_remoteEndPoint, cancellationToken).ConfigureAwait(false);
@@ -125,7 +123,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
- var targetValue = string.Format(CultureInfo.InvariantCulture, "rtp://{0}:{1}", localIp, localPort);
+ var targetValue = string.Format(CultureInfo.InvariantCulture, "rtp://{0}:{1}", localIP, localPort);
var targetMsgLen = WriteSetMessage(buffer, i, "target", targetValue, lockKeyValue);
await stream.WriteAsync(buffer.AsMemory(0, targetMsgLen), cancellationToken).ConfigureAwait(false);
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/LegacyHdHomerunChannelCommands.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/LegacyHdHomerunChannelCommands.cs
index 3450f971f..654474e97 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/LegacyHdHomerunChannelCommands.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/LegacyHdHomerunChannelCommands.cs
@@ -5,7 +5,7 @@ using System.Text.RegularExpressions;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
- public class LegacyHdHomerunChannelCommands : IHdHomerunChannelCommands
+ public partial class LegacyHdHomerunChannelCommands : IHdHomerunChannelCommands
{
private string? _channel;
private string? _program;
@@ -13,7 +13,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
public LegacyHdHomerunChannelCommands(string url)
{
// parse url for channel and program
- var match = Regex.Match(url, @"\/ch([0-9]+)-?([0-9]*)");
+ var match = ChannelAndProgramRegex().Match(url);
if (match.Success)
{
_channel = match.Groups[1].Value;
@@ -21,6 +21,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
+ [GeneratedRegex(@"\/ch([0-9]+)-?([0-9]*)")]
+ private static partial Regex ChannelAndProgramRegex();
+
public IEnumerable<(string CommandName, string CommandValue)> GetCommands()
{
if (!string.IsNullOrEmpty(_channel))
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index acf3964c8..db5e81df5 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
@@ -22,7 +21,6 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.MediaInfo;
-using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
@@ -54,9 +52,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
IHttpClientFactory httpClientFactory,
IServerApplicationHost appHost,
INetworkManager networkManager,
- IStreamHelper streamHelper,
- IMemoryCache memoryCache)
- : base(config, logger, fileSystem, memoryCache)
+ IStreamHelper streamHelper)
+ : base(config, logger, fileSystem)
{
_httpClientFactory = httpClientFactory;
_appHost = appHost;
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
index b41816230..341782d9d 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
@@ -20,7 +20,7 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
- public class M3uParser
+ public partial class M3uParser
{
private const string ExtInfPrefix = "#EXTINF:";
@@ -33,6 +33,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
_httpClientFactory = httpClientFactory;
}
+ [GeneratedRegex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase, "en-US")]
+ private static partial Regex KeyValueRegex();
+
public async Task<List<ChannelInfo>> Parse(TunerHostInfo info, string channelIdPrefix, CancellationToken cancellationToken)
{
// Read the file and display it line by line.
@@ -91,14 +94,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
else if (!string.IsNullOrWhiteSpace(extInf) && !trimmedLine.StartsWith('#'))
{
var channel = GetChannelnfo(extInf, tunerHostId, trimmedLine);
- if (string.IsNullOrWhiteSpace(channel.Id))
- {
- channel.Id = channelIdPrefix + trimmedLine.GetMD5().ToString("N", CultureInfo.InvariantCulture);
- }
- else
- {
- channel.Id = channelIdPrefix + channel.Id.GetMD5().ToString("N", CultureInfo.InvariantCulture);
- }
+ channel.Id = channelIdPrefix + trimmedLine.GetMD5().ToString("N", CultureInfo.InvariantCulture);
channel.Path = trimmedLine;
channels.Add(channel);
@@ -311,7 +307,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- var matches = Regex.Matches(line, @"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase);
+ var matches = KeyValueRegex().Matches(line);
remaining = line;
@@ -320,7 +316,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
var key = match.Groups[1].Value;
var value = match.Groups[2].Value;
- dict[match.Groups[1].Value] = match.Groups[2].Value;
+ dict[key] = value;
remaining = remaining.Replace(key + "=\"" + value + "\"", string.Empty, StringComparison.OrdinalIgnoreCase);
}