diff options
| author | TheMelmacian <76712303+TheMelmacian@users.noreply.github.com> | 2026-05-25 23:40:40 +0200 |
|---|---|---|
| committer | TheMelmacian <76712303+TheMelmacian@users.noreply.github.com> | 2026-05-30 16:33:59 +0200 |
| commit | 7939f3b009e830e38a3f37455418011043429ee3 (patch) | |
| tree | 1436c149f12c271c13fa9328757268644ddf3758 | |
| parent | 2a95223c6718bf8892369322b8a30a45e430739f (diff) | |
only fetch language codes for the requested library when generating filter values
5 files changed, 105 insertions, 3 deletions
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index cc85f09d23..f075d2f649 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -3862,5 +3862,17 @@ namespace Emby.Server.Implementations.Library { return _mediaStreamRepository.GetMediaStreamLanguages(mediaStreamType); } + + /// <inheritdoc /> + public IReadOnlyList<string> GetMediaStreamLanguages(MediaStreamType mediaStreamType, InternalItemsQuery query) + { + if (query.User is not null) + { + AddUserToQuery(query, query.User); + } + + SetTopParentOrAncestorIds(query); + return _itemRepository.GetMediaStreamLanguages(query, mediaStreamType); + } } } diff --git a/Jellyfin.Api/Controllers/FilterController.cs b/Jellyfin.Api/Controllers/FilterController.cs index cfc8be28ae..07ebe83e86 100644 --- a/Jellyfin.Api/Controllers/FilterController.cs +++ b/Jellyfin.Api/Controllers/FilterController.cs @@ -158,13 +158,42 @@ public class FilterController : BaseJellyfinApiController IsSeries = isSeries }; + var streamLanguageQuery = new InternalItemsQuery(user) + { + // It's possible that different langauges are only available on alternative versions. + // To fetch them all, owned items are inlcluded. + IncludeOwnedItems = true, + IncludeItemTypes = includeItemTypes, + DtoOptions = new DtoOptions + { + Fields = Array.Empty<ItemFields>(), + EnableImages = false, + EnableUserData = false + }, + IsAiring = isAiring, + IsMovie = isMovie, + IsSports = isSports, + IsKids = isKids, + IsNews = isNews, + IsSeries = isSeries + }; + if ((recursive ?? true) || parentItem is UserView || parentItem is ICollectionFolder) { genreQuery.AncestorIds = parentItem is null ? Array.Empty<Guid>() : new[] { parentItem.Id }; + streamLanguageQuery.AncestorIds = parentItem is null ? Array.Empty<Guid>() : new[] { parentItem.Id }; } else { genreQuery.Parent = parentItem; + streamLanguageQuery.Parent = parentItem; + } + + if ((includeItemTypes.Contains(BaseItemKind.Series) || includeItemTypes.Contains(BaseItemKind.Season)) + && !includeItemTypes.Contains(BaseItemKind.Episode)) + { + // streams are joined on epsiodes not shows or seasons + streamLanguageQuery.IncludeItemTypes = [..includeItemTypes, BaseItemKind.Episode]; } if (includeItemTypes.Length == 1 @@ -188,10 +217,13 @@ public class FilterController : BaseJellyfinApiController }).ToArray(); } - if (includeItemTypes.Contains(BaseItemKind.Movie) || includeItemTypes.Contains(BaseItemKind.Series)) + if (includeItemTypes.Contains(BaseItemKind.Movie) + || includeItemTypes.Contains(BaseItemKind.Series) + || includeItemTypes.Contains(BaseItemKind.Season) + || includeItemTypes.Contains(BaseItemKind.Episode)) { filters.AudioLanguages = _libraryManager - .GetMediaStreamLanguages(MediaStreamType.Audio) + .GetMediaStreamLanguages(MediaStreamType.Audio, streamLanguageQuery) .Select(language => { var culture = _localization.FindLanguageInfo(language); @@ -204,7 +236,7 @@ public class FilterController : BaseJellyfinApiController .OrderBy(l => l.Name) .ToArray(); filters.SubtitleLanguages = _libraryManager - .GetMediaStreamLanguages(MediaStreamType.Subtitle) + .GetMediaStreamLanguages(MediaStreamType.Subtitle, streamLanguageQuery) .Select(language => { var culture = _localization.FindLanguageInfo(language); diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.ByName.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.ByName.cs index e4fd3204e1..00ffd984f5 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.ByName.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.ByName.cs @@ -7,6 +7,7 @@ using Jellyfin.Data.Enums; using Jellyfin.Database.Implementations.Entities; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using Microsoft.EntityFrameworkCore; using BaseItemDto = MediaBrowser.Controller.Entities.BaseItem; @@ -81,6 +82,46 @@ public sealed partial class BaseItemRepository _itemTypeLookup.MusicGenreTypes); } + /// <inheritdoc /> + public IReadOnlyList<string> GetMediaStreamLanguages(InternalItemsQuery filter, MediaStreamType mediaStreamType) + { + ArgumentNullException.ThrowIfNull(filter); + + if (!filter.Limit.HasValue) + { + filter.EnableTotalRecordCount = false; + } + + using var context = _dbProvider.CreateDbContext(); + + return TranslateQuery( + context.BaseItems.Include(e => e.MediaStreams).Where(e => e.Id != EF.Constant(PlaceholderId)), + context, + new InternalItemsQuery(filter.User) + { + IncludeOwnedItems = filter.IncludeOwnedItems, + ExcludeItemTypes = filter.ExcludeItemTypes, + IncludeItemTypes = filter.IncludeItemTypes, + MediaTypes = filter.MediaTypes, + AncestorIds = filter.AncestorIds, + ItemIds = filter.ItemIds, + TopParentIds = filter.TopParentIds, + ParentId = filter.ParentId, + IsAiring = filter.IsAiring, + IsMovie = filter.IsMovie, + IsSports = filter.IsSports, + IsKids = filter.IsKids, + IsNews = filter.IsNews, + IsSeries = filter.IsSeries + }) + .Where(e => e.MediaStreams != null) + .SelectMany(e => e.MediaStreams!) + .Where(e => e.StreamType == (MediaStreamTypeEntity)mediaStreamType) + .Select(s => string.IsNullOrEmpty(s.Language) ? "und" : s.Language) // und = undetermined + .Distinct() + .ToArray(); + } + private string[] GetItemValueNames(IReadOnlyList<ItemValueType> itemValueTypes, IReadOnlyList<string> withItemTypes, IReadOnlyList<string> excludeItemTypes) { using var context = _dbProvider.CreateDbContext(); diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index c23eba75ef..c37b13ea4f 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -800,5 +800,13 @@ namespace MediaBrowser.Controller.Library /// <param name="mediaStreamType">The stream type.</param> /// <returns>List of language codes.</returns> IReadOnlyList<string> GetMediaStreamLanguages(MediaStreamType mediaStreamType); + + /// <summary> + /// Gets a list of all language codes for the matching items and the the provided stream type. + /// </summary> + /// <param name="mediaStreamType">The stream type.</param> + /// <param name="query">The query filter.</param> + /// <returns>List of language codes.</returns> + IReadOnlyList<string> GetMediaStreamLanguages(MediaStreamType mediaStreamType, InternalItemsQuery query); } } diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 291916ab25..d44fe57bed 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -7,6 +7,7 @@ using Jellyfin.Data.Enums; using Jellyfin.Database.Implementations.Entities; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Persistence; @@ -120,6 +121,14 @@ public interface IItemRepository IReadOnlyList<string> GetGenreNames(); /// <summary> + /// Gets all language codes of the matching base items and the provided stream type. + /// </summary> + /// <param name="filter">The query filter.</param> + /// <param name="mediaStreamType">The type of the media stream.</param> + /// <returns>List of language codes.</returns> + public IReadOnlyList<string> GetMediaStreamLanguages(InternalItemsQuery filter, MediaStreamType mediaStreamType); + + /// <summary> /// Gets all artist names. /// </summary> /// <returns>The list of artist names.</returns> |
