|
@@ -17,6 +17,7 @@ using System.Xml;
|
|
|
using Jellyfin.Data.Enums;
|
|
|
using Jellyfin.Data.Events;
|
|
|
using Jellyfin.Extensions;
|
|
|
+using Jellyfin.LiveTv.Configuration;
|
|
|
using MediaBrowser.Common.Configuration;
|
|
|
using MediaBrowser.Common.Extensions;
|
|
|
using MediaBrowser.Common.Progress;
|
|
@@ -43,8 +44,6 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
{
|
|
|
public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss";
|
|
|
|
|
|
- private const int TunerDiscoveryDurationMs = 3000;
|
|
|
-
|
|
|
private readonly ILogger<EmbyTV> _logger;
|
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
|
private readonly IServerConfigurationManager _config;
|
|
@@ -53,6 +52,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
private readonly TimerManager _timerProvider;
|
|
|
|
|
|
private readonly LiveTvManager _liveTvManager;
|
|
|
+ private readonly ITunerHostManager _tunerHostManager;
|
|
|
private readonly IFileSystem _fileSystem;
|
|
|
|
|
|
private readonly ILibraryMonitor _libraryMonitor;
|
|
@@ -79,6 +79,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
IHttpClientFactory httpClientFactory,
|
|
|
IServerConfigurationManager config,
|
|
|
ILiveTvManager liveTvManager,
|
|
|
+ ITunerHostManager tunerHostManager,
|
|
|
IFileSystem fileSystem,
|
|
|
ILibraryManager libraryManager,
|
|
|
ILibraryMonitor libraryMonitor,
|
|
@@ -96,6 +97,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
_providerManager = providerManager;
|
|
|
_mediaEncoder = mediaEncoder;
|
|
|
_liveTvManager = (LiveTvManager)liveTvManager;
|
|
|
+ _tunerHostManager = tunerHostManager;
|
|
|
_mediaSourceManager = mediaSourceManager;
|
|
|
_streamHelper = streamHelper;
|
|
|
|
|
@@ -126,7 +128,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
- var path = GetConfiguration().RecordingPath;
|
|
|
+ var path = _config.GetLiveTvConfiguration().RecordingPath;
|
|
|
|
|
|
return string.IsNullOrWhiteSpace(path)
|
|
|
? DefaultRecordingPath
|
|
@@ -189,7 +191,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
pathsAdded.AddRange(pathsToCreate);
|
|
|
}
|
|
|
|
|
|
- var config = GetConfiguration();
|
|
|
+ var config = _config.GetLiveTvConfiguration();
|
|
|
|
|
|
var pathsToRemove = config.MediaLocationsCreated
|
|
|
.Except(recordingFolders.SelectMany(i => i.Locations))
|
|
@@ -309,7 +311,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
{
|
|
|
var list = new List<ChannelInfo>();
|
|
|
|
|
|
- foreach (var hostInstance in _liveTvManager.TunerHosts)
|
|
|
+ foreach (var hostInstance in _tunerHostManager.TunerHosts)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
@@ -509,7 +511,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
{
|
|
|
var list = new List<ChannelInfo>();
|
|
|
|
|
|
- foreach (var hostInstance in _liveTvManager.TunerHosts)
|
|
|
+ foreach (var hostInstance in _tunerHostManager.TunerHosts)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
@@ -831,7 +833,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
|
|
|
public Task<SeriesTimerInfo> GetNewTimerDefaultsAsync(CancellationToken cancellationToken, ProgramInfo program = null)
|
|
|
{
|
|
|
- var config = GetConfiguration();
|
|
|
+ var config = _config.GetLiveTvConfiguration();
|
|
|
|
|
|
var defaults = new SeriesTimerInfo()
|
|
|
{
|
|
@@ -932,7 +934,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
|
|
|
private List<Tuple<IListingsProvider, ListingsProviderInfo>> GetListingProviders()
|
|
|
{
|
|
|
- return GetConfiguration().ListingProviders
|
|
|
+ return _config.GetLiveTvConfiguration().ListingProviders
|
|
|
.Select(i =>
|
|
|
{
|
|
|
var provider = _liveTvManager.ListingProviders.FirstOrDefault(l => string.Equals(l.Type, i.Type, StringComparison.OrdinalIgnoreCase));
|
|
@@ -965,7 +967,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- foreach (var hostInstance in _liveTvManager.TunerHosts)
|
|
|
+ foreach (var hostInstance in _tunerHostManager.TunerHosts)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
@@ -997,7 +999,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
throw new ArgumentNullException(nameof(channelId));
|
|
|
}
|
|
|
|
|
|
- foreach (var hostInstance in _liveTvManager.TunerHosts)
|
|
|
+ foreach (var hostInstance in _tunerHostManager.TunerHosts)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
@@ -1021,11 +1023,6 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
return Task.CompletedTask;
|
|
|
}
|
|
|
|
|
|
- public Task RecordLiveStream(string id, CancellationToken cancellationToken)
|
|
|
- {
|
|
|
- return Task.CompletedTask;
|
|
|
- }
|
|
|
-
|
|
|
public Task ResetTuner(string id, CancellationToken cancellationToken)
|
|
|
{
|
|
|
return Task.CompletedTask;
|
|
@@ -1076,7 +1073,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
private string GetRecordingPath(TimerInfo timer, RemoteSearchResult metadata, out string seriesPath)
|
|
|
{
|
|
|
var recordPath = RecordingPath;
|
|
|
- var config = GetConfiguration();
|
|
|
+ var config = _config.GetLiveTvConfiguration();
|
|
|
seriesPath = null;
|
|
|
|
|
|
if (timer.IsProgramSeries)
|
|
@@ -1596,7 +1593,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
|
|
|
private void PostProcessRecording(TimerInfo timer, string path)
|
|
|
{
|
|
|
- var options = GetConfiguration();
|
|
|
+ var options = _config.GetLiveTvConfiguration();
|
|
|
if (string.IsNullOrWhiteSpace(options.RecordingPostProcessor))
|
|
|
{
|
|
|
return;
|
|
@@ -1777,7 +1774,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
program.AddGenre("News");
|
|
|
}
|
|
|
|
|
|
- var config = GetConfiguration();
|
|
|
+ var config = _config.GetLiveTvConfiguration();
|
|
|
|
|
|
if (config.SaveRecordingNFO)
|
|
|
{
|
|
@@ -2128,11 +2125,6 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
return _libraryManager.GetItemList(query).Cast<LiveTvProgram>().FirstOrDefault();
|
|
|
}
|
|
|
|
|
|
- private LiveTvOptions GetConfiguration()
|
|
|
- {
|
|
|
- return _config.GetConfiguration<LiveTvOptions>("livetv");
|
|
|
- }
|
|
|
-
|
|
|
private bool ShouldCancelTimerForSeriesTimer(SeriesTimerInfo seriesTimer, TimerInfo timer)
|
|
|
{
|
|
|
if (timer.IsManual)
|
|
@@ -2519,7 +2511,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- var customPath = GetConfiguration().MovieRecordingPath;
|
|
|
+ var customPath = _config.GetLiveTvConfiguration().MovieRecordingPath;
|
|
|
if (!string.IsNullOrWhiteSpace(customPath) && !string.Equals(customPath, defaultFolder, StringComparison.OrdinalIgnoreCase) && Directory.Exists(customPath))
|
|
|
{
|
|
|
yield return new VirtualFolderInfo
|
|
@@ -2530,7 +2522,7 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- customPath = GetConfiguration().SeriesRecordingPath;
|
|
|
+ customPath = _config.GetLiveTvConfiguration().SeriesRecordingPath;
|
|
|
if (!string.IsNullOrWhiteSpace(customPath) && !string.Equals(customPath, defaultFolder, StringComparison.OrdinalIgnoreCase) && Directory.Exists(customPath))
|
|
|
{
|
|
|
yield return new VirtualFolderInfo
|
|
@@ -2541,81 +2533,5 @@ namespace Jellyfin.LiveTv.EmbyTV
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- public async Task<List<TunerHostInfo>> DiscoverTuners(bool newDevicesOnly, CancellationToken cancellationToken)
|
|
|
- {
|
|
|
- var list = new List<TunerHostInfo>();
|
|
|
-
|
|
|
- var configuredDeviceIds = GetConfiguration().TunerHosts
|
|
|
- .Where(i => !string.IsNullOrWhiteSpace(i.DeviceId))
|
|
|
- .Select(i => i.DeviceId)
|
|
|
- .ToList();
|
|
|
-
|
|
|
- foreach (var host in _liveTvManager.TunerHosts)
|
|
|
- {
|
|
|
- var discoveredDevices = await DiscoverDevices(host, TunerDiscoveryDurationMs, cancellationToken).ConfigureAwait(false);
|
|
|
-
|
|
|
- if (newDevicesOnly)
|
|
|
- {
|
|
|
- discoveredDevices = discoveredDevices.Where(d => !configuredDeviceIds.Contains(d.DeviceId, StringComparison.OrdinalIgnoreCase))
|
|
|
- .ToList();
|
|
|
- }
|
|
|
-
|
|
|
- list.AddRange(discoveredDevices);
|
|
|
- }
|
|
|
-
|
|
|
- return list;
|
|
|
- }
|
|
|
-
|
|
|
- public async Task ScanForTunerDeviceChanges(CancellationToken cancellationToken)
|
|
|
- {
|
|
|
- foreach (var host in _liveTvManager.TunerHosts)
|
|
|
- {
|
|
|
- await ScanForTunerDeviceChanges(host, cancellationToken).ConfigureAwait(false);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private async Task ScanForTunerDeviceChanges(ITunerHost host, CancellationToken cancellationToken)
|
|
|
- {
|
|
|
- var discoveredDevices = await DiscoverDevices(host, TunerDiscoveryDurationMs, cancellationToken).ConfigureAwait(false);
|
|
|
-
|
|
|
- var configuredDevices = GetConfiguration().TunerHosts
|
|
|
- .Where(i => string.Equals(i.Type, host.Type, StringComparison.OrdinalIgnoreCase))
|
|
|
- .ToList();
|
|
|
-
|
|
|
- foreach (var device in discoveredDevices)
|
|
|
- {
|
|
|
- var configuredDevice = configuredDevices.FirstOrDefault(i => string.Equals(i.DeviceId, device.DeviceId, StringComparison.OrdinalIgnoreCase));
|
|
|
-
|
|
|
- if (configuredDevice is not null && !string.Equals(device.Url, configuredDevice.Url, StringComparison.OrdinalIgnoreCase))
|
|
|
- {
|
|
|
- _logger.LogInformation("Tuner url has changed from {PreviousUrl} to {NewUrl}", configuredDevice.Url, device.Url);
|
|
|
-
|
|
|
- configuredDevice.Url = device.Url;
|
|
|
- await _liveTvManager.SaveTunerHost(configuredDevice).ConfigureAwait(false);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private async Task<List<TunerHostInfo>> DiscoverDevices(ITunerHost host, int discoveryDurationMs, CancellationToken cancellationToken)
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- var discoveredDevices = await host.DiscoverDevices(discoveryDurationMs, cancellationToken).ConfigureAwait(false);
|
|
|
-
|
|
|
- foreach (var device in discoveredDevices)
|
|
|
- {
|
|
|
- _logger.LogInformation("Discovered tuner device {0} at {1}", host.Name, device.Url);
|
|
|
- }
|
|
|
-
|
|
|
- return discoveredDevices;
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- _logger.LogError(ex, "Error discovering tuner devices");
|
|
|
-
|
|
|
- return new List<TunerHostInfo>();
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
}
|