diff options
| author | Cody Robibero <cody@robibe.ro> | 2022-01-10 08:25:46 -0700 |
|---|---|---|
| committer | Cody Robibero <cody@robibe.ro> | 2022-01-10 08:26:30 -0700 |
| commit | ecb73168b34e3d58dff186b6d90fb4bdd192e24a (patch) | |
| tree | a973f42d5e77239077e967eef28105a30ada3fe3 | |
| parent | 360fd70fc74325008b031c9a1155b9b76724866d (diff) | |
Suggestions from review
| -rw-r--r-- | Emby.Drawing/NullImageEncoder.cs | 6 | ||||
| -rw-r--r-- | Emby.Server.Implementations/Library/SplashscreenPostScanTask.cs (renamed from Jellyfin.Drawing.Skia/DefaultImageGenerator.cs) | 51 | ||||
| -rw-r--r-- | Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs | 17 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/ImageController.cs | 21 | ||||
| -rw-r--r-- | Jellyfin.Drawing.Skia/SkiaEncoder.cs | 8 | ||||
| -rw-r--r-- | Jellyfin.Drawing.Skia/SplashscreenBuilder.cs | 14 | ||||
| -rw-r--r-- | Jellyfin.Server/CoreAppHost.cs | 3 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/IImageEncoder.cs | 7 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/IImageGenerator.cs | 22 |
9 files changed, 64 insertions, 85 deletions
diff --git a/Emby.Drawing/NullImageEncoder.cs b/Emby.Drawing/NullImageEncoder.cs index 1c05aa916..d0a26b713 100644 --- a/Emby.Drawing/NullImageEncoder.cs +++ b/Emby.Drawing/NullImageEncoder.cs @@ -44,6 +44,12 @@ namespace Emby.Drawing } /// <inheritdoc /> + public void CreateSplashscreen(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops) + { + throw new NotImplementedException(); + } + + /// <inheritdoc /> public string GetImageBlurHash(int xComp, int yComp, string path) { throw new NotImplementedException(); diff --git a/Jellyfin.Drawing.Skia/DefaultImageGenerator.cs b/Emby.Server.Implementations/Library/SplashscreenPostScanTask.cs index e102b8f49..65445d3af 100644 --- a/Jellyfin.Drawing.Skia/DefaultImageGenerator.cs +++ b/Emby.Server.Implementations/Library/SplashscreenPostScanTask.cs @@ -1,68 +1,65 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Jellyfin.Data.Enums; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using Microsoft.Extensions.Logging; -namespace Jellyfin.Drawing.Skia; +namespace Emby.Server.Implementations.Library; /// <summary> -/// The default image generator. +/// The splashscreen post scan task. /// </summary> -public class DefaultImageGenerator : IImageGenerator +public class SplashscreenPostScanTask : ILibraryPostScanTask { - private readonly IImageEncoder _imageEncoder; private readonly IItemRepository _itemRepository; - private readonly ILogger _logger; + private readonly IImageEncoder _imageEncoder; + private readonly ILogger<SplashscreenPostScanTask> _logger; /// <summary> - /// Initializes a new instance of the <see cref="DefaultImageGenerator"/> class. + /// Initializes a new instance of the <see cref="SplashscreenPostScanTask"/> class. /// </summary> - /// <param name="imageEncoder">Instance of the <see cref="IImageEncoder"/> interface.</param> /// <param name="itemRepository">Instance of the <see cref="IItemRepository"/> interface.</param> - /// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param> - public DefaultImageGenerator( - IImageEncoder imageEncoder, + /// <param name="imageEncoder">Instance of the <see cref="IImageEncoder"/> interface.</param> + /// <param name="logger">Instance of the <see cref="ILogger{SplashscreenPostScanTask"/> interface.</param> + public SplashscreenPostScanTask( IItemRepository itemRepository, - ILogger<DefaultImageGenerator> logger) + IImageEncoder imageEncoder, + ILogger<SplashscreenPostScanTask> logger) { - _imageEncoder = imageEncoder; _itemRepository = itemRepository; + _imageEncoder = imageEncoder; _logger = logger; } - /// <inheritdoc/> - public IReadOnlyList<GeneratedImageType> GetSupportedImages() - { - return new[] { GeneratedImageType.Splashscreen }; - } - - /// <inheritdoc/> - public void Generate(GeneratedImageType imageTypeType, string outputPath) + /// <inheritdoc /> + public Task Run(IProgress<double> progress, CancellationToken cancellationToken) { var posters = GetItemsWithImageType(ImageType.Primary).Select(x => x.GetImages(ImageType.Primary).First().Path).ToList(); - var landscape = GetItemsWithImageType(ImageType.Thumb).Select(x => x.GetImages(ImageType.Thumb).First().Path).ToList(); - if (landscape.Count == 0) + var backdrops = GetItemsWithImageType(ImageType.Thumb).Select(x => x.GetImages(ImageType.Thumb).First().Path).ToList(); + if (backdrops.Count == 0) { // Thumb images fit better because they include the title in the image but are not provided with TMDb. // Using backdrops as a fallback to generate an image at all _logger.LogDebug("No thumb images found. Using backdrops to generate splashscreen"); - landscape = GetItemsWithImageType(ImageType.Backdrop).Select(x => x.GetImages(ImageType.Backdrop).First().Path).ToList(); + backdrops = GetItemsWithImageType(ImageType.Backdrop).Select(x => x.GetImages(ImageType.Backdrop).First().Path).ToList(); } - var splashBuilder = new SplashscreenBuilder((SkiaEncoder)_imageEncoder); - splashBuilder.GenerateSplash(posters, landscape, outputPath); + _imageEncoder.CreateSplashscreen(posters, backdrops); + return Task.CompletedTask; } private IReadOnlyList<BaseItem> GetItemsWithImageType(ImageType imageType) { - // todo make included libraries configurable + // TODO make included libraries configurable return _itemRepository.GetItemList(new InternalItemsQuery { CollapseBoxSetItems = false, @@ -70,7 +67,7 @@ public class DefaultImageGenerator : IImageGenerator DtoOptions = new DtoOptions(false), ImageTypes = new[] { imageType }, Limit = 30, - // todo max parental rating configurable + // TODO max parental rating configurable MaxParentalRating = 10, OrderBy = new ValueTuple<string, SortOrder>[] { diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs index c12fc2113..7c27ae384 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs @@ -2,12 +2,9 @@ using System; using System.Collections.Generic; -using System.IO; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.Library; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Tasks; @@ -24,26 +21,16 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks /// </summary> private readonly ILibraryManager _libraryManager; private readonly ILocalizationManager _localization; - private readonly IImageGenerator _imageGenerator; - private readonly IApplicationPaths _applicationPaths; /// <summary> /// Initializes a new instance of the <see cref="RefreshMediaLibraryTask" /> class. /// </summary> /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param> /// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param> - /// <param name="imageGenerator">Instance of the <see cref="IImageGenerator"/> interface.</param> - /// <param name="applicationPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param> - public RefreshMediaLibraryTask( - ILibraryManager libraryManager, - ILocalizationManager localization, - IImageGenerator imageGenerator, - IApplicationPaths applicationPaths) + public RefreshMediaLibraryTask(ILibraryManager libraryManager, ILocalizationManager localization) { _libraryManager = libraryManager; _localization = localization; - _imageGenerator = imageGenerator; - _applicationPaths = applicationPaths; } /// <inheritdoc /> @@ -83,8 +70,6 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks progress.Report(0); - _imageGenerator.Generate(GeneratedImageType.Splashscreen, Path.Combine(_applicationPaths.DataPath, "splashscreen.webp")); - return ((LibraryManager)_libraryManager).ValidateMediaLibraryInternal(progress, cancellationToken); } } diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs index 6d34ca770..b44a21d03 100644 --- a/Jellyfin.Api/Controllers/ImageController.cs +++ b/Jellyfin.Api/Controllers/ImageController.cs @@ -48,7 +48,7 @@ namespace Jellyfin.Api.Controllers private readonly ILogger<ImageController> _logger; private readonly IServerConfigurationManager _serverConfigurationManager; private readonly IApplicationPaths _appPaths; - private readonly IImageGenerator _imageGenerator; + private readonly IImageEncoder _imageEncoder; /// <summary> /// Initializes a new instance of the <see cref="ImageController"/> class. @@ -62,7 +62,7 @@ namespace Jellyfin.Api.Controllers /// <param name="logger">Instance of the <see cref="ILogger{ImageController}"/> interface.</param> /// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> /// <param name="appPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param> - /// <param name="imageGenerator">Instance of the <see cref="IImageGenerator"/> interface.</param> + /// <param name="imageEncoder">Instance of the <see cref="IImageEncoder"/> interface.</param> public ImageController( IUserManager userManager, ILibraryManager libraryManager, @@ -73,7 +73,7 @@ namespace Jellyfin.Api.Controllers ILogger<ImageController> logger, IServerConfigurationManager serverConfigurationManager, IApplicationPaths appPaths, - IImageGenerator imageGenerator) + IImageEncoder imageEncoder) { _userManager = userManager; _libraryManager = libraryManager; @@ -84,7 +84,7 @@ namespace Jellyfin.Api.Controllers _logger = logger; _serverConfigurationManager = serverConfigurationManager; _appPaths = appPaths; - _imageGenerator = imageGenerator; + _imageEncoder = imageEncoder; } /// <summary> @@ -1737,19 +1737,20 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? foregroundLayer, [FromQuery, Range(0, 100)] int quality = 90) { - string splashscreenPath; var brandingOptions = _serverConfigurationManager.GetConfiguration<BrandingOptions>("branding"); - if (!string.IsNullOrWhiteSpace(brandingOptions.SplashscreenLocation)) + string splashscreenPath; + + if (!string.IsNullOrWhiteSpace(brandingOptions.SplashscreenLocation) + && System.IO.File.Exists(brandingOptions.SplashscreenLocation)) { - splashscreenPath = brandingOptions.SplashscreenLocation!; + splashscreenPath = brandingOptions.SplashscreenLocation; } else { splashscreenPath = Path.Combine(_appPaths.DataPath, "splashscreen.webp"); - - if (!System.IO.File.Exists(splashscreenPath) && _imageGenerator.GetSupportedImages().Contains(GeneratedImageType.Splashscreen)) + if (!System.IO.File.Exists(splashscreenPath)) { - _imageGenerator.Generate(GeneratedImageType.Splashscreen, splashscreenPath); + return NotFound(); } } diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs index 6d0a5ac2b..c40103f82 100644 --- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs +++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs @@ -492,6 +492,14 @@ namespace Jellyfin.Drawing.Skia } } + /// <inheritdoc /> + public void CreateSplashscreen(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops) + { + var splashBuilder = new SplashscreenBuilder(this); + var outputPath = Path.Combine(_appPaths.DataPath, "splashscreen.webp"); + splashBuilder.GenerateSplash(posters, backdrops, outputPath); + } + private void DrawIndicator(SKCanvas canvas, int imageWidth, int imageHeight, ImageProcessingOptions options) { try diff --git a/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs b/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs index 9f801c320..132c35e67 100644 --- a/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs +++ b/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs @@ -32,12 +32,12 @@ namespace Jellyfin.Drawing.Skia /// Generate a splashscreen. /// </summary> /// <param name="posters">The poster paths.</param> - /// <param name="backdrop">The landscape paths.</param> + /// <param name="backdrops">The landscape paths.</param> /// <param name="outputPath">The output path.</param> - public void GenerateSplash(IReadOnlyList<string> posters, IReadOnlyList<string> backdrop, string outputPath) + public void GenerateSplash(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops, string outputPath) { - var wall = GenerateCollage(posters, backdrop); - var transformed = Transform3D(wall); + using var wall = GenerateCollage(posters, backdrops); + using var transformed = Transform3D(wall); using var outputStream = new SKFileWStream(outputPath); using var pixmap = new SKPixmap(new SKImageInfo(FinalWidth, FinalHeight), transformed.GetPixels()); @@ -48,9 +48,9 @@ namespace Jellyfin.Drawing.Skia /// Generates a collage of posters and landscape pictures. /// </summary> /// <param name="posters">The poster paths.</param> - /// <param name="backdrop">The landscape paths.</param> + /// <param name="backdrops">The landscape paths.</param> /// <returns>The created collage as a bitmap.</returns> - private SKBitmap GenerateCollage(IReadOnlyList<string> posters, IReadOnlyList<string> backdrop) + private SKBitmap GenerateCollage(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops) { var random = new Random(); @@ -82,7 +82,7 @@ namespace Jellyfin.Drawing.Skia posterIndex = newPosterIndex; break; default: - currentImage = SkiaHelper.GetNextValidImage(_skiaEncoder, backdrop, backdropIndex, out int newBackdropIndex); + currentImage = SkiaHelper.GetNextValidImage(_skiaEncoder, backdrops, backdropIndex, out int newBackdropIndex); backdropIndex = newBackdropIndex; break; } diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index b2f9a518a..67e50b92d 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -85,9 +85,6 @@ namespace Jellyfin.Server serviceCollection.AddSingleton<IDisplayPreferencesManager, DisplayPreferencesManager>(); serviceCollection.AddSingleton<IDeviceManager, DeviceManager>(); - // TODO search plugins - serviceCollection.AddSingleton<IImageGenerator, DefaultImageGenerator>(); - // TODO search the assemblies instead of adding them manually? serviceCollection.AddSingleton<IWebSocketListener, SessionWebSocketListener>(); serviceCollection.AddSingleton<IWebSocketListener, ActivityLogWebSocketListener>(); diff --git a/MediaBrowser.Controller/Drawing/IImageEncoder.cs b/MediaBrowser.Controller/Drawing/IImageEncoder.cs index 4e67cfee4..e5c8ebfaf 100644 --- a/MediaBrowser.Controller/Drawing/IImageEncoder.cs +++ b/MediaBrowser.Controller/Drawing/IImageEncoder.cs @@ -74,5 +74,12 @@ namespace MediaBrowser.Controller.Drawing /// <param name="options">The options to use when creating the collage.</param> /// <param name="libraryName">Optional. </param> void CreateImageCollage(ImageCollageOptions options, string? libraryName); + + /// <summary> + /// Creates a new splashscreen image. + /// </summary> + /// <param name="posters">The list of poster paths.</param> + /// <param name="backdrops">The list of backdrop paths.</param> + void CreateSplashscreen(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops); } } diff --git a/MediaBrowser.Controller/Drawing/IImageGenerator.cs b/MediaBrowser.Controller/Drawing/IImageGenerator.cs deleted file mode 100644 index 773db02cb..000000000 --- a/MediaBrowser.Controller/Drawing/IImageGenerator.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; - -namespace MediaBrowser.Controller.Drawing; - -/// <summary> -/// Interface for an image generator. -/// </summary> -public interface IImageGenerator -{ - /// <summary> - /// Gets the supported generated images of the image generator. - /// </summary> - /// <returns>The supported generated image types.</returns> - IReadOnlyList<GeneratedImageType> GetSupportedImages(); - - /// <summary> - /// Generates a splashscreen. - /// </summary> - /// <param name="imageTypeType">The image to generate.</param> - /// <param name="outputPath">The path where the splashscreen should be saved.</param> - void Generate(GeneratedImageType imageTypeType, string outputPath); -} |
