SplashscreenPostScanTask.cs 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using Jellyfin.Data.Enums;
  7. using Jellyfin.Database.Implementations.Enums;
  8. using MediaBrowser.Controller.Drawing;
  9. using MediaBrowser.Controller.Dto;
  10. using MediaBrowser.Controller.Entities;
  11. using MediaBrowser.Controller.Library;
  12. using MediaBrowser.Controller.Persistence;
  13. using MediaBrowser.Model.Entities;
  14. using Microsoft.Extensions.Logging;
  15. namespace Emby.Server.Implementations.Library;
  16. /// <summary>
  17. /// The splashscreen post scan task.
  18. /// </summary>
  19. public class SplashscreenPostScanTask : ILibraryPostScanTask
  20. {
  21. private readonly IItemRepository _itemRepository;
  22. private readonly IImageEncoder _imageEncoder;
  23. private readonly ILogger<SplashscreenPostScanTask> _logger;
  24. /// <summary>
  25. /// Initializes a new instance of the <see cref="SplashscreenPostScanTask"/> class.
  26. /// </summary>
  27. /// <param name="itemRepository">Instance of the <see cref="IItemRepository"/> interface.</param>
  28. /// <param name="imageEncoder">Instance of the <see cref="IImageEncoder"/> interface.</param>
  29. /// <param name="logger">Instance of the <see cref="ILogger{SplashscreenPostScanTask}"/> interface.</param>
  30. public SplashscreenPostScanTask(
  31. IItemRepository itemRepository,
  32. IImageEncoder imageEncoder,
  33. ILogger<SplashscreenPostScanTask> logger)
  34. {
  35. _itemRepository = itemRepository;
  36. _imageEncoder = imageEncoder;
  37. _logger = logger;
  38. }
  39. /// <inheritdoc />
  40. public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
  41. {
  42. var posters = GetItemsWithImageType(ImageType.Primary)
  43. .Select(x => x.GetImages(ImageType.Primary).FirstOrDefault()?.Path)
  44. .Where(path => !string.IsNullOrEmpty(path))
  45. .Select(path => path!)
  46. .ToList();
  47. var backdrops = GetItemsWithImageType(ImageType.Thumb)
  48. .Select(x => x.GetImages(ImageType.Thumb).FirstOrDefault()?.Path)
  49. .Where(path => !string.IsNullOrEmpty(path))
  50. .Select(path => path!)
  51. .ToList();
  52. if (backdrops.Count == 0)
  53. {
  54. // Thumb images fit better because they include the title in the image but are not provided with TMDb.
  55. // Using backdrops as a fallback to generate an image at all
  56. _logger.LogDebug("No thumb images found. Using backdrops to generate splashscreen");
  57. backdrops = GetItemsWithImageType(ImageType.Backdrop)
  58. .Select(x => x.GetImages(ImageType.Backdrop).FirstOrDefault()?.Path)
  59. .Where(path => !string.IsNullOrEmpty(path))
  60. .Select(path => path!)
  61. .ToList();
  62. }
  63. _imageEncoder.CreateSplashscreen(posters, backdrops);
  64. return Task.CompletedTask;
  65. }
  66. private IReadOnlyList<BaseItem> GetItemsWithImageType(ImageType imageType)
  67. {
  68. // TODO make included libraries configurable
  69. return _itemRepository.GetItemList(new InternalItemsQuery
  70. {
  71. CollapseBoxSetItems = false,
  72. Recursive = true,
  73. DtoOptions = new DtoOptions(false),
  74. ImageTypes = [imageType],
  75. Limit = 30,
  76. // TODO max parental rating configurable
  77. MaxParentalRating = new(10, null),
  78. OrderBy =
  79. [
  80. (ItemSortBy.Random, SortOrder.Ascending)
  81. ],
  82. IncludeItemTypes = [BaseItemKind.Movie, BaseItemKind.Series]
  83. });
  84. }
  85. }