Use DI for timer managers

pull/11045/head
Patrick Barron 4 months ago
parent ef96b5fa20
commit dfe82a7472

@ -47,21 +47,18 @@ namespace Jellyfin.LiveTv.EmbyTV
private readonly ILogger<EmbyTV> _logger; private readonly ILogger<EmbyTV> _logger;
private readonly IHttpClientFactory _httpClientFactory; private readonly IHttpClientFactory _httpClientFactory;
private readonly IServerConfigurationManager _config; private readonly IServerConfigurationManager _config;
private readonly ItemDataProvider<SeriesTimerInfo> _seriesTimerProvider;
private readonly TimerManager _timerProvider;
private readonly ITunerHostManager _tunerHostManager; private readonly ITunerHostManager _tunerHostManager;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly ILibraryMonitor _libraryMonitor; private readonly ILibraryMonitor _libraryMonitor;
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly IProviderManager _providerManager; private readonly IProviderManager _providerManager;
private readonly IMediaEncoder _mediaEncoder; private readonly IMediaEncoder _mediaEncoder;
private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaSourceManager _mediaSourceManager;
private readonly IStreamHelper _streamHelper; private readonly IStreamHelper _streamHelper;
private readonly LiveTvDtoService _tvDtoService;
private readonly IListingsManager _listingsManager; private readonly IListingsManager _listingsManager;
private readonly LiveTvDtoService _tvDtoService;
private readonly TimerManager _timerManager;
private readonly ItemDataProvider<SeriesTimerInfo> _seriesTimerManager;
private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings = private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings =
new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase); new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase);
@ -82,8 +79,10 @@ namespace Jellyfin.LiveTv.EmbyTV
ILibraryMonitor libraryMonitor, ILibraryMonitor libraryMonitor,
IProviderManager providerManager, IProviderManager providerManager,
IMediaEncoder mediaEncoder, IMediaEncoder mediaEncoder,
IListingsManager listingsManager,
LiveTvDtoService tvDtoService, LiveTvDtoService tvDtoService,
IListingsManager listingsManager) TimerManager timerManager,
SeriesTimerManager seriesTimerManager)
{ {
Current = this; Current = this;
@ -95,16 +94,15 @@ namespace Jellyfin.LiveTv.EmbyTV
_libraryMonitor = libraryMonitor; _libraryMonitor = libraryMonitor;
_providerManager = providerManager; _providerManager = providerManager;
_mediaEncoder = mediaEncoder; _mediaEncoder = mediaEncoder;
_tvDtoService = tvDtoService;
_tunerHostManager = tunerHostManager; _tunerHostManager = tunerHostManager;
_mediaSourceManager = mediaSourceManager; _mediaSourceManager = mediaSourceManager;
_streamHelper = streamHelper; _streamHelper = streamHelper;
_listingsManager = listingsManager; _listingsManager = listingsManager;
_tvDtoService = tvDtoService;
_timerManager = timerManager;
_seriesTimerManager = seriesTimerManager;
_seriesTimerProvider = new SeriesTimerManager(_logger, Path.Combine(DataPath, "seriestimers.json")); _timerManager.TimerFired += OnTimerManagerTimerFired;
_timerProvider = new TimerManager(_logger, Path.Combine(DataPath, "timers.json"));
_timerProvider.TimerFired += OnTimerProviderTimerFired;
_config.NamedConfigurationUpdated += OnNamedConfigurationUpdated; _config.NamedConfigurationUpdated += OnNamedConfigurationUpdated;
} }
@ -146,7 +144,7 @@ namespace Jellyfin.LiveTv.EmbyTV
public Task Start() public Task Start()
{ {
_timerProvider.RestartTimers(); _timerManager.RestartTimers();
return CreateRecordingFolders(); return CreateRecordingFolders();
} }
@ -298,13 +296,13 @@ namespace Jellyfin.LiveTv.EmbyTV
} }
CopyProgramInfoToTimerInfo(program, timer, tempChannelCache); CopyProgramInfoToTimerInfo(program, timer, tempChannelCache);
_timerProvider.Update(timer); _timerManager.Update(timer);
} }
} }
private void OnTimerOutOfDate(TimerInfo timer) private void OnTimerOutOfDate(TimerInfo timer)
{ {
_timerProvider.Delete(timer); _timerManager.Delete(timer);
} }
private async Task<IEnumerable<ChannelInfo>> GetChannelsAsync(bool enableCache, CancellationToken cancellationToken) private async Task<IEnumerable<ChannelInfo>> GetChannelsAsync(bool enableCache, CancellationToken cancellationToken)
@ -337,7 +335,7 @@ namespace Jellyfin.LiveTv.EmbyTV
public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken) public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken)
{ {
var timers = _timerProvider var timers = _timerManager
.GetAll() .GetAll()
.Where(i => string.Equals(i.SeriesTimerId, timerId, StringComparison.OrdinalIgnoreCase)) .Where(i => string.Equals(i.SeriesTimerId, timerId, StringComparison.OrdinalIgnoreCase))
.ToList(); .ToList();
@ -347,10 +345,10 @@ namespace Jellyfin.LiveTv.EmbyTV
CancelTimerInternal(timer.Id, true, true); CancelTimerInternal(timer.Id, true, true);
} }
var remove = _seriesTimerProvider.GetAll().FirstOrDefault(r => string.Equals(r.Id, timerId, StringComparison.OrdinalIgnoreCase)); var remove = _seriesTimerManager.GetAll().FirstOrDefault(r => string.Equals(r.Id, timerId, StringComparison.OrdinalIgnoreCase));
if (remove is not null) if (remove is not null)
{ {
_seriesTimerProvider.Delete(remove); _seriesTimerManager.Delete(remove);
} }
return Task.CompletedTask; return Task.CompletedTask;
@ -358,7 +356,7 @@ namespace Jellyfin.LiveTv.EmbyTV
private void CancelTimerInternal(string timerId, bool isSeriesCancelled, bool isManualCancellation) private void CancelTimerInternal(string timerId, bool isSeriesCancelled, bool isManualCancellation)
{ {
var timer = _timerProvider.GetTimer(timerId); var timer = _timerManager.GetTimer(timerId);
if (timer is not null) if (timer is not null)
{ {
var statusChanging = timer.Status != RecordingStatus.Cancelled; var statusChanging = timer.Status != RecordingStatus.Cancelled;
@ -371,11 +369,11 @@ namespace Jellyfin.LiveTv.EmbyTV
if (string.IsNullOrWhiteSpace(timer.SeriesTimerId) || isSeriesCancelled) if (string.IsNullOrWhiteSpace(timer.SeriesTimerId) || isSeriesCancelled)
{ {
_timerProvider.Delete(timer); _timerManager.Delete(timer);
} }
else else
{ {
_timerProvider.AddOrUpdate(timer, false); _timerManager.AddOrUpdate(timer, false);
} }
if (statusChanging && TimerCancelled is not null) if (statusChanging && TimerCancelled is not null)
@ -411,7 +409,7 @@ namespace Jellyfin.LiveTv.EmbyTV
{ {
var existingTimer = string.IsNullOrWhiteSpace(info.ProgramId) ? var existingTimer = string.IsNullOrWhiteSpace(info.ProgramId) ?
null : null :
_timerProvider.GetTimerByProgramId(info.ProgramId); _timerManager.GetTimerByProgramId(info.ProgramId);
if (existingTimer is not null) if (existingTimer is not null)
{ {
@ -420,7 +418,7 @@ namespace Jellyfin.LiveTv.EmbyTV
{ {
existingTimer.Status = RecordingStatus.New; existingTimer.Status = RecordingStatus.New;
existingTimer.IsManual = true; existingTimer.IsManual = true;
_timerProvider.Update(existingTimer); _timerManager.Update(existingTimer);
return Task.FromResult(existingTimer.Id); return Task.FromResult(existingTimer.Id);
} }
@ -448,7 +446,7 @@ namespace Jellyfin.LiveTv.EmbyTV
} }
info.IsManual = true; info.IsManual = true;
_timerProvider.Add(info); _timerManager.Add(info);
TimerCreated?.Invoke(this, new GenericEventArgs<TimerInfo>(info)); TimerCreated?.Invoke(this, new GenericEventArgs<TimerInfo>(info));
@ -489,14 +487,14 @@ namespace Jellyfin.LiveTv.EmbyTV
}) })
.ToList(); .ToList();
_seriesTimerProvider.Add(info); _seriesTimerManager.Add(info);
foreach (var timer in existingTimers) foreach (var timer in existingTimers)
{ {
timer.SeriesTimerId = info.Id; timer.SeriesTimerId = info.Id;
timer.IsManual = true; timer.IsManual = true;
_timerProvider.AddOrUpdate(timer, false); _timerManager.AddOrUpdate(timer, false);
} }
UpdateTimersForSeriesTimer(info, true, false); UpdateTimersForSeriesTimer(info, true, false);
@ -506,7 +504,7 @@ namespace Jellyfin.LiveTv.EmbyTV
public Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken) public Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken)
{ {
var instance = _seriesTimerProvider.GetAll().FirstOrDefault(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase)); var instance = _seriesTimerManager.GetAll().FirstOrDefault(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));
if (instance is not null) if (instance is not null)
{ {
@ -526,7 +524,7 @@ namespace Jellyfin.LiveTv.EmbyTV
instance.KeepUntil = info.KeepUntil; instance.KeepUntil = info.KeepUntil;
instance.StartDate = info.StartDate; instance.StartDate = info.StartDate;
_seriesTimerProvider.Update(instance); _seriesTimerManager.Update(instance);
UpdateTimersForSeriesTimer(instance, true, true); UpdateTimersForSeriesTimer(instance, true, true);
} }
@ -536,7 +534,7 @@ namespace Jellyfin.LiveTv.EmbyTV
public Task UpdateTimerAsync(TimerInfo updatedTimer, CancellationToken cancellationToken) public Task UpdateTimerAsync(TimerInfo updatedTimer, CancellationToken cancellationToken)
{ {
var existingTimer = _timerProvider.GetTimer(updatedTimer.Id); var existingTimer = _timerManager.GetTimer(updatedTimer.Id);
if (existingTimer is null) if (existingTimer is null)
{ {
@ -551,7 +549,7 @@ namespace Jellyfin.LiveTv.EmbyTV
existingTimer.IsPostPaddingRequired = updatedTimer.IsPostPaddingRequired; existingTimer.IsPostPaddingRequired = updatedTimer.IsPostPaddingRequired;
existingTimer.IsPrePaddingRequired = updatedTimer.IsPrePaddingRequired; existingTimer.IsPrePaddingRequired = updatedTimer.IsPrePaddingRequired;
_timerProvider.Update(existingTimer); _timerManager.Update(existingTimer);
} }
return Task.CompletedTask; return Task.CompletedTask;
@ -625,7 +623,7 @@ namespace Jellyfin.LiveTv.EmbyTV
RecordingStatus.Completed RecordingStatus.Completed
}; };
var timers = _timerProvider.GetAll() var timers = _timerManager.GetAll()
.Where(i => !excludeStatues.Contains(i.Status)); .Where(i => !excludeStatues.Contains(i.Status));
return Task.FromResult(timers); return Task.FromResult(timers);
@ -671,7 +669,7 @@ namespace Jellyfin.LiveTv.EmbyTV
public Task<IEnumerable<SeriesTimerInfo>> GetSeriesTimersAsync(CancellationToken cancellationToken) public Task<IEnumerable<SeriesTimerInfo>> GetSeriesTimersAsync(CancellationToken cancellationToken)
{ {
return Task.FromResult((IEnumerable<SeriesTimerInfo>)_seriesTimerProvider.GetAll()); return Task.FromResult((IEnumerable<SeriesTimerInfo>)_seriesTimerManager.GetAll());
} }
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
@ -766,7 +764,7 @@ namespace Jellyfin.LiveTv.EmbyTV
return Task.CompletedTask; return Task.CompletedTask;
} }
private async void OnTimerProviderTimerFired(object sender, GenericEventArgs<TimerInfo> e) private async void OnTimerManagerTimerFired(object sender, GenericEventArgs<TimerInfo> e)
{ {
var timer = e.Argument; var timer = e.Argument;
@ -996,7 +994,7 @@ namespace Jellyfin.LiveTv.EmbyTV
_activeRecordings.TryAdd(timer.Id, activeRecordingInfo); _activeRecordings.TryAdd(timer.Id, activeRecordingInfo);
timer.Status = RecordingStatus.InProgress; timer.Status = RecordingStatus.InProgress;
_timerProvider.AddOrUpdate(timer, false); _timerManager.AddOrUpdate(timer, false);
await SaveRecordingMetadata(timer, recordPath, seriesPath).ConfigureAwait(false); await SaveRecordingMetadata(timer, recordPath, seriesPath).ConfigureAwait(false);
@ -1050,18 +1048,18 @@ namespace Jellyfin.LiveTv.EmbyTV
timer.PrePaddingSeconds = 0; timer.PrePaddingSeconds = 0;
timer.StartDate = DateTime.UtcNow.AddSeconds(RetryIntervalSeconds); timer.StartDate = DateTime.UtcNow.AddSeconds(RetryIntervalSeconds);
timer.RetryCount++; timer.RetryCount++;
_timerProvider.AddOrUpdate(timer); _timerManager.AddOrUpdate(timer);
} }
else if (File.Exists(recordPath)) else if (File.Exists(recordPath))
{ {
timer.RecordingPath = recordPath; timer.RecordingPath = recordPath;
timer.Status = RecordingStatus.Completed; timer.Status = RecordingStatus.Completed;
_timerProvider.AddOrUpdate(timer, false); _timerManager.AddOrUpdate(timer, false);
OnSuccessfulRecording(timer, recordPath); OnSuccessfulRecording(timer, recordPath);
} }
else else
{ {
_timerProvider.Delete(timer); _timerManager.Delete(timer);
} }
} }
@ -1176,7 +1174,7 @@ namespace Jellyfin.LiveTv.EmbyTV
} }
var seriesTimerId = timer.SeriesTimerId; var seriesTimerId = timer.SeriesTimerId;
var seriesTimer = _seriesTimerProvider.GetAll().FirstOrDefault(i => string.Equals(i.Id, seriesTimerId, StringComparison.OrdinalIgnoreCase)); var seriesTimer = _seriesTimerManager.GetAll().FirstOrDefault(i => string.Equals(i.Id, seriesTimerId, StringComparison.OrdinalIgnoreCase));
if (seriesTimer is null || seriesTimer.KeepUpTo <= 0) if (seriesTimer is null || seriesTimer.KeepUpTo <= 0)
{ {
@ -1195,7 +1193,7 @@ namespace Jellyfin.LiveTv.EmbyTV
return; return;
} }
var timersToDelete = _timerProvider.GetAll() var timersToDelete = _timerManager.GetAll()
.Where(i => i.Status == RecordingStatus.Completed && !string.IsNullOrWhiteSpace(i.RecordingPath)) .Where(i => i.Status == RecordingStatus.Completed && !string.IsNullOrWhiteSpace(i.RecordingPath))
.Where(i => string.Equals(i.SeriesTimerId, seriesTimerId, StringComparison.OrdinalIgnoreCase)) .Where(i => string.Equals(i.SeriesTimerId, seriesTimerId, StringComparison.OrdinalIgnoreCase))
.OrderByDescending(i => i.EndDate) .OrderByDescending(i => i.EndDate)
@ -1282,7 +1280,7 @@ namespace Jellyfin.LiveTv.EmbyTV
_fileSystem.DeleteFile(timer.RecordingPath); _fileSystem.DeleteFile(timer.RecordingPath);
} }
_timerProvider.Delete(timer); _timerManager.Delete(timer);
} }
private string EnsureFileUnique(string path, string timerId) private string EnsureFileUnique(string path, string timerId)
@ -1896,7 +1894,7 @@ namespace Jellyfin.LiveTv.EmbyTV
foreach (var timer in timers.OrderByDescending(t => GetLiveTvChannel(t).IsHD).ThenBy(t => t.StartDate).Skip(1)) foreach (var timer in timers.OrderByDescending(t => GetLiveTvChannel(t).IsHD).ThenBy(t => t.StartDate).Skip(1))
{ {
timer.Status = RecordingStatus.Cancelled; timer.Status = RecordingStatus.Cancelled;
_timerProvider.Update(timer); _timerManager.Update(timer);
} }
} }
@ -1935,10 +1933,10 @@ namespace Jellyfin.LiveTv.EmbyTV
var enabledTimersForSeries = new List<TimerInfo>(); var enabledTimersForSeries = new List<TimerInfo>();
foreach (var timer in allTimers) foreach (var timer in allTimers)
{ {
var existingTimer = _timerProvider.GetTimer(timer.Id) var existingTimer = _timerManager.GetTimer(timer.Id)
?? (string.IsNullOrWhiteSpace(timer.ProgramId) ?? (string.IsNullOrWhiteSpace(timer.ProgramId)
? null ? null
: _timerProvider.GetTimerByProgramId(timer.ProgramId)); : _timerManager.GetTimerByProgramId(timer.ProgramId));
if (existingTimer is null) if (existingTimer is null)
{ {
@ -1951,7 +1949,7 @@ namespace Jellyfin.LiveTv.EmbyTV
enabledTimersForSeries.Add(timer); enabledTimersForSeries.Add(timer);
} }
_timerProvider.Add(timer); _timerManager.Add(timer);
TimerCreated?.Invoke(this, new GenericEventArgs<TimerInfo>(timer)); TimerCreated?.Invoke(this, new GenericEventArgs<TimerInfo>(timer));
} }
@ -1991,7 +1989,7 @@ namespace Jellyfin.LiveTv.EmbyTV
} }
existingTimer.SeriesTimerId = seriesTimer.Id; existingTimer.SeriesTimerId = seriesTimer.Id;
_timerProvider.Update(existingTimer); _timerManager.Update(existingTimer);
} }
} }
@ -2008,7 +2006,7 @@ namespace Jellyfin.LiveTv.EmbyTV
RecordingStatus.New RecordingStatus.New
}; };
var deletes = _timerProvider.GetAll() var deletes = _timerManager.GetAll()
.Where(i => string.Equals(i.SeriesTimerId, seriesTimer.Id, StringComparison.OrdinalIgnoreCase)) .Where(i => string.Equals(i.SeriesTimerId, seriesTimer.Id, StringComparison.OrdinalIgnoreCase))
.Where(i => !allTimerIds.Contains(i.Id, StringComparison.OrdinalIgnoreCase) && i.StartDate > DateTime.UtcNow) .Where(i => !allTimerIds.Contains(i.Id, StringComparison.OrdinalIgnoreCase) && i.StartDate > DateTime.UtcNow)
.Where(i => deleteStatuses.Contains(i.Status)) .Where(i => deleteStatuses.Contains(i.Status))

@ -1,6 +1,8 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
using System; using System;
using System.IO;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.LiveTv;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -8,8 +10,11 @@ namespace Jellyfin.LiveTv.EmbyTV
{ {
public class SeriesTimerManager : ItemDataProvider<SeriesTimerInfo> public class SeriesTimerManager : ItemDataProvider<SeriesTimerInfo>
{ {
public SeriesTimerManager(ILogger logger, string dataPath) public SeriesTimerManager(ILogger<SeriesTimerManager> logger, IConfigurationManager config)
: base(logger, dataPath, (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase)) : base(
logger,
Path.Combine(config.CommonApplicationPaths.DataPath, "livetv/seriestimers.json"),
(r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase))
{ {
} }

@ -3,9 +3,11 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Globalization; using System.Globalization;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using Jellyfin.Data.Events; using Jellyfin.Data.Events;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.LiveTv;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -14,10 +16,13 @@ namespace Jellyfin.LiveTv.EmbyTV
{ {
public class TimerManager : ItemDataProvider<TimerInfo> public class TimerManager : ItemDataProvider<TimerInfo>
{ {
private readonly ConcurrentDictionary<string, Timer> _timers = new ConcurrentDictionary<string, Timer>(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary<string, Timer> _timers = new(StringComparer.OrdinalIgnoreCase);
public TimerManager(ILogger logger, string dataPath) public TimerManager(ILogger<TimerManager> logger, IConfigurationManager config)
: base(logger, dataPath, (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase)) : base(
logger,
Path.Combine(config.CommonApplicationPaths.DataPath, "livetv"),
(r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase))
{ {
} }
@ -80,22 +85,11 @@ namespace Jellyfin.LiveTv.EmbyTV
AddOrUpdateSystemTimer(item); AddOrUpdateSystemTimer(item);
} }
private static bool ShouldStartTimer(TimerInfo item)
{
if (item.Status == RecordingStatus.Completed
|| item.Status == RecordingStatus.Cancelled)
{
return false;
}
return true;
}
private void AddOrUpdateSystemTimer(TimerInfo item) private void AddOrUpdateSystemTimer(TimerInfo item)
{ {
StopTimer(item); StopTimer(item);
if (!ShouldStartTimer(item)) if (item.Status is RecordingStatus.Completed or RecordingStatus.Cancelled)
{ {
return; return;
} }
@ -169,13 +163,9 @@ namespace Jellyfin.LiveTv.EmbyTV
} }
public TimerInfo? GetTimer(string id) public TimerInfo? GetTimer(string id)
{ => GetAll().FirstOrDefault(r => string.Equals(r.Id, id, StringComparison.OrdinalIgnoreCase));
return GetAll().FirstOrDefault(r => string.Equals(r.Id, id, StringComparison.OrdinalIgnoreCase));
}
public TimerInfo? GetTimerByProgramId(string programId) public TimerInfo? GetTimerByProgramId(string programId)
{ => GetAll().FirstOrDefault(r => string.Equals(r.ProgramId, programId, StringComparison.OrdinalIgnoreCase));
return GetAll().FirstOrDefault(r => string.Equals(r.ProgramId, programId, StringComparison.OrdinalIgnoreCase));
}
} }
} }

@ -1,4 +1,5 @@
using Jellyfin.LiveTv.Channels; using Jellyfin.LiveTv.Channels;
using Jellyfin.LiveTv.EmbyTV;
using Jellyfin.LiveTv.Guide; using Jellyfin.LiveTv.Guide;
using Jellyfin.LiveTv.Listings; using Jellyfin.LiveTv.Listings;
using Jellyfin.LiveTv.TunerHosts; using Jellyfin.LiveTv.TunerHosts;
@ -22,6 +23,8 @@ public static class LiveTvServiceCollectionExtensions
public static void AddLiveTvServices(this IServiceCollection services) public static void AddLiveTvServices(this IServiceCollection services)
{ {
services.AddSingleton<LiveTvDtoService>(); services.AddSingleton<LiveTvDtoService>();
services.AddSingleton<TimerManager>();
services.AddSingleton<SeriesTimerManager>();
services.AddSingleton<ILiveTvManager, LiveTvManager>(); services.AddSingleton<ILiveTvManager, LiveTvManager>();
services.AddSingleton<IChannelManager, ChannelManager>(); services.AddSingleton<IChannelManager, ChannelManager>();
services.AddSingleton<IStreamHelper, StreamHelper>(); services.AddSingleton<IStreamHelper, StreamHelper>();

Loading…
Cancel
Save