diff options
Diffstat (limited to 'Emby.Server.Implementations')
37 files changed, 348 insertions, 74 deletions
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index a5cc125ec..886da1390 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -29,7 +29,7 @@ <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" /> - <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.2" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.3" /> <PackageReference Include="Mono.Nat" Version="3.0.2" /> <PackageReference Include="prometheus-net.DotNetRuntime" Version="4.2.3" /> <PackageReference Include="sharpcompress" Version="0.30.1" /> diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index 34fdfbe8d..e45baedd7 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.EntryPoints { CheckDisposed(); - if (_configurationManager.GetNetworkConfiguration().AutoDiscovery) + if (!_configurationManager.GetNetworkConfiguration().AutoDiscovery) { return Task.CompletedTask; } diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 4f8a52f41..399ece7fd 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -704,6 +704,18 @@ namespace Emby.Server.Implementations.IO return Directory.EnumerateFileSystemEntries(path, "*", GetEnumerationOptions(recursive)); } + /// <inheritdoc /> + public virtual bool DirectoryExists(string path) + { + return Directory.Exists(path); + } + + /// <inheritdoc /> + public virtual bool FileExists(string path) + { + return File.Exists(path); + } + private EnumerationOptions GetEnumerationOptions(bool recursive) { return new EnumerationOptions diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs index 758986945..57c2f1a5e 100644 --- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs @@ -135,7 +135,7 @@ namespace Emby.Server.Implementations.Images protected virtual IEnumerable<string> GetStripCollageImagePaths(BaseItem primaryItem, IEnumerable<BaseItem> items) { - var useBackdrop = primaryItem is CollectionFolder; + var useBackdrop = primaryItem is CollectionFolder || primaryItem is UserView; return items .Select(i => { diff --git a/Emby.Server.Implementations/Images/DynamicImageProvider.cs b/Emby.Server.Implementations/Images/DynamicImageProvider.cs index 575680653..9f9a4902a 100644 --- a/Emby.Server.Implementations/Images/DynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/DynamicImageProvider.cs @@ -84,16 +84,20 @@ namespace Emby.Server.Implementations.Images }).GroupBy(x => x.Id) .Select(x => x.First()); + List<BaseItem> returnItems; if (isUsingCollectionStrip) { - return items + returnItems = items .Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)) .ToList(); + returnItems.Shuffle(); + return returnItems; } - - return items + returnItems = items .Where(i => i.HasImage(ImageType.Primary)) .ToList(); + returnItems.Shuffle(); + return returnItems; } protected override bool Supports(BaseItem item) diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index d340115a8..a9428ae9b 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -46,6 +46,7 @@ using MediaBrowser.Model.Library; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Tasks; using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Episode = MediaBrowser.Controller.Entities.TV.Episode; using EpisodeInfo = Emby.Naming.TV.EpisodeInfo; @@ -99,7 +100,7 @@ namespace Emby.Server.Implementations.Library /// Initializes a new instance of the <see cref="LibraryManager" /> class. /// </summary> /// <param name="appHost">The application host.</param> - /// <param name="logger">The logger.</param> + /// <param name="loggerFactory">The logger factory.</param> /// <param name="taskManager">The task manager.</param> /// <param name="userManager">The user manager.</param> /// <param name="configurationManager">The configuration manager.</param> @@ -115,7 +116,7 @@ namespace Emby.Server.Implementations.Library /// <param name="namingOptions">The naming options.</param> public LibraryManager( IServerApplicationHost appHost, - ILogger<LibraryManager> logger, + ILoggerFactory loggerFactory, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, @@ -131,7 +132,7 @@ namespace Emby.Server.Implementations.Library NamingOptions namingOptions) { _appHost = appHost; - _logger = logger; + _logger = loggerFactory.CreateLogger<LibraryManager>(); _taskManager = taskManager; _userManager = userManager; _configurationManager = configurationManager; @@ -146,7 +147,7 @@ namespace Emby.Server.Implementations.Library _memoryCache = memoryCache; _namingOptions = namingOptions; - _extraResolver = new ExtraResolver(namingOptions); + _extraResolver = new ExtraResolver(loggerFactory.CreateLogger<ExtraResolver>(), namingOptions); _configurationManager.ConfigurationUpdated += ConfigurationUpdated; diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index 9222a9479..3d6b9f3b6 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -12,6 +12,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Library.Resolvers { @@ -22,8 +23,11 @@ namespace Emby.Server.Implementations.Library.Resolvers public abstract class BaseVideoResolver<T> : MediaBrowser.Controller.Resolvers.ItemResolver<T> where T : Video, new() { - protected BaseVideoResolver(NamingOptions namingOptions) + private readonly ILogger _logger; + + protected BaseVideoResolver(ILogger logger, NamingOptions namingOptions) { + _logger = logger; NamingOptions = namingOptions; } @@ -156,19 +160,26 @@ namespace Emby.Server.Implementations.Library.Resolvers } else { - // use disc-utils, both DVDs and BDs use UDF filesystem - using (var videoFileStream = File.Open(video.Path, FileMode.Open, FileAccess.Read)) - using (UdfReader udfReader = new UdfReader(videoFileStream)) + try { - if (udfReader.DirectoryExists("VIDEO_TS")) - { - video.IsoType = IsoType.Dvd; - } - else if (udfReader.DirectoryExists("BDMV")) + // use disc-utils, both DVDs and BDs use UDF filesystem + using (var videoFileStream = File.Open(video.Path, FileMode.Open, FileAccess.Read)) + using (UdfReader udfReader = new UdfReader(videoFileStream)) { - video.IsoType = IsoType.BluRay; + if (udfReader.DirectoryExists("VIDEO_TS")) + { + video.IsoType = IsoType.Dvd; + } + else if (udfReader.DirectoryExists("BDMV")) + { + video.IsoType = IsoType.BluRay; + } } } + catch (Exception ex) + { + _logger.LogError(ex, "Error opening UDF/ISO image: {Value}", video.Path ?? video.Name); + } } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs index 807913b5d..408e640f9 100644 --- a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs @@ -6,6 +6,7 @@ using Emby.Naming.Video; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; +using Microsoft.Extensions.Logging; using static Emby.Naming.Video.ExtraRuleResolver; namespace Emby.Server.Implementations.Library.Resolvers @@ -22,12 +23,13 @@ namespace Emby.Server.Implementations.Library.Resolvers /// <summary> /// Initializes a new instance of the <see cref="ExtraResolver"/> class. /// </summary> + /// <param name="logger">The logger.</param> /// <param name="namingOptions">An instance of <see cref="NamingOptions"/>.</param> - public ExtraResolver(NamingOptions namingOptions) + public ExtraResolver(ILogger<ExtraResolver> logger, NamingOptions namingOptions) { _namingOptions = namingOptions; - _trailerResolvers = new IItemResolver[] { new GenericVideoResolver<Trailer>(namingOptions) }; - _videoResolvers = new IItemResolver[] { new GenericVideoResolver<Video>(namingOptions) }; + _trailerResolvers = new IItemResolver[] { new GenericVideoResolver<Trailer>(logger, namingOptions) }; + _videoResolvers = new IItemResolver[] { new GenericVideoResolver<Video>(logger, namingOptions) }; } /// <summary> diff --git a/Emby.Server.Implementations/Library/Resolvers/GenericVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/GenericVideoResolver.cs index b8554bd51..5e33b402d 100644 --- a/Emby.Server.Implementations/Library/Resolvers/GenericVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/GenericVideoResolver.cs @@ -1,7 +1,8 @@ -#nullable disable +#nullable disable using Emby.Naming.Common; using MediaBrowser.Controller.Entities; +using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Library.Resolvers { @@ -15,9 +16,10 @@ namespace Emby.Server.Implementations.Library.Resolvers /// <summary> /// Initializes a new instance of the <see cref="GenericVideoResolver{T}"/> class. /// </summary> + /// <param name="logger">The logger.</param> /// <param name="namingOptions">The naming options.</param> - public GenericVideoResolver(NamingOptions namingOptions) - : base(namingOptions) + public GenericVideoResolver(ILogger logger, NamingOptions namingOptions) + : base(logger, namingOptions) { } } diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index be1460928..140c4272e 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -17,6 +17,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; +using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Library.Resolvers.Movies { @@ -40,9 +41,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies /// Initializes a new instance of the <see cref="MovieResolver"/> class. /// </summary> /// <param name="imageProcessor">The image processor.</param> + /// <param name="logger">The logger.</param> /// <param name="namingOptions">The naming options.</param> - public MovieResolver(IImageProcessor imageProcessor, NamingOptions namingOptions) - : base(namingOptions) + public MovieResolver(IImageProcessor imageProcessor, ILogger<MovieResolver> logger, NamingOptions namingOptions) + : base(logger, namingOptions) { _imageProcessor = imageProcessor; } diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index be9905647..bfa73af2f 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -6,6 +6,7 @@ using Emby.Naming.Common; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; +using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Library.Resolvers.TV { @@ -17,9 +18,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV /// <summary> /// Initializes a new instance of the <see cref="EpisodeResolver"/> class. /// </summary> + /// <param name="logger">The logger.</param> /// <param name="namingOptions">The naming options.</param> - public EpisodeResolver(NamingOptions namingOptions) - : base(namingOptions) + public EpisodeResolver(ILogger<EpisodeResolver> logger, NamingOptions namingOptions) + : base(logger, namingOptions) { } diff --git a/Emby.Server.Implementations/Localization/Core/cs.json b/Emby.Server.Implementations/Localization/Core/cs.json index 7ee8d1040..01a9969b4 100644 --- a/Emby.Server.Implementations/Localization/Core/cs.json +++ b/Emby.Server.Implementations/Localization/Core/cs.json @@ -120,5 +120,7 @@ "Forced": "Vynucené", "Default": "Výchozí", "TaskOptimizeDatabaseDescription": "Zmenší databázi a odstraní prázdné místo. Spuštění této úlohy po skenování knihovny či jiných změnách databáze může zlepšit výkon.", - "TaskOptimizeDatabase": "Optimalizovat databázi" + "TaskOptimizeDatabase": "Optimalizovat databázi", + "TaskKeyframeExtractorDescription": "Vytahuje klíčové snímky ze souborů videa za účelem vytváření přesnějších seznamů přehrávání HLS. Tento úkol může trvat velmi dlouho.", + "TaskKeyframeExtractor": "Vytahovač klíčových snímků" } diff --git a/Emby.Server.Implementations/Localization/Core/cy.json b/Emby.Server.Implementations/Localization/Core/cy.json index 7fc27e18a..981614005 100644 --- a/Emby.Server.Implementations/Localization/Core/cy.json +++ b/Emby.Server.Implementations/Localization/Core/cy.json @@ -54,5 +54,57 @@ "Undefined": "Heb ddiffiniad", "TvShows": "Rhaglenni teledu", "HeaderLiveTV": "Teledu Byw", - "User": "Defnyddiwr" + "User": "Defnyddiwr", + "TaskCleanLogsDescription": "Dileu ffeiliau log sy'n fwy na {0} diwrnod oed.", + "TaskCleanLogs": "Glanhau ffolder log", + "TaskRefreshLibraryDescription": "Sganio'ch llyfrgell gyfryngau am ffeiliau newydd ac yn adnewyddu metaddata.", + "TaskRefreshLibrary": "Sganwich Llyfrgell Cyfryngau", + "TaskCleanActivityLogDescription": "Yn dileu cofnodion log gweithgaredd sy'n hŷn na'r oedran a nodwyd.", + "TaskCleanActivityLog": "Glanhau Log Gweithgaredd", + "SubtitleDownloadFailureFromForItem": "Methodd is-deitlau lawrlwytho o {0} ar gyfer {1}", + "NotificationOptionPluginError": "Methodd ategyn", + "NotificationOptionAudioPlaybackStopped": "Stopiwyd chwarae sain", + "NotificationOptionAudioPlayback": "Dechreuwyd chwarae sain", + "MessageServerConfigurationUpdated": "Mae ffurfweddiad gweinydd wedi'i ddiweddaru", + "MessageNamedServerConfigurationUpdatedWithValue": "Mae adran ffurfweddu gweinydd {0} wedi'i diweddaru", + "FailedLoginAttemptWithUserName": "Cais mewngofnodi wedi methu gan {0}", + "ValueHasBeenAddedToLibrary": "{0} wedi'i hychwanegu at eich llyfrgell gyfryngau", + "UserStoppedPlayingItemWithValues": "{0} wedi gorffen chwarae {1} ar {2}", + "UserStartedPlayingItemWithValues": "{0} yn chwarae {1} ar {2}", + "UserPolicyUpdatedWithName": "Polisi defnyddiwr wedi'i newid ar gyfer {0}", + "UserPasswordChangedWithName": "Cyfrinair wedi'i newid ar gyfer defnyddiwr {0}", + "UserOnlineFromDevice": "Mae {0} ar-lein o {1}", + "UserOfflineFromDevice": "Mae {0} wedi datgysylltu o {1}", + "UserLockedOutWithName": "Mae defnyddiwr {0} wedi'i gloi allan", + "UserDownloadingItemWithValues": "Mae {0} yn lawrlwytho {1}", + "UserDeletedWithName": "Defnyddiwr {0} wedi'i ddileu", + "UserCreatedWithName": "Defnyddiwr {0} wedi'i greu", + "StartupEmbyServerIsLoading": "Gweinydd Jellyfin yn llwytho. Triwch eto mewn ychydig.", + "ServerNameNeedsToBeRestarted": "Mae angen ailddechrau {0}", + "PluginUpdatedWithName": "{0} wedi'i ddiweddaru", + "PluginUninstalledWithName": "{0} wedi'i ddadosod", + "PluginInstalledWithName": "{0} wedi'i osod", + "NotificationOptionVideoPlaybackStopped": "Stopiwyd chwarae fideo", + "NotificationOptionVideoPlayback": "Dechreuwyd chwarae fideo", + "NotificationOptionUserLockedOut": "Defnyddiwr wedi'i gloi allan", + "NotificationOptionTaskFailed": "Methwyd cyflawni y dasg a drefnwyd", + "NotificationOptionServerRestartRequired": "Mae angen ailgychwyn y gweinydd", + "NotificationOptionPluginUpdateInstalled": "Diweddariad ategyn wedi'i osod", + "NotificationOptionPluginUninstalled": "Ategyn wedi'i ddadosod", + "NotificationOptionPluginInstalled": "Ategyn wedi'i osod", + "NotificationOptionNewLibraryContent": "Cynnwys newydd ar gael", + "NotificationOptionCameraImageUploaded": "Llun camera wedi'i huwchlwytho", + "NotificationOptionApplicationUpdateInstalled": "Diweddariad ap wedi'i osod", + "NotificationOptionApplicationUpdateAvailable": "Diweddariad ap ar gael", + "NewVersionIsAvailable": "Mae fersiwn diweddarach o'r gweinydd Jellyfin ar gael.", + "NameInstallFailed": "Gosodiad {0} wedi methu", + "MessageApplicationUpdatedTo": "Gweinydd Jellyfin wedi'i ddiweddaru i {0}", + "MessageApplicationUpdated": "Gweinydd Jellyfin wedi'i ddiweddaru", + "LabelIpAddressValue": "Cyfeiriad IP: {0}", + "ItemRemovedWithName": "{0} wedi'i dynnu o'r llyfrgell", + "ItemAddedWithName": "{0} wedi'i adio i'r llyfrgell", + "HeaderRecordingGroups": "Grwpiau Recordio", + "HeaderFavoriteSongs": "Ffefryn Ganeuon", + "HeaderFavoriteShows": "Ffefryn Shoeau", + "HeaderFavoriteEpisodes": "Ffefryn Rhaglenni" } diff --git a/Emby.Server.Implementations/Localization/Core/en-US.json b/Emby.Server.Implementations/Localization/Core/en-US.json index 568a8e447..e06f8e6fe 100644 --- a/Emby.Server.Implementations/Localization/Core/en-US.json +++ b/Emby.Server.Implementations/Localization/Core/en-US.json @@ -119,5 +119,7 @@ "TaskDownloadMissingSubtitles": "Download missing subtitles", "TaskDownloadMissingSubtitlesDescription": "Searches the internet for missing subtitles based on metadata configuration.", "TaskOptimizeDatabase": "Optimize database", - "TaskOptimizeDatabaseDescription": "Compacts database and truncates free space. Running this task after scanning the library or doing other changes that imply database modifications might improve performance." + "TaskOptimizeDatabaseDescription": "Compacts database and truncates free space. Running this task after scanning the library or doing other changes that imply database modifications might improve performance.", + "TaskKeyframeExtractor": "Keyframe Extractor", + "TaskKeyframeExtractorDescription": "Extracts keyframes from video files to create more precise HLS playlists. This task may run for a long time." } diff --git a/Emby.Server.Implementations/Localization/Core/eo.json b/Emby.Server.Implementations/Localization/Core/eo.json index 8abf7fa66..7d0fca47f 100644 --- a/Emby.Server.Implementations/Localization/Core/eo.json +++ b/Emby.Server.Implementations/Localization/Core/eo.json @@ -119,5 +119,7 @@ "HeaderRecordingGroups": "Rikordadaj Grupoj", "FailedLoginAttemptWithUserName": "Malsukcesa ensaluta provo de {0}", "CameraImageUploadedFrom": "Nova kamera bildo estis alŝutita de {0}", - "AuthenticationSucceededWithUserName": "{0} sukcese aŭtentikigis" + "AuthenticationSucceededWithUserName": "{0} sukcese aŭtentikigis", + "TaskKeyframeExtractorDescription": "Eltiras ĉefkadrojn el videodosieroj por krei pli precizajn HLS-ludlistojn. Ĉi tiu tasko povas funkcii dum longa tempo.", + "TaskKeyframeExtractor": "Eltiri Ĉefkadrojn" } diff --git a/Emby.Server.Implementations/Localization/Core/es-MX.json b/Emby.Server.Implementations/Localization/Core/es-MX.json index 432814dac..80ae16c5c 100644 --- a/Emby.Server.Implementations/Localization/Core/es-MX.json +++ b/Emby.Server.Implementations/Localization/Core/es-MX.json @@ -120,5 +120,7 @@ "Forced": "Forzado", "Default": "Predeterminado", "TaskOptimizeDatabase": "Optimizar base de datos", - "TaskOptimizeDatabaseDescription": "Compacta la base de datos y trunca el espacio libre. Puede mejorar el rendimiento si se realiza esta tarea después de escanear la biblioteca o después de realizar otros cambios que impliquen modificar la base de datos." + "TaskOptimizeDatabaseDescription": "Compacta la base de datos y trunca el espacio libre. Puede mejorar el rendimiento si se realiza esta tarea después de escanear la biblioteca o después de realizar otros cambios que impliquen modificar la base de datos.", + "TaskKeyframeExtractorDescription": "Extrae los cuadros clave de los archivos de vídeo para crear listas HLS más precisas. Esta tarea puede tardar un buen rato.", + "TaskKeyframeExtractor": "Extractor de Cuadros Clave" } diff --git a/Emby.Server.Implementations/Localization/Core/es.json b/Emby.Server.Implementations/Localization/Core/es.json index f8c69712e..4918f468b 100644 --- a/Emby.Server.Implementations/Localization/Core/es.json +++ b/Emby.Server.Implementations/Localization/Core/es.json @@ -120,5 +120,7 @@ "Forced": "Forzado", "Default": "Predeterminado", "TaskOptimizeDatabase": "Optimizar la base de datos", - "TaskOptimizeDatabaseDescription": "Compacta y libera el espacio libre en la base de datos. Ejecutar esta tarea tras escanear la biblioteca o hacer cambios que impliquen modificaciones en la base de datos puede mejorar el rendimiento." + "TaskOptimizeDatabaseDescription": "Compacta y libera el espacio libre en la base de datos. Ejecutar esta tarea tras escanear la biblioteca o hacer cambios que impliquen modificaciones en la base de datos puede mejorar el rendimiento.", + "TaskKeyframeExtractorDescription": "Extrae los fotogramas clave de los archivos de vídeo para crear listas HLS más precisas. Esta tarea puede tardar mucho tiempo.", + "TaskKeyframeExtractor": "Extractor de Fotogramas Clave" } diff --git a/Emby.Server.Implementations/Localization/Core/fa.json b/Emby.Server.Implementations/Localization/Core/fa.json index 6960ff007..7fb560be8 100644 --- a/Emby.Server.Implementations/Localization/Core/fa.json +++ b/Emby.Server.Implementations/Localization/Core/fa.json @@ -119,5 +119,8 @@ "TaskCleanActivityLogDescription": "ورودیهای قدیمیتر از سن تنظیم شده در سیاهه فعالیت را حذف میکند.", "TaskCleanActivityLog": "پاکسازی سیاهه فعالیت", "Undefined": "تعریف نشده", - "TaskOptimizeDatabase": "بهینه سازی پایگاه داده" + "TaskOptimizeDatabase": "بهینه سازی پایگاه داده", + "TaskOptimizeDatabaseDescription": "فشرده سازی پایگاه داده و باز کردن فضای آزاد.اجرای این گزینه بعد از اسکن کردن کتابخانه یا تغییرات دیگر که روی پایگاه داده تأثیر میگذارند میتواند کارایی را بهبود ببخشد.", + "TaskKeyframeExtractorDescription": "فریم های کلیدی را از فایل های ویدئویی استخراج می کند تا لیست های پخش HLS دقیق تری ایجاد کند. این کار ممکن است برای مدت طولانی اجرا شود.", + "TaskKeyframeExtractor": "استخراج کننده فریم کلیدی" } diff --git a/Emby.Server.Implementations/Localization/Core/fi.json b/Emby.Server.Implementations/Localization/Core/fi.json index 4a1f4f1d5..435de7363 100644 --- a/Emby.Server.Implementations/Localization/Core/fi.json +++ b/Emby.Server.Implementations/Localization/Core/fi.json @@ -119,5 +119,7 @@ "TaskCleanActivityLog": "Tyhjennä toimintahistoria", "Undefined": "Määrittelemätön", "TaskOptimizeDatabaseDescription": "Tiivistää ja puhdistaa tietokannan. Tämän toiminnon suorittaminen kirjastojen skannauksen tai muiden tietokantaan liittyvien muutoksien jälkeen voi parantaa suorituskykyä.", - "TaskOptimizeDatabase": "Optimoi tietokanta" + "TaskOptimizeDatabase": "Optimoi tietokanta", + "TaskKeyframeExtractorDescription": "Purkaa videotiedostojen avainkuvat tarkempien HLS-toistolistojen luomiseksi. Tehtävä saattaa kestää huomattavan pitkään.", + "TaskKeyframeExtractor": "Avainkuvien purkain" } diff --git a/Emby.Server.Implementations/Localization/Core/fr.json b/Emby.Server.Implementations/Localization/Core/fr.json index e56ae6071..2a329e74d 100644 --- a/Emby.Server.Implementations/Localization/Core/fr.json +++ b/Emby.Server.Implementations/Localization/Core/fr.json @@ -120,5 +120,7 @@ "Forced": "Forcé", "Default": "Par défaut", "TaskOptimizeDatabaseDescription": "Réduit les espaces vides/inutiles et compacte la base de données. Utiliser cette fonction après une mise à jour de la bibliothèque ou toute autre modification de la base de données peut améliorer les performances du serveur.", - "TaskOptimizeDatabase": "Optimiser la base de données" + "TaskOptimizeDatabase": "Optimiser la base de données", + "TaskKeyframeExtractorDescription": "Extrait les images clés des fichiers vidéo pour créer des listes de lecture HLS plus précises. Cette tâche peut durer très longtemps.", + "TaskKeyframeExtractor": "Extracteur d'image clé" } diff --git a/Emby.Server.Implementations/Localization/Core/hi.json b/Emby.Server.Implementations/Localization/Core/hi.json index 85de5925e..781cfcfa2 100644 --- a/Emby.Server.Implementations/Localization/Core/hi.json +++ b/Emby.Server.Implementations/Localization/Core/hi.json @@ -61,5 +61,10 @@ "LabelRunningTimeValue": "चलने का समय: {0}", "ItemAddedWithName": "{0} को लाइब्रेरी में जोड़ा गया", "Inherit": "इनहेरिट", - "NotificationOptionVideoPlaybackStopped": "चलचित्र रुका हुआ" + "NotificationOptionVideoPlaybackStopped": "चलचित्र रुका हुआ", + "PluginUninstalledWithName": "{0} अनइंस्टॉल हुए", + "PluginInstalledWithName": "{0} इंस्टॉल हुए", + "Plugin": "प्लग-इन", + "Playlists": "प्लेलिस्ट", + "Photos": "तस्वीरें" } diff --git a/Emby.Server.Implementations/Localization/Core/hu.json b/Emby.Server.Implementations/Localization/Core/hu.json index acde84aaf..2da936cff 100644 --- a/Emby.Server.Implementations/Localization/Core/hu.json +++ b/Emby.Server.Implementations/Localization/Core/hu.json @@ -120,5 +120,7 @@ "Forced": "Kényszerített", "Default": "Alapértelmezett", "TaskOptimizeDatabaseDescription": "Tömöríti az adatbázist és csonkolja a szabad helyet. A feladat futtatása a könyvtár beolvasása után, vagy egyéb, adatbázis-módosítást igénylő változtatások végrehajtása javíthatja a teljesítményt.", - "TaskOptimizeDatabase": "Adatbázis optimalizálása" + "TaskOptimizeDatabase": "Adatbázis optimalizálása", + "TaskKeyframeExtractor": "Kulcskockák kibontása", + "TaskKeyframeExtractorDescription": "Kulcskockákat bont ki a videofájlokból, hogy pontosabb HLS lejátszási listákat hozzon létre. Ez a feladat hosszú ideig tarthat." } diff --git a/Emby.Server.Implementations/Localization/Core/kk.json b/Emby.Server.Implementations/Localization/Core/kk.json index 1b4a18deb..aaaf04712 100644 --- a/Emby.Server.Implementations/Localization/Core/kk.json +++ b/Emby.Server.Implementations/Localization/Core/kk.json @@ -120,5 +120,7 @@ "TaskCleanCacheDescription": "Jüiede qajet emes keştelgen faildardy joiady.", "TaskCleanActivityLogDescription": "Äreket jūrnalyndağy teñşelgen jasynan asqan jazbalary joiady.", "TaskOptimizeDatabaseDescription": "Derekqordy qysyp, bos oryndy qysqartady. Būl tapsyrmany tasyğyşhanany skanerlegennen keiın nemese derekqorğa meñzeitın basqa özgertuler ıstelgennen keiın oryndau önımdılıktı damytuy mümkın.", - "TaskOptimizeDatabase": "Derekqordy oñtailandyru" + "TaskOptimizeDatabase": "Derekqordy oñtailandyru", + "TaskKeyframeExtractorDescription": "Naqtyraq HLS oynatu tızımderın jasau üşın beinefaildardan negızgı kadrlardy şyğarady. Būl tapsyrma ūzaq uaqytqa sozyluy mümkın.", + "TaskKeyframeExtractor": "Negızgı kadrlardy şyğaru" } diff --git a/Emby.Server.Implementations/Localization/Core/mr.json b/Emby.Server.Implementations/Localization/Core/mr.json index fdb4171b5..5aad4b0ed 100644 --- a/Emby.Server.Implementations/Localization/Core/mr.json +++ b/Emby.Server.Implementations/Localization/Core/mr.json @@ -58,5 +58,47 @@ "Application": "अॅप्लिकेशन", "AppDeviceValues": "अॅप: {0}, यंत्र: {1}", "Collections": "संग्रह", - "ChapterNameValue": "धडा {0}" + "ChapterNameValue": "धडा {0}", + "TaskDownloadMissingSubtitlesDescription": "नसलेल्या उपशिर्षकांचा मेटाडॅटा कॉन्फिग्युरेशनप्रमाणे इन्टरनेटवर शोध घेतो.", + "TaskRefreshChannelsDescription": "इन्टरनेट वाहिन्यांची माहिती ताजी करतो.", + "TaskUpdatePluginsDescription": "आपोआप अपडेट करण्यासाठी कॉन्फिगर केलेल्या प्लगइनसाठी अपडेट डाउनलोड करून इन्स्टॉल करतो.", + "TaskRefreshChannels": "वाहिन्या ताज्या करा", + "TaskRefreshPeopleDescription": "आपल्या माध्यम संग्रहातील अभिनेत्यांचा व दिग्दर्शकांचा मेटाडॅटा ताजा करतो.", + "TaskRefreshPeople": "लोकांची माहिती ताजी करा", + "TaskRefreshLibraryDescription": "माध्यम संग्रह स्कॅन करून नवीन फायली शोधतो व मेटाडॅटा ताजे करतो.", + "TaskRefreshLibrary": "माध्यम संग्रह स्कॅन करा", + "TaskRefreshChapterImagesDescription": "अध्याय असलेल्या व्हिडियोंसाठी थंबनेल चित्र बनवतो.", + "TaskRefreshChapterImages": "अध्याय चित्र काढून घ्या", + "TasksMaintenanceCategory": "देखरेख", + "ValueHasBeenAddedToLibrary": "{0} हे तुमच्या माध्यम संग्रहात जोडण्यात आले आहे", + "UserStoppedPlayingItemWithValues": "{0} यांचं {2} वर {1} पूर्णपणे प्ले करून झालं आहे", + "UserStartedPlayingItemWithValues": "{0} हे {2} वर {1} प्ले करत आहे", + "UserDownloadingItemWithValues": "{0} हे {1} डाउनलोड करत आहे", + "System": "प्रणाली", + "Undefined": "अव्याख्यात", + "Sync": "सिंक", + "ServerNameNeedsToBeRestarted": "{0} याला बंद करून पुन्हा सुरू करायची गरज आहे", + "SubtitleDownloadFailureFromForItem": "{0} येथून {1} यासाठी उपशिर्षक डाउनलोड करण्यात अपयश", + "ScheduledTaskStartedWithName": "{0} सुरू झाले", + "ScheduledTaskFailedWithName": "{0} अपयशी झाले", + "ProviderValue": "पुरवणारा: {0}", + "PluginUpdatedWithName": "{0} अपडेट केले", + "PluginUninstalledWithName": "{0} अनिन्स्टॉल केले", + "PluginInstalledWithName": "{0} इन्स्टॉल केले", + "NotificationOptionVideoPlaybackStopped": "व्हिडियो प्लेबॅक बंद केले", + "NotificationOptionVideoPlayback": "व्हिडियो प्लेबॅक सुरू केले", + "NotificationOptionTaskFailed": "अनुसूचित कार्यात अपयश", + "NotificationOptionServerRestartRequired": "सर्व्हर बंद करून पुन्हा सुरू करावा लागेल", + "NotificationOptionPluginUpdateInstalled": "प्लगइन अपडेट इन्स्टॉल झाले", + "NotificationOptionPluginUninstalled": "प्लगइन अनिन्स्टॉल झाले", + "NotificationOptionPluginInstalled": "प्लगइन इन्स्टॉल झाले", + "NotificationOptionPluginError": "प्लगइनमध्ये अपयश", + "NotificationOptionNewLibraryContent": "नवीन सामग्री जोडली गेली", + "NotificationOptionInstallationFailed": "इन्स्टॉल करण्यात अपयश", + "NotificationOptionAudioPlayback": "ऑडियो प्लेबॅक सुरू झाले", + "NotificationOptionAudioPlaybackStopped": "ऑडियो प्लेबॅक बंद झाले", + "MixedContent": "मिश्रित सामग्री", + "LabelRunningTimeValue": "चालू काल: {0}", + "HeaderContinueWatching": "बघणे चालू ठेवा", + "Default": "डीफॉल्ट" } diff --git a/Emby.Server.Implementations/Localization/Core/pr.json b/Emby.Server.Implementations/Localization/Core/pr.json index 81aa996d9..401e68b2a 100644 --- a/Emby.Server.Implementations/Localization/Core/pr.json +++ b/Emby.Server.Implementations/Localization/Core/pr.json @@ -1,7 +1,16 @@ { - "Books": "Libros", - "AuthenticationSucceededWithUserName": "{0} autentificado correctamente", + "Books": "Scrolls", + "AuthenticationSucceededWithUserName": "{0} passed yer trial", "Artists": "Artistas", "Songs": "Shantees", - "Albums": "Ships" + "Albums": "Tomes", + "Photos": "Paintings", + "NotificationOptionUserLockedOut": "Crewmate sent to the brig", + "HeaderContinueWatching": "Continue Yer Journey", + "Folders": "Chests", + "Application": "Captain", + "DeviceOnlineWithName": "{0} joined yer crew", + "DeviceOfflineWithName": "{0} abandoned ship", + "AppDeviceValues": "Captain: {0}, Ship: {1}", + "CameraImageUploadedFrom": "Yer looking glass has glimpsed another painting from {0}" } diff --git a/Emby.Server.Implementations/Localization/Core/ru.json b/Emby.Server.Implementations/Localization/Core/ru.json index dc3793f1b..dd1e5d0ee 100644 --- a/Emby.Server.Implementations/Localization/Core/ru.json +++ b/Emby.Server.Implementations/Localization/Core/ru.json @@ -120,5 +120,7 @@ "Forced": "Форсир-ые", "Default": "По умолчанию", "TaskOptimizeDatabaseDescription": "Сжимает базу данных и вырезает свободные места. Выполнение этой задачи после сканирования библиотеки или внесения других изменений, предполагающих модификации базы данных, может повысить производительность.", - "TaskOptimizeDatabase": "Оптимизация базы данных" + "TaskOptimizeDatabase": "Оптимизация базы данных", + "TaskKeyframeExtractorDescription": "Извлекаются ключевые кадры из видеофайлов для создания более точных списков плей-листов HLS. Эта задача может выполняться в течение длительного времени.", + "TaskKeyframeExtractor": "Извлечение ключевых кадров" } diff --git a/Emby.Server.Implementations/Localization/Core/sv.json b/Emby.Server.Implementations/Localization/Core/sv.json index 5d05361b0..10c6db63b 100644 --- a/Emby.Server.Implementations/Localization/Core/sv.json +++ b/Emby.Server.Implementations/Localization/Core/sv.json @@ -120,5 +120,7 @@ "Forced": "Tvingad", "Default": "Standard", "TaskOptimizeDatabase": "Optimera databasen", - "TaskOptimizeDatabaseDescription": "Komprimerar databasen och trunkerar ledigt utrymme. Prestandan kan förbättras genom att köra denna task efter att du har skannat biblioteket eller gjort andra förändringar som indikerar att databasen har modifierats." + "TaskOptimizeDatabaseDescription": "Komprimerar databasen och trunkerar ledigt utrymme. Prestandan kan förbättras genom att köra denna task efter att du har skannat biblioteket eller gjort andra förändringar som indikerar att databasen har modifierats.", + "TaskKeyframeExtractorDescription": "Expoterar nyckelram från video filer för att skapa mer exakta HLS-spellistor. Denna uppgift kan pågå under lång tid.", + "TaskKeyframeExtractor": "Nyckelram Extraktor" } diff --git a/Emby.Server.Implementations/Localization/Core/ta.json b/Emby.Server.Implementations/Localization/Core/ta.json index 98d763fcd..5548a74d2 100644 --- a/Emby.Server.Implementations/Localization/Core/ta.json +++ b/Emby.Server.Implementations/Localization/Core/ta.json @@ -119,5 +119,7 @@ "Forced": "கட்டாயப்படுத்தப்பட்டது", "Default": "இயல்புநிலை", "TaskOptimizeDatabaseDescription": "தரவுத்தளத்தை சுருக்கி, இலவச இடத்தை குறைக்கிறது. நூலகத்தை ஸ்கேன் செய்தபின் அல்லது தரவுத்தள மாற்றங்களைக் குறிக்கும் பிற மாற்றங்களைச் செய்தபின் இந்த பணியை இயக்குவது செயல்திறனை மேம்படுத்தக்கூடும்.", - "TaskOptimizeDatabase": "தரவுத்தளத்தை மேம்படுத்தவும்" + "TaskOptimizeDatabase": "தரவுத்தளத்தை மேம்படுத்தவும்", + "TaskKeyframeExtractorDescription": "மிகவும் துல்லியமான HLS பிளேலிஸ்ட்களை உருவாக்க வீடியோ கோப்புகளிலிருந்து கீஃப்ரேம்களைப் பிரித்தெடுக்கிறது. இந்த பணி நீண்ட காலமாக இருக்கலாம்.", + "TaskKeyframeExtractor": "கீஃப்ரேம் எக்ஸ்ட்ராக்டர்" } diff --git a/Emby.Server.Implementations/Localization/Core/vi.json b/Emby.Server.Implementations/Localization/Core/vi.json index d0e08d8ee..a9268c7d5 100644 --- a/Emby.Server.Implementations/Localization/Core/vi.json +++ b/Emby.Server.Implementations/Localization/Core/vi.json @@ -119,5 +119,7 @@ "Forced": "Bắt Buộc", "Default": "Mặc Định", "TaskOptimizeDatabaseDescription": "Thu gọn cơ sở dữ liệu và cắt bớt dung lượng trống. Chạy tác vụ này sau khi quét thư viện hoặc thực hiện các thay đổi khác ngụ ý sửa đổi cơ sở dữ liệu có thể cải thiện hiệu suất.", - "TaskOptimizeDatabase": "Tối ưu hóa cơ sở dữ liệu" + "TaskOptimizeDatabase": "Tối ưu hóa cơ sở dữ liệu", + "TaskKeyframeExtractor": "Trích Xuất Khung Hình", + "TaskKeyframeExtractorDescription": "Trích xuất khung hình chính từ các tệp video để tạo danh sách phát HLS chính xác hơn. Tác vụ này có thể chạy trong một thời gian dài." } diff --git a/Emby.Server.Implementations/Localization/Core/zh-CN.json b/Emby.Server.Implementations/Localization/Core/zh-CN.json index ac4eb644b..23d2819c3 100644 --- a/Emby.Server.Implementations/Localization/Core/zh-CN.json +++ b/Emby.Server.Implementations/Localization/Core/zh-CN.json @@ -120,5 +120,7 @@ "Forced": "强制的", "Default": "默认", "TaskOptimizeDatabaseDescription": "压缩数据库并优化可用空间,在扫描库或执行其他数据库修改后运行此任务可能会提高性能。", - "TaskOptimizeDatabase": "优化数据库" + "TaskOptimizeDatabase": "优化数据库", + "TaskKeyframeExtractorDescription": "从视频文件中提取关键帧以创建更准确的HLS播放列表。这项任务可能需要很长时间。", + "TaskKeyframeExtractor": "关键帧提取器" } diff --git a/Emby.Server.Implementations/Localization/Core/zh-HK.json b/Emby.Server.Implementations/Localization/Core/zh-HK.json index 1cc97bc27..ac74da67d 100644 --- a/Emby.Server.Implementations/Localization/Core/zh-HK.json +++ b/Emby.Server.Implementations/Localization/Core/zh-HK.json @@ -103,7 +103,7 @@ "TaskCleanTranscodeDescription": "刪除超過一天的轉碼文件。", "TaskCleanTranscode": "清理轉碼目錄", "TaskUpdatePluginsDescription": "下載並安裝配置為自動更新的插件的更新。", - "TaskRefreshPeopleDescription": "更新媒體庫中演員和導演的metadata。", + "TaskRefreshPeopleDescription": "更新媒體庫中演員和導演的元數據。", "TaskCleanLogsDescription": "刪除超過{0}天的日誌文件。", "TaskCleanLogs": "清理日誌目錄", "TaskRefreshLibrary": "掃描媒體庫", diff --git a/Emby.Server.Implementations/Localization/Ratings/au.csv b/Emby.Server.Implementations/Localization/Ratings/au.csv index 940375e26..11f4ed94c 100644 --- a/Emby.Server.Implementations/Localization/Ratings/au.csv +++ b/Emby.Server.Implementations/Localization/Ratings/au.csv @@ -2,7 +2,6 @@ AU-G,1 AU-PG,5 AU-M,6 AU-MA15+,7 -AU-M15+,8 AU-R18+,9 AU-X18+,10 AU-RC,11 diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index fd3fc31c9..21795c8f8 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -1,5 +1,3 @@ -#nullable disable - #pragma warning disable CS1591 using System; @@ -63,18 +61,13 @@ namespace Emby.Server.Implementations.Net } /// <inheritdoc /> - public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) + public ISocket CreateUdpMulticastSocket(IPAddress ipAddress, int multicastTimeToLive, int localPort) { if (ipAddress == null) { throw new ArgumentNullException(nameof(ipAddress)); } - if (ipAddress.Length == 0) - { - throw new ArgumentException("ipAddress cannot be an empty string.", nameof(ipAddress)); - } - if (multicastTimeToLive <= 0) { throw new ArgumentException("multicastTimeToLive cannot be zero or less.", nameof(multicastTimeToLive)); @@ -87,14 +80,7 @@ namespace Emby.Server.Implementations.Net var retVal = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - try - { - // not supported on all platforms. throws on ubuntu with .net core 2.0 - retVal.ExclusiveAddressUse = false; - } - catch (SocketException) - { - } + retVal.ExclusiveAddressUse = false; try { @@ -114,7 +100,7 @@ namespace Emby.Server.Implementations.Net var localIp = IPAddress.Any; - retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); + retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ipAddress, localIp)); retVal.MulticastLoopback = true; return new UdpSocket(retVal, localPort, localIp); diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 5d16f8353..277fdf87d 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -424,9 +424,14 @@ namespace Emby.Server.Implementations.Session var nowPlayingQueue = info.NowPlayingQueue; - if (nowPlayingQueue != null) + if (nowPlayingQueue?.Length > 0) { session.NowPlayingQueue = nowPlayingQueue; + + var itemIds = nowPlayingQueue.Select(queue => queue.Id).ToArray(); + session.NowPlayingQueueFullItems = _dtoService.GetBaseItemDtos( + _libraryManager.GetItemList(new InternalItemsQuery { ItemIds = itemIds }), + new DtoOptions(true)); } } diff --git a/Emby.Server.Implementations/Sorting/IndexNumberComparer.cs b/Emby.Server.Implementations/Sorting/IndexNumberComparer.cs new file mode 100644 index 000000000..e39280a10 --- /dev/null +++ b/Emby.Server.Implementations/Sorting/IndexNumberComparer.cs @@ -0,0 +1,50 @@ +using System; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; + +namespace Emby.Server.Implementations.Sorting +{ + /// <summary> + /// Class IndexNumberComparer. + /// </summary> + public class IndexNumberComparer : IBaseItemComparer + { + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public string Name => ItemSortBy.IndexNumber; + + /// <summary> + /// Compares the specified x. + /// </summary> + /// <param name="x">The x.</param> + /// <param name="y">The y.</param> + /// <returns>System.Int32.</returns> + public int Compare(BaseItem? x, BaseItem? y) + { + if (x == null) + { + throw new ArgumentNullException(nameof(x)); + } + + if (y == null) + { + throw new ArgumentNullException(nameof(y)); + } + + if (!x.IndexNumber.HasValue) + { + return -1; + } + + if (!y.IndexNumber.HasValue) + { + return 1; + } + + return x.IndexNumber.Value.CompareTo(y.IndexNumber.Value); + } + } +} diff --git a/Emby.Server.Implementations/Sorting/ParentIndexNumberComparer.cs b/Emby.Server.Implementations/Sorting/ParentIndexNumberComparer.cs new file mode 100644 index 000000000..ffc4e0cad --- /dev/null +++ b/Emby.Server.Implementations/Sorting/ParentIndexNumberComparer.cs @@ -0,0 +1,50 @@ +using System; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; + +namespace Emby.Server.Implementations.Sorting +{ + /// <summary> + /// Class ParentIndexNumberComparer. + /// </summary> + public class ParentIndexNumberComparer : IBaseItemComparer + { + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public string Name => ItemSortBy.ParentIndexNumber; + + /// <summary> + /// Compares the specified x. + /// </summary> + /// <param name="x">The x.</param> + /// <param name="y">The y.</param> + /// <returns>System.Int32.</returns> + public int Compare(BaseItem? x, BaseItem? y) + { + if (x == null) + { + throw new ArgumentNullException(nameof(x)); + } + + if (y == null) + { + throw new ArgumentNullException(nameof(y)); + } + + if (!x.ParentIndexNumber.HasValue) + { + return -1; + } + + if (!y.ParentIndexNumber.HasValue) + { + return 1; + } + + return x.ParentIndexNumber.Value.CompareTo(y.ParentIndexNumber.Value); + } + } +} diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index 3f2d6a55c..727b9d4b5 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -126,7 +126,8 @@ namespace Emby.Server.Implementations.TV parentsFolders.ToList()) .Cast<Episode>() .Where(episode => !string.IsNullOrEmpty(episode.SeriesPresentationUniqueKey)) - .Select(GetUniqueSeriesKey); + .Select(GetUniqueSeriesKey) + .ToList(); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items, options); @@ -134,13 +135,21 @@ namespace Emby.Server.Implementations.TV return GetResult(episodes, request); } - public IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IEnumerable<string> seriesKeys, DtoOptions dtoOptions) + public IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IReadOnlyList<string> seriesKeys, DtoOptions dtoOptions) { // Avoid implicitly captured closure var currentUser = user; var allNextUp = seriesKeys - .Select(i => GetNextUp(i, currentUser, dtoOptions, request.Rewatching)); + .Select(i => GetNextUp(i, currentUser, dtoOptions, false)); + + if (request.EnableRewatching) + { + allNextUp = allNextUp.Concat( + seriesKeys.Select(i => GetNextUp(i, currentUser, dtoOptions, true)) + ) + .OrderByDescending(i => i.Item1); + } // If viewing all next up for all series, remove first episodes // But if that returns empty, keep those first episodes (avoid completely empty view) |
