| 
					
				 | 
			
			
				@@ -7,9 +7,9 @@ using System.Collections.Generic; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Globalization; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.IO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Linq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-using System.Threading.Tasks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Jellyfin.Data.Entities; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Jellyfin.Data.Enums; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using Jellyfin.Extensions; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Common; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Controller.Channels; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Controller.Drawing; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -51,8 +51,6 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private readonly IMediaSourceManager _mediaSourceManager; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private readonly Lazy<ILiveTvManager> _livetvManagerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private ILiveTvManager LivetvManager => _livetvManagerFactory.Value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public DtoService( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ILogger<DtoService> logger, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ILibraryManager libraryManager, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -75,6 +73,8 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             _livetvManagerFactory = livetvManagerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private ILiveTvManager LivetvManager => _livetvManagerFactory.Value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <inheritdoc /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public IReadOnlyList<BaseItemDto> GetBaseItemDtos(IReadOnlyList<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -134,14 +134,11 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var dto = GetBaseItemDtoInternal(item, options, user, owner); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (item is LiveTvChannel tvChannel) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var list = new List<(BaseItemDto, LiveTvChannel)>(1) { (dto, tvChannel) }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                LivetvManager.AddChannelInfo(list, options, user); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                LivetvManager.AddChannelInfo(new[] { (dto, tvChannel) }, options, user); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else if (item is LiveTvProgram) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var list = new List<(BaseItem, BaseItemDto)>(1) { (item, dto) }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var task = LivetvManager.AddInfoToProgramDto(list, options.Fields, user); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Task.WaitAll(task); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                LivetvManager.AddInfoToProgramDto(new[] { (item, dto) }, options.Fields, user).GetAwaiter().GetResult(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (item is IItemByName itemByName 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -297,7 +294,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             path = path.TrimStart('.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if (!string.IsNullOrEmpty(path) && containers.Contains(path, StringComparer.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (!string.IsNullOrEmpty(path) && containers.Contains(path, StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             fileExtensionContainer = path; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -373,6 +370,12 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if (item is MusicAlbum || item is Season || item is Playlist) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         dto.ChildCount = dto.RecursiveItemCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var folderChildCount = folder.LinkedChildren.Length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        // The default is an empty array, so we can't reliably use the count when it's empty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (folderChildCount > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            dto.ChildCount ??= folderChildCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if (options.ContainsField(ItemFields.ChildCount)) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -420,7 +423,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // Just return something so that apps that are expecting a value won't think the folders are empty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (folder is ICollectionFolder || folder is UserView) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return new Random().Next(1, 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return Random.Shared.Next(1, 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return folder.GetChildCount(user); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -467,7 +470,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 var parentAlbumIds = _libraryManager.GetItemIds(new InternalItemsQuery 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    IncludeItemTypes = new[] { nameof(MusicAlbum) }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    IncludeItemTypes = new[] { BaseItemKind.MusicAlbum }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     Name = item.Album, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     Limit = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 }); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -497,7 +500,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             catch (Exception ex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                _logger.LogError(ex, "Error getting {imageType} image info for {path}", image.Type, image.Path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _logger.LogError(ex, "Error getting {ImageType} image info for {Path}", image.Type, image.Path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -507,7 +510,6 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <param name="dto">The dto.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <param name="item">The item.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <returns>Task.</returns> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private void AttachPeople(BaseItemDto dto, BaseItem item) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // Ordering by person type to ensure actors and artists are at the front. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -616,7 +618,6 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <param name="dto">The dto.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <param name="item">The item.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <returns>Task.</returns> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private void AttachStudios(BaseItemDto dto, BaseItem item) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dto.Studios = item.Studios 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -757,15 +758,6 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.BackdropImageTags = GetTagsAndFillBlurhashes(dto, item, ImageType.Backdrop, backdropLimit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (options.ContainsField(ItemFields.ScreenshotImageTags)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var screenshotLimit = options.GetImageLimit(ImageType.Screenshot); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (screenshotLimit > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    dto.ScreenshotImageTags = GetTagsAndFillBlurhashes(dto, item, ImageType.Screenshot, screenshotLimit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (options.ContainsField(ItemFields.Genres)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.Genres = item.Genres; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -807,7 +799,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dto.MediaType = item.MediaType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!(item is LiveTvProgram)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (item is not LiveTvProgram) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.LocationType = item.LocationType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -928,9 +920,9 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // if (options.ContainsField(ItemFields.MediaSourceCount)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // Songs always have one 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (item is IHasArtist hasArtist) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -938,10 +930,10 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.Artists = hasArtist.Artists; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // var artistItems = _libraryManager.GetArtists(new InternalItemsQuery 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //    EnableTotalRecordCount = false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //    ItemIds = new[] { item.Id.ToString("N", CultureInfo.InvariantCulture) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // dto.ArtistItems = artistItems.Items 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //    .Select(i => 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -958,7 +950,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // Include artists that are not in the database yet, e.g., just added via metadata editor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // var foundArtists = artistItems.Items.Select(i => i.Item1.Name).ToList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.ArtistItems = hasArtist.Artists 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    //.Except(foundArtists, new DistinctNameComparer()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // .Except(foundArtists, new DistinctNameComparer()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     .Select(i => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         // This should not be necessary but we're seeing some cases of it 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -990,10 +982,10 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // var artistItems = _libraryManager.GetAlbumArtists(new InternalItemsQuery 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //    EnableTotalRecordCount = false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //    ItemIds = new[] { item.Id.ToString("N", CultureInfo.InvariantCulture) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // dto.AlbumArtists = artistItems.Items 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //    .Select(i => 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1008,7 +1000,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //    .ToList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.AlbumArtists = hasAlbumArtist.AlbumArtists 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    //.Except(foundArtists, new DistinctNameComparer()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // .Except(foundArtists, new DistinctNameComparer()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     .Select(i => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         // This should not be necessary but we're seeing some cases of it 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1035,8 +1027,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // Add video info 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var video = item as Video; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (video != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (item is Video video) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.VideoType = video.VideoType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.Video3DFormat = video.Video3DFormat; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1075,9 +1066,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (options.ContainsField(ItemFields.MediaStreams)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // Add VideoInfo 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var iHasMediaSources = item as IHasMediaSources; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (iHasMediaSources != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (item is IHasMediaSources) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     MediaStream[] mediaStreams; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1146,7 +1135,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // TODO maybe remove the if statement entirely 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // if (options.ContainsField(ItemFields.SeriesPrimaryImage)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    episodeSeries = episodeSeries ?? episode.Series; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    episodeSeries ??= episode.Series; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if (episodeSeries != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         dto.SeriesPrimaryImageTag = GetTagAndFillBlurhash(dto, episodeSeries, ImageType.Primary); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1159,7 +1148,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (options.ContainsField(ItemFields.SeriesStudio)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    episodeSeries = episodeSeries ?? episode.Series; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    episodeSeries ??= episode.Series; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if (episodeSeries != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         dto.SeriesStudio = episodeSeries.Studios.FirstOrDefault(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1172,7 +1161,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.AirDays = series.AirDays; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 dto.AirTime = series.AirTime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                dto.Status = series.Status.HasValue ? series.Status.Value.ToString() : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                dto.Status = series.Status?.ToString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // Add SeasonInfo 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1185,7 +1174,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (options.ContainsField(ItemFields.SeriesStudio)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    series = series ?? season.Series; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    series ??= season.Series; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if (series != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         dto.SeriesStudio = series.Studios.FirstOrDefault(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1196,7 +1185,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // TODO maybe remove the if statement entirely 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // if (options.ContainsField(ItemFields.SeriesPrimaryImage)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    series = series ?? season.Series; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    series ??= season.Series; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if (series != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         dto.SeriesPrimaryImageTag = GetTagAndFillBlurhash(dto, series, ImageType.Primary); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1283,7 +1272,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var parent = currentItem.DisplayParent ?? currentItem.GetOwner() ?? currentItem.GetParent(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (parent == null && !(originalItem is UserRootFolder) && !(originalItem is UserView) && !(originalItem is AggregateFolder) && !(originalItem is ICollectionFolder) && !(originalItem is Channel)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (parent == null && originalItem is not UserRootFolder && originalItem is not UserView && originalItem is not AggregateFolder && originalItem is not ICollectionFolder && originalItem is not Channel) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 parent = _libraryManager.GetCollectionFolders(originalItem).FirstOrDefault(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1316,9 +1305,12 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var imageTags = dto.ImageTags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            while (((!(imageTags != null && imageTags.ContainsKey(ImageType.Logo)) && logoLimit > 0) || (!(imageTags != null && imageTags.ContainsKey(ImageType.Art)) && artLimit > 0) || (!(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && thumbLimit > 0) || parent is Series) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                (parent = parent ?? (isFirst ? GetImageDisplayParent(item, item) ?? owner : parent)) != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while ((!(imageTags != null && imageTags.ContainsKey(ImageType.Logo)) && logoLimit > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || (!(imageTags != null && imageTags.ContainsKey(ImageType.Art)) && artLimit > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || (!(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && thumbLimit > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || parent is Series) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                parent ??= isFirst ? GetImageDisplayParent(item, item) ?? owner : parent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (parent == null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     break; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1348,7 +1340,7 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (thumbLimit > 0 && !(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && (dto.ParentThumbItemId == null || parent is Series) && !(parent is ICollectionFolder) && !(parent is UserView)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (thumbLimit > 0 && !(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && (dto.ParentThumbItemId == null || parent is Series) && parent is not ICollectionFolder && parent is not UserView) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     var image = allImages.FirstOrDefault(i => i.Type == ImageType.Thumb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1398,7 +1390,6 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <param name="dto">The dto.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <param name="item">The item.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <returns>Task.</returns> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dto.PrimaryImageAspectRatio = GetPrimaryImageAspectRatio(item); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1413,44 +1404,27 @@ namespace Emby.Server.Implementations.Dto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ImageDimensions size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var defaultAspectRatio = item.GetDefaultPrimaryImageAspectRatio(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (defaultAspectRatio > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return defaultAspectRatio; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (!imageInfo.IsLocalFile) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return item.GetDefaultPrimaryImageAspectRatio(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                size = _imageProcessor.GetImageDimensions(item, imageInfo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (size.Width <= 0 || size.Height <= 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var size = _imageProcessor.GetImageDimensions(item, imageInfo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var width = size.Width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var height = size.Height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (width > 0 && height > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return (double)width / height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             catch (Exception ex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                _logger.LogError(ex, "Failed to determine primary image aspect ratio for {0}", imageInfo.Path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var width = size.Width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var height = size.Height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (width <= 0 || height <= 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _logger.LogError(ex, "Failed to determine primary image aspect ratio for {ImagePath}", imageInfo.Path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return (double)width / height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return item.GetDefaultPrimaryImageAspectRatio(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |