From 9809c609249188cfdf876ab9f53981bd8ec24044 Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Mon, 5 Apr 2021 16:06:13 -0500 Subject: [PATCH] send all audio streams on hls channels with no preferred language (#142) * Revert "fix search index threading (#141)" This reverts commit 3fb6da0754e72aa844065bba5c7d814eed7bd3bc. * send all audio streams on hls channels with no preferred language --- .../ISearchBackgroundServiceRequest.cs | 6 -- .../Commands/ScanLocalLibraryHandler.cs | 26 ++------ .../SynchronizePlexLibraryByIdHandler.cs | 22 +------ .../Search/Commands/AddItemsToSearchIndex.cs | 9 --- .../Commands/AddItemsToSearchIndexHandler.cs | 17 ------ .../Search/Commands/RebuildSearchIndex.cs | 2 +- .../Commands/RemoveItemsFromSearchIndex.cs | 8 --- .../RemoveItemsFromSearchIndexHandler.cs | 17 ------ .../Metadata/MovieFolderScannerTests.cs | 59 +++++------------- .../FFmpeg/FFmpegComplexFilterBuilder.cs | 4 +- .../FFmpegPlaybackSettingsCalculator.cs | 15 +++-- ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs | 9 ++- ErsatzTV.Core/FFmpeg/FFmpegProcessService.cs | 12 ++-- ErsatzTV.Core/FFmpeg/FFmpegStreamSelector.cs | 12 +++- .../FFmpeg/IFFmpegStreamSelector.cs | 3 +- .../Metadata/IMovieFolderScanner.cs | 5 +- .../Metadata/IMusicVideoFolderScanner.cs | 5 +- .../Metadata/ITelevisionFolderScanner.cs | 5 +- .../Plex/IPlexMovieLibraryScanner.cs | 8 +-- .../Plex/IPlexTelevisionLibraryScanner.cs | 8 +-- ErsatzTV.Core/Metadata/MovieFolderScanner.cs | 22 +++++-- .../Metadata/MusicVideoFolderScanner.cs | 22 +++++-- .../Metadata/TelevisionFolderScanner.cs | 20 ++++-- ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs | 25 +++++--- .../Plex/PlexTelevisionLibraryScanner.cs | 23 ++++--- ErsatzTV/Pages/Movie.razor | 2 +- ErsatzTV/Pages/MovieList.razor | 5 +- ErsatzTV/Pages/MusicVideoList.razor | 5 +- ErsatzTV/Pages/TelevisionEpisodeList.razor | 2 +- ErsatzTV/Pages/TelevisionSeasonList.razor | 2 +- ErsatzTV/Pages/TelevisionShowList.razor | 5 +- ErsatzTV/Services/SchedulerService.cs | 5 +- ErsatzTV/Services/SearchIndexService.cs | 61 ------------------- ErsatzTV/Shared/FragmentLetterAnchor.razor | 5 +- ErsatzTV/Startup.cs | 1 - 35 files changed, 159 insertions(+), 298 deletions(-) delete mode 100644 ErsatzTV.Application/ISearchBackgroundServiceRequest.cs delete mode 100644 ErsatzTV.Application/Search/Commands/AddItemsToSearchIndex.cs delete mode 100644 ErsatzTV.Application/Search/Commands/AddItemsToSearchIndexHandler.cs delete mode 100644 ErsatzTV.Application/Search/Commands/RemoveItemsFromSearchIndex.cs delete mode 100644 ErsatzTV.Application/Search/Commands/RemoveItemsFromSearchIndexHandler.cs delete mode 100644 ErsatzTV/Services/SearchIndexService.cs diff --git a/ErsatzTV.Application/ISearchBackgroundServiceRequest.cs b/ErsatzTV.Application/ISearchBackgroundServiceRequest.cs deleted file mode 100644 index 52bccad75..000000000 --- a/ErsatzTV.Application/ISearchBackgroundServiceRequest.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ErsatzTV.Application -{ - public interface ISearchBackgroundServiceRequest - { - } -} diff --git a/ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs b/ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs index 543add0b3..f58a10790 100644 --- a/ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs +++ b/ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs @@ -1,11 +1,8 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading; -using System.Threading.Channels; using System.Threading.Tasks; -using ErsatzTV.Application.Search.Commands; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Locking; @@ -29,7 +26,6 @@ namespace ErsatzTV.Application.MediaSources.Commands private readonly IMediator _mediator; private readonly IMovieFolderScanner _movieFolderScanner; private readonly IMusicVideoFolderScanner _musicVideoFolderScanner; - private readonly ChannelWriter _searchChannel; private readonly ITelevisionFolderScanner _televisionFolderScanner; public ScanLocalLibraryHandler( @@ -40,8 +36,7 @@ namespace ErsatzTV.Application.MediaSources.Commands IMusicVideoFolderScanner musicVideoFolderScanner, IEntityLocker entityLocker, IMediator mediator, - ILogger logger, - ChannelWriter searchChannel) + ILogger logger) { _libraryRepository = libraryRepository; _configElementRepository = configElementRepository; @@ -51,7 +46,6 @@ namespace ErsatzTV.Application.MediaSources.Commands _entityLocker = entityLocker; _mediator = mediator; _logger = logger; - _searchChannel = searchChannel; } public Task> Handle( @@ -93,9 +87,7 @@ namespace ErsatzTV.Application.MediaSources.Commands ffprobePath, lastScan, progressMin, - progressMax, - AddToSearchIndex, - RemoveFromSearchIndex); + progressMax); break; case LibraryMediaKind.Shows: await _televisionFolderScanner.ScanFolder( @@ -103,9 +95,7 @@ namespace ErsatzTV.Application.MediaSources.Commands ffprobePath, lastScan, progressMin, - progressMax, - AddToSearchIndex, - RemoveFromSearchIndex); + progressMax); break; case LibraryMediaKind.MusicVideos: await _musicVideoFolderScanner.ScanFolder( @@ -113,9 +103,7 @@ namespace ErsatzTV.Application.MediaSources.Commands ffprobePath, lastScan, progressMin, - progressMax, - AddToSearchIndex, - RemoveFromSearchIndex); + progressMax); break; } @@ -138,12 +126,6 @@ namespace ErsatzTV.Application.MediaSources.Commands return Unit.Default; } - private ValueTask AddToSearchIndex(List mediaItems) => - _searchChannel.WriteAsync(new AddItemsToSearchIndex(mediaItems)); - - private ValueTask RemoveFromSearchIndex(List mediaItemIds) => - _searchChannel.WriteAsync(new RemoveItemsFromSearchIndex(mediaItemIds)); - private async Task> Validate(IScanLocalLibrary request) => (await LocalLibraryMustExist(request), await ValidateFFprobePath()) .Apply( diff --git a/ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs b/ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs index 90b8401cb..ca98b9090 100644 --- a/ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs +++ b/ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs @@ -1,10 +1,7 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading; -using System.Threading.Channels; using System.Threading.Tasks; -using ErsatzTV.Application.Search.Commands; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Locking; @@ -29,7 +26,6 @@ namespace ErsatzTV.Application.Plex.Commands private readonly IPlexMovieLibraryScanner _plexMovieLibraryScanner; private readonly IPlexSecretStore _plexSecretStore; private readonly IPlexTelevisionLibraryScanner _plexTelevisionLibraryScanner; - private readonly ChannelWriter _searchChannel; public SynchronizePlexLibraryByIdHandler( IMediaSourceRepository mediaSourceRepository, @@ -38,8 +34,7 @@ namespace ErsatzTV.Application.Plex.Commands IPlexTelevisionLibraryScanner plexTelevisionLibraryScanner, ILibraryRepository libraryRepository, IEntityLocker entityLocker, - ILogger logger, - ChannelWriter searchChannel) + ILogger logger) { _mediaSourceRepository = mediaSourceRepository; _plexSecretStore = plexSecretStore; @@ -48,7 +43,6 @@ namespace ErsatzTV.Application.Plex.Commands _libraryRepository = libraryRepository; _entityLocker = entityLocker; _logger = logger; - _searchChannel = searchChannel; } public Task> Handle( @@ -76,17 +70,13 @@ namespace ErsatzTV.Application.Plex.Commands await _plexMovieLibraryScanner.ScanLibrary( parameters.ConnectionParameters.ActiveConnection, parameters.ConnectionParameters.PlexServerAuthToken, - parameters.Library, - AddToSearchIndex, - RemoveFromSearchIndex); + parameters.Library); break; case LibraryMediaKind.Shows: await _plexTelevisionLibraryScanner.ScanLibrary( parameters.ConnectionParameters.ActiveConnection, parameters.ConnectionParameters.PlexServerAuthToken, - parameters.Library, - AddToSearchIndex, - RemoveFromSearchIndex); + parameters.Library); break; } @@ -104,12 +94,6 @@ namespace ErsatzTV.Application.Plex.Commands return Unit.Default; } - private ValueTask AddToSearchIndex(List mediaItems) => - _searchChannel.WriteAsync(new AddItemsToSearchIndex(mediaItems)); - - private ValueTask RemoveFromSearchIndex(List mediaItemIds) => - _searchChannel.WriteAsync(new RemoveItemsFromSearchIndex(mediaItemIds)); - private async Task> Validate(ISynchronizePlexLibraryById request) => (await ValidateConnection(request), await PlexLibraryMustExist(request)) .Apply( diff --git a/ErsatzTV.Application/Search/Commands/AddItemsToSearchIndex.cs b/ErsatzTV.Application/Search/Commands/AddItemsToSearchIndex.cs deleted file mode 100644 index 0ee5dbcf8..000000000 --- a/ErsatzTV.Application/Search/Commands/AddItemsToSearchIndex.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; -using ErsatzTV.Core.Domain; -using LanguageExt; - -namespace ErsatzTV.Application.Search.Commands -{ - public record AddItemsToSearchIndex(List MediaItems) : MediatR.IRequest, - ISearchBackgroundServiceRequest; -} diff --git a/ErsatzTV.Application/Search/Commands/AddItemsToSearchIndexHandler.cs b/ErsatzTV.Application/Search/Commands/AddItemsToSearchIndexHandler.cs deleted file mode 100644 index cebbe509a..000000000 --- a/ErsatzTV.Application/Search/Commands/AddItemsToSearchIndexHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using ErsatzTV.Core.Interfaces.Search; -using LanguageExt; - -namespace ErsatzTV.Application.Search.Commands -{ - public class AddItemsToSearchIndexHandler : MediatR.IRequestHandler - { - private readonly ISearchIndex _searchIndex; - - public AddItemsToSearchIndexHandler(ISearchIndex searchIndex) => _searchIndex = searchIndex; - - public Task Handle(AddItemsToSearchIndex request, CancellationToken cancellationToken) => - _searchIndex.AddItems(request.MediaItems); - } -} diff --git a/ErsatzTV.Application/Search/Commands/RebuildSearchIndex.cs b/ErsatzTV.Application/Search/Commands/RebuildSearchIndex.cs index 6b05213f9..7eafb3e17 100644 --- a/ErsatzTV.Application/Search/Commands/RebuildSearchIndex.cs +++ b/ErsatzTV.Application/Search/Commands/RebuildSearchIndex.cs @@ -2,5 +2,5 @@ namespace ErsatzTV.Application.Search.Commands { - public record RebuildSearchIndex : MediatR.IRequest, ISearchBackgroundServiceRequest; + public record RebuildSearchIndex : MediatR.IRequest, IBackgroundServiceRequest; } diff --git a/ErsatzTV.Application/Search/Commands/RemoveItemsFromSearchIndex.cs b/ErsatzTV.Application/Search/Commands/RemoveItemsFromSearchIndex.cs deleted file mode 100644 index df010c7e7..000000000 --- a/ErsatzTV.Application/Search/Commands/RemoveItemsFromSearchIndex.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Collections.Generic; -using LanguageExt; - -namespace ErsatzTV.Application.Search.Commands -{ - public record RemoveItemsFromSearchIndex(List MediaItemIds) : MediatR.IRequest, - ISearchBackgroundServiceRequest; -} diff --git a/ErsatzTV.Application/Search/Commands/RemoveItemsFromSearchIndexHandler.cs b/ErsatzTV.Application/Search/Commands/RemoveItemsFromSearchIndexHandler.cs deleted file mode 100644 index dd24ccebd..000000000 --- a/ErsatzTV.Application/Search/Commands/RemoveItemsFromSearchIndexHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using ErsatzTV.Core.Interfaces.Search; -using LanguageExt; - -namespace ErsatzTV.Application.Search.Commands -{ - public class RemoveItemsFromSearchIndexHandler : MediatR.IRequestHandler - { - private readonly ISearchIndex _searchIndex; - - public RemoveItemsFromSearchIndexHandler(ISearchIndex searchIndex) => _searchIndex = searchIndex; - - public Task Handle(RemoveItemsFromSearchIndex request, CancellationToken cancellationToken) => - _searchIndex.RemoveItems(request.MediaItemIds); - } -} diff --git a/ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs b/ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs index 77fd2d239..60856949d 100644 --- a/ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs +++ b/ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs @@ -9,6 +9,7 @@ using ErsatzTV.Core.Errors; using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Repositories; +using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Metadata; using ErsatzTV.Core.Tests.Fakes; using FluentAssertions; @@ -87,9 +88,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); + 1); result.IsLeft.Should().BeTrue(); result.IfLeft(error => error.Should().BeOfType()); @@ -114,9 +113,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); + 1); result.IsRight.Should().BeTrue(); @@ -157,10 +154,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); - + 1); result.IsRight.Should().BeTrue(); @@ -202,10 +196,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); - + 1); result.IsRight.Should().BeTrue(); @@ -251,10 +242,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); - + 1); result.IsRight.Should().BeTrue(); @@ -303,10 +291,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); - + 1); result.IsRight.Should().BeTrue(); @@ -355,10 +340,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); - + 1); result.IsRight.Should().BeTrue(); @@ -406,10 +388,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); - + 1); result.IsRight.Should().BeTrue(); @@ -453,10 +432,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); - + 1); result.IsRight.Should().BeTrue(); @@ -494,10 +470,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); - + 1); result.IsRight.Should().BeTrue(); @@ -537,9 +510,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); + 1); result.IsRight.Should().BeTrue(); @@ -568,10 +539,7 @@ namespace ErsatzTV.Core.Tests.Metadata FFprobePath, DateTimeOffset.MinValue, 0, - 1, - _ => ValueTask.CompletedTask, - _ => ValueTask.CompletedTask); - + 1); result.IsRight.Should().BeTrue(); @@ -588,6 +556,7 @@ namespace ErsatzTV.Core.Tests.Metadata _localMetadataProvider.Object, new Mock().Object, _imageCache.Object, + new Mock().Object, new Mock().Object, new Mock>().Object ); diff --git a/ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs b/ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs index 27da5c74c..89ae37382 100644 --- a/ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs +++ b/ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs @@ -68,12 +68,12 @@ namespace ErsatzTV.Core.FFmpeg return this; } - public Option Build(int videoStreamIndex, int audioStreamIndex) + public Option Build(int videoStreamIndex, Option audioStreamIndex) { var complexFilter = new StringBuilder(); var videoLabel = $"0:{videoStreamIndex}"; - var audioLabel = $"0:{audioStreamIndex}"; + string audioLabel = audioStreamIndex.Match(index => $"0:{index}", () => "0:a"); HardwareAccelerationKind acceleration = _hardwareAccelerationKind.IfNone(HardwareAccelerationKind.None); bool isHardwareDecode = acceleration switch diff --git a/ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettingsCalculator.cs b/ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettingsCalculator.cs index 533bd0e79..230186b20 100644 --- a/ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettingsCalculator.cs +++ b/ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettingsCalculator.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.FFmpeg; +using LanguageExt; using static LanguageExt.Prelude; namespace ErsatzTV.Core.FFmpeg @@ -46,7 +47,7 @@ namespace ErsatzTV.Core.FFmpeg FFmpegProfile ffmpegProfile, MediaVersion version, MediaStream videoStream, - MediaStream audioStream, + Option audioStream, DateTimeOffset start, DateTimeOffset now) { @@ -113,10 +114,14 @@ namespace ErsatzTV.Core.FFmpeg result.AudioBitrate = ffmpegProfile.AudioBitrate; result.AudioBufferSize = ffmpegProfile.AudioBufferSize; - if (audioStream.Channels != ffmpegProfile.AudioChannels) - { - result.AudioChannels = ffmpegProfile.AudioChannels; - } + audioStream.IfSome( + stream => + { + if (stream.Channels != ffmpegProfile.AudioChannels) + { + result.AudioChannels = ffmpegProfile.AudioChannels; + } + }); result.AudioSampleRate = ffmpegProfile.AudioSampleRate; result.AudioDuration = version.Duration; diff --git a/ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs b/ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs index f6daf5ec8..629c1163f 100644 --- a/ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs +++ b/ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs @@ -354,12 +354,15 @@ namespace ErsatzTV.Core.FFmpeg return this; } - public FFmpegProcessBuilder WithFilterComplex(int videoStreamIndex, int audioStreamIndex) + public FFmpegProcessBuilder WithFilterComplex(MediaStream videoStream, Option maybeAudioStream) { + int videoStreamIndex = videoStream.Index; + Option maybeIndex = maybeAudioStream.Map(ms => ms.Index); + var videoLabel = $"0:{videoStreamIndex}"; - var audioLabel = $"0:{audioStreamIndex}"; + var audioLabel = $"0:{maybeIndex.Match(i => i.ToString(), () => "a")}"; - Option maybeFilter = _complexFilterBuilder.Build(videoStreamIndex, audioStreamIndex); + Option maybeFilter = _complexFilterBuilder.Build(videoStreamIndex, maybeIndex); maybeFilter.IfSome( filter => { diff --git a/ErsatzTV.Core/FFmpeg/FFmpegProcessService.cs b/ErsatzTV.Core/FFmpeg/FFmpegProcessService.cs index 46b4d5bd6..d6cc2d8e2 100644 --- a/ErsatzTV.Core/FFmpeg/FFmpegProcessService.cs +++ b/ErsatzTV.Core/FFmpeg/FFmpegProcessService.cs @@ -30,14 +30,14 @@ namespace ErsatzTV.Core.FFmpeg DateTimeOffset now) { MediaStream videoStream = await _ffmpegStreamSelector.SelectVideoStream(channel, version); - MediaStream audioStream = await _ffmpegStreamSelector.SelectAudioStream(channel, version); + Option maybeAudioStream = await _ffmpegStreamSelector.SelectAudioStream(channel, version); FFmpegPlaybackSettings playbackSettings = _playbackSettingsCalculator.CalculateSettings( channel.StreamingMode, channel.FFmpegProfile, version, videoStream, - audioStream, + maybeAudioStream, start, now); @@ -67,7 +67,7 @@ namespace ErsatzTV.Core.FFmpeg } builder = builder - .WithFilterComplex(videoStream.Index, audioStream.Index); + .WithFilterComplex(videoStream, maybeAudioStream); }, () => { @@ -76,18 +76,18 @@ namespace ErsatzTV.Core.FFmpeg builder = builder .WithDeinterlace(playbackSettings.Deinterlace) .WithBlackBars(channel.FFmpegProfile.Resolution) - .WithFilterComplex(videoStream.Index, audioStream.Index); + .WithFilterComplex(videoStream, maybeAudioStream); } else if (playbackSettings.Deinterlace) { builder = builder.WithDeinterlace(playbackSettings.Deinterlace) .WithAlignedAudio(playbackSettings.AudioDuration) - .WithFilterComplex(videoStream.Index, audioStream.Index); + .WithFilterComplex(videoStream, maybeAudioStream); } else { builder = builder - .WithFilterComplex(videoStream.Index, audioStream.Index); + .WithFilterComplex(videoStream, maybeAudioStream); } }); diff --git a/ErsatzTV.Core/FFmpeg/FFmpegStreamSelector.cs b/ErsatzTV.Core/FFmpeg/FFmpegStreamSelector.cs index 8e680ffac..3889038cc 100644 --- a/ErsatzTV.Core/FFmpeg/FFmpegStreamSelector.cs +++ b/ErsatzTV.Core/FFmpeg/FFmpegStreamSelector.cs @@ -6,6 +6,7 @@ using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; using Microsoft.Extensions.Logging; +using static LanguageExt.Prelude; namespace ErsatzTV.Core.FFmpeg { @@ -25,8 +26,17 @@ namespace ErsatzTV.Core.FFmpeg public Task SelectVideoStream(Channel channel, MediaVersion version) => version.Streams.First(s => s.MediaStreamKind == MediaStreamKind.Video).AsTask(); - public async Task SelectAudioStream(Channel channel, MediaVersion version) + public async Task> SelectAudioStream(Channel channel, MediaVersion version) { + if (channel.StreamingMode == StreamingMode.HttpLiveStreaming && + string.IsNullOrWhiteSpace(channel.PreferredLanguageCode)) + { + _logger.LogDebug( + "Channel {Number} is HLS with no preferred language; using all audio streams", + channel.Number); + return None; + } + var audioStreams = version.Streams.Filter(s => s.MediaStreamKind == MediaStreamKind.Audio).ToList(); string language = (channel.PreferredLanguageCode ?? string.Empty).ToLowerInvariant(); diff --git a/ErsatzTV.Core/Interfaces/FFmpeg/IFFmpegStreamSelector.cs b/ErsatzTV.Core/Interfaces/FFmpeg/IFFmpegStreamSelector.cs index d18b9268d..0ca32f8b6 100644 --- a/ErsatzTV.Core/Interfaces/FFmpeg/IFFmpegStreamSelector.cs +++ b/ErsatzTV.Core/Interfaces/FFmpeg/IFFmpegStreamSelector.cs @@ -1,11 +1,12 @@ using System.Threading.Tasks; using ErsatzTV.Core.Domain; +using LanguageExt; namespace ErsatzTV.Core.Interfaces.FFmpeg { public interface IFFmpegStreamSelector { Task SelectVideoStream(Channel channel, MediaVersion version); - Task SelectAudioStream(Channel channel, MediaVersion version); + Task> SelectAudioStream(Channel channel, MediaVersion version); } } diff --git a/ErsatzTV.Core/Interfaces/Metadata/IMovieFolderScanner.cs b/ErsatzTV.Core/Interfaces/Metadata/IMovieFolderScanner.cs index e0619c19e..366993725 100644 --- a/ErsatzTV.Core/Interfaces/Metadata/IMovieFolderScanner.cs +++ b/ErsatzTV.Core/Interfaces/Metadata/IMovieFolderScanner.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using ErsatzTV.Core.Domain; using LanguageExt; @@ -13,8 +12,6 @@ namespace ErsatzTV.Core.Interfaces.Metadata string ffprobePath, DateTimeOffset lastScan, decimal progressMin, - decimal progressMax, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex); + decimal progressMax); } } diff --git a/ErsatzTV.Core/Interfaces/Metadata/IMusicVideoFolderScanner.cs b/ErsatzTV.Core/Interfaces/Metadata/IMusicVideoFolderScanner.cs index f01fe2223..1947c3f7f 100644 --- a/ErsatzTV.Core/Interfaces/Metadata/IMusicVideoFolderScanner.cs +++ b/ErsatzTV.Core/Interfaces/Metadata/IMusicVideoFolderScanner.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using ErsatzTV.Core.Domain; using LanguageExt; @@ -13,8 +12,6 @@ namespace ErsatzTV.Core.Interfaces.Metadata string ffprobePath, DateTimeOffset lastScan, decimal progressMin, - decimal progressMax, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex); + decimal progressMax); } } diff --git a/ErsatzTV.Core/Interfaces/Metadata/ITelevisionFolderScanner.cs b/ErsatzTV.Core/Interfaces/Metadata/ITelevisionFolderScanner.cs index 261d74a72..f2d3d2b65 100644 --- a/ErsatzTV.Core/Interfaces/Metadata/ITelevisionFolderScanner.cs +++ b/ErsatzTV.Core/Interfaces/Metadata/ITelevisionFolderScanner.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using ErsatzTV.Core.Domain; using LanguageExt; @@ -13,8 +12,6 @@ namespace ErsatzTV.Core.Interfaces.Metadata string ffprobePath, DateTimeOffset lastScan, decimal progressMin, - decimal progressMax, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex); + decimal progressMax); } } diff --git a/ErsatzTV.Core/Interfaces/Plex/IPlexMovieLibraryScanner.cs b/ErsatzTV.Core/Interfaces/Plex/IPlexMovieLibraryScanner.cs index 2711c9314..f802b3347 100644 --- a/ErsatzTV.Core/Interfaces/Plex/IPlexMovieLibraryScanner.cs +++ b/ErsatzTV.Core/Interfaces/Plex/IPlexMovieLibraryScanner.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; +using System.Threading.Tasks; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Plex; using LanguageExt; @@ -12,8 +10,6 @@ namespace ErsatzTV.Core.Interfaces.Plex Task> ScanLibrary( PlexConnection connection, PlexServerAuthToken token, - PlexLibrary plexMediaSourceLibrary, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex); + PlexLibrary plexMediaSourceLibrary); } } diff --git a/ErsatzTV.Core/Interfaces/Plex/IPlexTelevisionLibraryScanner.cs b/ErsatzTV.Core/Interfaces/Plex/IPlexTelevisionLibraryScanner.cs index f8dd7c0d2..2d2c19e86 100644 --- a/ErsatzTV.Core/Interfaces/Plex/IPlexTelevisionLibraryScanner.cs +++ b/ErsatzTV.Core/Interfaces/Plex/IPlexTelevisionLibraryScanner.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; +using System.Threading.Tasks; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Plex; using LanguageExt; @@ -12,8 +10,6 @@ namespace ErsatzTV.Core.Interfaces.Plex Task> ScanLibrary( PlexConnection connection, PlexServerAuthToken token, - PlexLibrary plexMediaSourceLibrary, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex); + PlexLibrary plexMediaSourceLibrary); } } diff --git a/ErsatzTV.Core/Metadata/MovieFolderScanner.cs b/ErsatzTV.Core/Metadata/MovieFolderScanner.cs index f86ae8736..508485923 100644 --- a/ErsatzTV.Core/Metadata/MovieFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/MovieFolderScanner.cs @@ -8,6 +8,7 @@ using ErsatzTV.Core.Errors; using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Repositories; +using ErsatzTV.Core.Interfaces.Search; using LanguageExt; using MediatR; using Microsoft.Extensions.Logging; @@ -24,6 +25,7 @@ namespace ErsatzTV.Core.Metadata private readonly ILogger _logger; private readonly IMediator _mediator; private readonly IMovieRepository _movieRepository; + private readonly ISearchIndex _searchIndex; public MovieFolderScanner( ILocalFileSystem localFileSystem, @@ -32,6 +34,7 @@ namespace ErsatzTV.Core.Metadata ILocalMetadataProvider localMetadataProvider, IMetadataRepository metadataRepository, IImageCache imageCache, + ISearchIndex searchIndex, IMediator mediator, ILogger logger) : base(localFileSystem, localStatisticsProvider, metadataRepository, imageCache, logger) @@ -39,6 +42,7 @@ namespace ErsatzTV.Core.Metadata _localFileSystem = localFileSystem; _movieRepository = movieRepository; _localMetadataProvider = localMetadataProvider; + _searchIndex = searchIndex; _mediator = mediator; _logger = logger; } @@ -48,9 +52,7 @@ namespace ErsatzTV.Core.Metadata string ffprobePath, DateTimeOffset lastScan, decimal progressMin, - decimal progressMax, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex) + decimal progressMax) { decimal progressSpread = progressMax - progressMin; @@ -109,7 +111,17 @@ namespace ErsatzTV.Core.Metadata .BindT(movie => UpdateArtwork(movie, ArtworkKind.FanArt)); await maybeMovie.Match( - async result => await addToSearchIndex(new List { result.Item }), + async result => + { + if (result.IsAdded) + { + await _searchIndex.AddItems(new List { result.Item }); + } + else if (result.IsUpdated) + { + await _searchIndex.UpdateItems(new List { result.Item }); + } + }, error => { _logger.LogWarning("Error processing movie at {Path}: {Error}", file, error.Value); @@ -124,7 +136,7 @@ namespace ErsatzTV.Core.Metadata { _logger.LogInformation("Removing missing movie at {Path}", path); List ids = await _movieRepository.DeleteByPath(libraryPath, path); - await removeFromSearchIndex(ids); + await _searchIndex.RemoveItems(ids); } } diff --git a/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs b/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs index 4055465bc..4a7449682 100644 --- a/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs @@ -8,6 +8,7 @@ using ErsatzTV.Core.Errors; using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Repositories; +using ErsatzTV.Core.Interfaces.Search; using LanguageExt; using MediatR; using Microsoft.Extensions.Logging; @@ -23,6 +24,7 @@ namespace ErsatzTV.Core.Metadata private readonly ILogger _logger; private readonly IMediator _mediator; private readonly IMusicVideoRepository _musicVideoRepository; + private readonly ISearchIndex _searchIndex; public MusicVideoFolderScanner( ILocalFileSystem localFileSystem, @@ -30,6 +32,7 @@ namespace ErsatzTV.Core.Metadata ILocalMetadataProvider localMetadataProvider, IMetadataRepository metadataRepository, IImageCache imageCache, + ISearchIndex searchIndex, IMusicVideoRepository musicVideoRepository, IMediator mediator, ILogger logger) : base( @@ -41,6 +44,7 @@ namespace ErsatzTV.Core.Metadata { _localFileSystem = localFileSystem; _localMetadataProvider = localMetadataProvider; + _searchIndex = searchIndex; _musicVideoRepository = musicVideoRepository; _mediator = mediator; _logger = logger; @@ -51,9 +55,7 @@ namespace ErsatzTV.Core.Metadata string ffprobePath, DateTimeOffset lastScan, decimal progressMin, - decimal progressMax, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex) + decimal progressMax) { decimal progressSpread = progressMax - progressMin; @@ -102,7 +104,17 @@ namespace ErsatzTV.Core.Metadata .BindT(UpdateThumbnail); await maybeMusicVideo.Match( - async result => await addToSearchIndex(new List { result.Item }), + async result => + { + if (result.IsAdded) + { + await _searchIndex.AddItems(new List { result.Item }); + } + else if (result.IsUpdated) + { + await _searchIndex.UpdateItems(new List { result.Item }); + } + }, error => { _logger.LogWarning("Error processing music video at {Path}: {Error}", file, error.Value); @@ -117,7 +129,7 @@ namespace ErsatzTV.Core.Metadata { _logger.LogInformation("Removing missing music video at {Path}", path); List ids = await _musicVideoRepository.DeleteByPath(libraryPath, path); - await removeFromSearchIndex(ids); + await _searchIndex.RemoveItems(ids); } } diff --git a/ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs b/ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs index feed66389..7c88c4047 100644 --- a/ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs @@ -8,6 +8,7 @@ using ErsatzTV.Core.Errors; using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Repositories; +using ErsatzTV.Core.Interfaces.Search; using LanguageExt; using MediatR; using Microsoft.Extensions.Logging; @@ -22,6 +23,7 @@ namespace ErsatzTV.Core.Metadata private readonly ILocalMetadataProvider _localMetadataProvider; private readonly ILogger _logger; private readonly IMediator _mediator; + private readonly ISearchIndex _searchIndex; private readonly ITelevisionRepository _televisionRepository; public TelevisionFolderScanner( @@ -31,6 +33,7 @@ namespace ErsatzTV.Core.Metadata ILocalMetadataProvider localMetadataProvider, IMetadataRepository metadataRepository, IImageCache imageCache, + ISearchIndex searchIndex, IMediator mediator, ILogger logger) : base( localFileSystem, @@ -42,6 +45,7 @@ namespace ErsatzTV.Core.Metadata _localFileSystem = localFileSystem; _televisionRepository = televisionRepository; _localMetadataProvider = localMetadataProvider; + _searchIndex = searchIndex; _mediator = mediator; _logger = logger; } @@ -51,9 +55,7 @@ namespace ErsatzTV.Core.Metadata string ffprobePath, DateTimeOffset lastScan, decimal progressMin, - decimal progressMax, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex) + decimal progressMax) { decimal progressSpread = progressMax - progressMin; @@ -82,7 +84,15 @@ namespace ErsatzTV.Core.Metadata await maybeShow.Match( async result => { - await addToSearchIndex(new List { result.Item }); + if (result.IsAdded) + { + await _searchIndex.AddItems(new List { result.Item }); + } + else if (result.IsUpdated) + { + await _searchIndex.UpdateItems(new List { result.Item }); + } + await ScanSeasons( libraryPath, ffprobePath, @@ -112,7 +122,7 @@ namespace ErsatzTV.Core.Metadata await _televisionRepository.DeleteEmptySeasons(libraryPath); List ids = await _televisionRepository.DeleteEmptyShows(libraryPath); - await removeFromSearchIndex(ids); + await _searchIndex.RemoveItems(ids); return Unit.Default; } diff --git a/ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs b/ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs index 9be3aaf0f..fffa6f694 100644 --- a/ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs +++ b/ErsatzTV.Core/Plex/PlexMovieLibraryScanner.cs @@ -1,10 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Plex; using ErsatzTV.Core.Interfaces.Repositories; +using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Metadata; using LanguageExt; using MediatR; @@ -20,11 +20,13 @@ namespace ErsatzTV.Core.Plex private readonly IMetadataRepository _metadataRepository; private readonly IMovieRepository _movieRepository; private readonly IPlexServerApiClient _plexServerApiClient; + private readonly ISearchIndex _searchIndex; public PlexMovieLibraryScanner( IPlexServerApiClient plexServerApiClient, IMovieRepository movieRepository, IMetadataRepository metadataRepository, + ISearchIndex searchIndex, IMediator mediator, ILogger logger) : base(metadataRepository, logger) @@ -32,6 +34,7 @@ namespace ErsatzTV.Core.Plex _plexServerApiClient = plexServerApiClient; _movieRepository = movieRepository; _metadataRepository = metadataRepository; + _searchIndex = searchIndex; _mediator = mediator; _logger = logger; } @@ -39,9 +42,7 @@ namespace ErsatzTV.Core.Plex public async Task> ScanLibrary( PlexConnection connection, PlexServerAuthToken token, - PlexLibrary plexMediaSourceLibrary, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex) + PlexLibrary plexMediaSourceLibrary) { Either> entries = await _plexServerApiClient.GetMovieLibraryContents( plexMediaSourceLibrary, @@ -64,7 +65,17 @@ namespace ErsatzTV.Core.Plex .BindT(existing => UpdateArtwork(existing, incoming)); await maybeMovie.Match( - async result => await addToSearchIndex(new List { result.Item }), + async result => + { + if (result.IsAdded) + { + await _searchIndex.AddItems(new List { result.Item }); + } + else if (result.IsUpdated) + { + await _searchIndex.UpdateItems(new List { result.Item }); + } + }, error => { _logger.LogWarning( @@ -77,7 +88,7 @@ namespace ErsatzTV.Core.Plex var movieKeys = movieEntries.Map(s => s.Key).ToList(); List ids = await _movieRepository.RemoveMissingPlexMovies(plexMediaSourceLibrary, movieKeys); - await removeFromSearchIndex(ids); + await _searchIndex.RemoveItems(ids); await _mediator.Publish(new LibraryScanProgress(plexMediaSourceLibrary.Id, 0)); }, diff --git a/ErsatzTV.Core/Plex/PlexTelevisionLibraryScanner.cs b/ErsatzTV.Core/Plex/PlexTelevisionLibraryScanner.cs index 3c5f3baa5..2179a5fc2 100644 --- a/ErsatzTV.Core/Plex/PlexTelevisionLibraryScanner.cs +++ b/ErsatzTV.Core/Plex/PlexTelevisionLibraryScanner.cs @@ -1,10 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Plex; using ErsatzTV.Core.Interfaces.Repositories; +using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Metadata; using LanguageExt; using MediatR; @@ -20,12 +20,14 @@ namespace ErsatzTV.Core.Plex private readonly IMediator _mediator; private readonly IMetadataRepository _metadataRepository; private readonly IPlexServerApiClient _plexServerApiClient; + private readonly ISearchIndex _searchIndex; private readonly ITelevisionRepository _televisionRepository; public PlexTelevisionLibraryScanner( IPlexServerApiClient plexServerApiClient, ITelevisionRepository televisionRepository, IMetadataRepository metadataRepository, + ISearchIndex searchIndex, IMediator mediator, ILogger logger) : base(metadataRepository, logger) @@ -33,6 +35,7 @@ namespace ErsatzTV.Core.Plex _plexServerApiClient = plexServerApiClient; _televisionRepository = televisionRepository; _metadataRepository = metadataRepository; + _searchIndex = searchIndex; _mediator = mediator; _logger = logger; } @@ -40,9 +43,7 @@ namespace ErsatzTV.Core.Plex public async Task> ScanLibrary( PlexConnection connection, PlexServerAuthToken token, - PlexLibrary plexMediaSourceLibrary, - Func, ValueTask> addToSearchIndex, - Func, ValueTask> removeFromSearchIndex) + PlexLibrary plexMediaSourceLibrary) { Either> entries = await _plexServerApiClient.GetShowLibraryContents( plexMediaSourceLibrary, @@ -66,7 +67,15 @@ namespace ErsatzTV.Core.Plex await maybeShow.Match( async result => { - await addToSearchIndex(new List { result.Item }); + if (result.IsAdded) + { + await _searchIndex.AddItems(new List { result.Item }); + } + else if (result.IsUpdated) + { + await _searchIndex.UpdateItems(new List { result.Item }); + } + await ScanSeasons(plexMediaSourceLibrary, result.Item, connection, token); }, error => @@ -82,7 +91,7 @@ namespace ErsatzTV.Core.Plex var showKeys = showEntries.Map(s => s.Key).ToList(); List ids = await _televisionRepository.RemoveMissingPlexShows(plexMediaSourceLibrary, showKeys); - await removeFromSearchIndex(ids); + await _searchIndex.RemoveItems(ids); await _mediator.Publish(new LibraryScanProgress(plexMediaSourceLibrary.Id, 0)); diff --git a/ErsatzTV/Pages/Movie.razor b/ErsatzTV/Pages/Movie.razor index f24323d95..4b17aa961 100644 --- a/ErsatzTV/Pages/Movie.razor +++ b/ErsatzTV/Pages/Movie.razor @@ -19,7 +19,7 @@ @if (!string.IsNullOrWhiteSpace(_movie.Poster)) { movie poster }
diff --git a/ErsatzTV/Pages/MovieList.razor b/ErsatzTV/Pages/MovieList.razor index 8394befa3..2b21c9cf1 100644 --- a/ErsatzTV/Pages/MovieList.razor +++ b/ErsatzTV/Pages/MovieList.razor @@ -130,10 +130,7 @@ private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) { - List GetSortedItems() - { - return _data.Cards.OrderBy(m => m.SortTitle).ToList(); - } + List GetSortedItems() => _data.Cards.OrderBy(m => m.SortTitle).ToList(); SelectClicked(GetSortedItems, card, e); } diff --git a/ErsatzTV/Pages/MusicVideoList.razor b/ErsatzTV/Pages/MusicVideoList.razor index dda224e7f..c90b0ef48 100644 --- a/ErsatzTV/Pages/MusicVideoList.razor +++ b/ErsatzTV/Pages/MusicVideoList.razor @@ -131,10 +131,7 @@ private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) { - List GetSortedItems() - { - return _data.Cards.OrderBy(m => m.SortTitle).ToList(); - } + List GetSortedItems() => _data.Cards.OrderBy(m => m.SortTitle).ToList(); SelectClicked(GetSortedItems, card, e); } diff --git a/ErsatzTV/Pages/TelevisionEpisodeList.razor b/ErsatzTV/Pages/TelevisionEpisodeList.razor index 63385e472..4959a5c5a 100644 --- a/ErsatzTV/Pages/TelevisionEpisodeList.razor +++ b/ErsatzTV/Pages/TelevisionEpisodeList.razor @@ -29,7 +29,7 @@ @if (!string.IsNullOrWhiteSpace(_season.Poster)) { show poster }
diff --git a/ErsatzTV/Pages/TelevisionSeasonList.razor b/ErsatzTV/Pages/TelevisionSeasonList.razor index 650a91a77..f64e6d216 100644 --- a/ErsatzTV/Pages/TelevisionSeasonList.razor +++ b/ErsatzTV/Pages/TelevisionSeasonList.razor @@ -27,7 +27,7 @@ @if (!string.IsNullOrWhiteSpace(_show.Poster)) { show poster }
diff --git a/ErsatzTV/Pages/TelevisionShowList.razor b/ErsatzTV/Pages/TelevisionShowList.razor index 285055352..6a6f124ea 100644 --- a/ErsatzTV/Pages/TelevisionShowList.razor +++ b/ErsatzTV/Pages/TelevisionShowList.razor @@ -130,10 +130,7 @@ private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) { - List GetSortedItems() - { - return _data.Cards.OrderBy(m => m.SortTitle).ToList(); - } + List GetSortedItems() => _data.Cards.OrderBy(m => m.SortTitle).ToList(); SelectClicked(GetSortedItems, card, e); } diff --git a/ErsatzTV/Services/SchedulerService.cs b/ErsatzTV/Services/SchedulerService.cs index 34d426224..3ad2f1240 100644 --- a/ErsatzTV/Services/SchedulerService.cs +++ b/ErsatzTV/Services/SchedulerService.cs @@ -24,7 +24,6 @@ namespace ErsatzTV.Services private readonly IEntityLocker _entityLocker; private readonly ILogger _logger; private readonly ChannelWriter _plexWorkerChannel; - private readonly ChannelWriter _searchWorkerChannel; private readonly IServiceScopeFactory _serviceScopeFactory; private readonly ChannelWriter _workerChannel; @@ -32,14 +31,12 @@ namespace ErsatzTV.Services IServiceScopeFactory serviceScopeFactory, ChannelWriter workerChannel, ChannelWriter plexWorkerChannel, - ChannelWriter searchWorkerChannel, IEntityLocker entityLocker, ILogger logger) { _serviceScopeFactory = serviceScopeFactory; _workerChannel = workerChannel; _plexWorkerChannel = plexWorkerChannel; - _searchWorkerChannel = searchWorkerChannel; _entityLocker = entityLocker; _logger = logger; } @@ -126,6 +123,6 @@ namespace ErsatzTV.Services } private ValueTask RebuildSearchIndex(CancellationToken cancellationToken) => - _searchWorkerChannel.WriteAsync(new RebuildSearchIndex(), cancellationToken); + _workerChannel.WriteAsync(new RebuildSearchIndex(), cancellationToken); } } diff --git a/ErsatzTV/Services/SearchIndexService.cs b/ErsatzTV/Services/SearchIndexService.cs deleted file mode 100644 index b7de5de2f..000000000 --- a/ErsatzTV/Services/SearchIndexService.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Channels; -using System.Threading.Tasks; -using ErsatzTV.Application; -using ErsatzTV.Application.Search.Commands; -using MediatR; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; - -namespace ErsatzTV.Services -{ - public class SearchIndexService : BackgroundService - { - private readonly ChannelReader _channel; - private readonly ILogger _logger; - private readonly IServiceScopeFactory _serviceScopeFactory; - - public SearchIndexService( - ChannelReader channel, - IServiceScopeFactory serviceScopeFactory, - ILogger logger) - { - _channel = channel; - _serviceScopeFactory = serviceScopeFactory; - _logger = logger; - } - - protected override async Task ExecuteAsync(CancellationToken cancellationToken) - { - _logger.LogInformation("Search index service started"); - - await foreach (ISearchBackgroundServiceRequest request in _channel.ReadAllAsync(cancellationToken)) - { - try - { - using IServiceScope scope = _serviceScopeFactory.CreateScope(); - IMediator mediator = scope.ServiceProvider.GetRequiredService(); - - switch (request) - { - case RebuildSearchIndex rebuildSearchIndex: - await mediator.Send(rebuildSearchIndex, cancellationToken); - break; - case AddItemsToSearchIndex addItemsToSearchIndex: - await mediator.Send(addItemsToSearchIndex, cancellationToken); - break; - case RemoveItemsFromSearchIndex removeItemsFromSearchIndex: - await mediator.Send(removeItemsFromSearchIndex, cancellationToken); - break; - } - } - catch (Exception ex) - { - _logger.LogWarning(ex, "Failed to process search index service request"); - } - } - } - } -} diff --git a/ErsatzTV/Shared/FragmentLetterAnchor.razor b/ErsatzTV/Shared/FragmentLetterAnchor.razor index 1ee3daa6c..7af7fcc0b 100644 --- a/ErsatzTV/Shared/FragmentLetterAnchor.razor +++ b/ErsatzTV/Shared/FragmentLetterAnchor.razor @@ -1,4 +1,5 @@ -@using LanguageExt.UnsafeValueAccess +@using ErsatzTV.Application.MediaCards +@using LanguageExt.UnsafeValueAccess @typeparam TCard @{ var letters = new System.Collections.Generic.HashSet(); } @@ -24,4 +25,4 @@ { @ChildContent } -} \ No newline at end of file +} diff --git a/ErsatzTV/Startup.cs b/ErsatzTV/Startup.cs index e4814a922..b25b73be7 100644 --- a/ErsatzTV/Startup.cs +++ b/ErsatzTV/Startup.cs @@ -187,7 +187,6 @@ namespace ErsatzTV services.AddSingleton(); AddChannel(services); AddChannel(services); - AddChannel(services); services.AddScoped(); services.AddScoped();