浏览代码

Register and construct IImageProcessor, SqliteItemRepository and IImageEncoder correctly

Mark Monteiro 5 年之前
父节点
当前提交
07cebbeae2

+ 4 - 4
Emby.Drawing/ImageProcessor.cs

@@ -33,7 +33,7 @@ namespace Emby.Drawing
         private readonly IFileSystem _fileSystem;
         private readonly IServerApplicationPaths _appPaths;
         private readonly IImageEncoder _imageEncoder;
-        private readonly Func<IMediaEncoder> _mediaEncoder;
+        private readonly IMediaEncoder _mediaEncoder;
 
         private bool _disposed = false;
 
@@ -50,7 +50,7 @@ namespace Emby.Drawing
             IServerApplicationPaths appPaths,
             IFileSystem fileSystem,
             IImageEncoder imageEncoder,
-            Func<IMediaEncoder> mediaEncoder)
+            IMediaEncoder mediaEncoder)
         {
             _logger = logger;
             _fileSystem = fileSystem;
@@ -359,13 +359,13 @@ namespace Emby.Drawing
                 {
                     string filename = (originalImagePath + dateModified.Ticks.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("N", CultureInfo.InvariantCulture);
 
-                    string cacheExtension = _mediaEncoder().SupportsEncoder("libwebp") ? ".webp" : ".png";
+                    string cacheExtension = _mediaEncoder.SupportsEncoder("libwebp") ? ".webp" : ".png";
                     var outputPath = Path.Combine(_appPaths.ImageCachePath, "converted-images", filename + cacheExtension);
 
                     var file = _fileSystem.GetFileInfo(outputPath);
                     if (!file.Exists)
                     {
-                        await _mediaEncoder().ConvertImage(originalImagePath, outputPath).ConfigureAwait(false);
+                        await _mediaEncoder.ConvertImage(originalImagePath, outputPath).ConfigureAwait(false);
                         dateModified = _fileSystem.GetLastWriteTimeUtc(outputPath);
                     }
                     else

+ 14 - 19
Emby.Server.Implementations/ApplicationHost.cs

@@ -48,6 +48,7 @@ using Emby.Server.Implementations.Session;
 using Emby.Server.Implementations.SocketSharp;
 using Emby.Server.Implementations.TV;
 using Emby.Server.Implementations.Updates;
+using Jellyfin.Drawing.Skia;
 using MediaBrowser.Api;
 using MediaBrowser.Common;
 using MediaBrowser.Common.Configuration;
@@ -262,8 +263,6 @@ namespace Emby.Server.Implementations
         /// <value>The directory watchers.</value>
         private ILibraryMonitor LibraryMonitor { get; set; }
 
-        public IImageProcessor ImageProcessor { get; set; }
-
         /// <summary>
         /// Gets or sets the media encoder.
         /// </summary>
@@ -278,8 +277,6 @@ namespace Emby.Server.Implementations
         /// <value>The user data repository.</value>
         private IUserDataManager UserDataManager { get; set; }
 
-        internal SqliteItemRepository ItemRepository { get; set; }
-
         private IAuthenticationRepository AuthenticationRepository { get; set; }
 
         /// <summary>
@@ -290,8 +287,6 @@ namespace Emby.Server.Implementations
 
         public IStartupOptions StartupOptions { get; }
 
-        internal IImageEncoder ImageEncoder { get; private set; }
-
         protected IProcessFactory ProcessFactory { get; private set; }
 
         protected readonly IXmlSerializer XmlSerializer;
@@ -316,7 +311,6 @@ namespace Emby.Server.Implementations
             ILoggerFactory loggerFactory,
             IStartupOptions options,
             IFileSystem fileSystem,
-            IImageEncoder imageEncoder,
             INetworkManager networkManager)
         {
             XmlSerializer = new MyXmlSerializer();
@@ -334,8 +328,6 @@ namespace Emby.Server.Implementations
 
             StartupOptions = options;
 
-            ImageEncoder = imageEncoder;
-
             fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
 
             NetworkManager.NetworkChanged += OnNetworkChanged;
@@ -603,6 +595,11 @@ namespace Emby.Server.Implementations
         /// </summary>
         protected async Task RegisterServices(IServiceCollection serviceCollection, IConfiguration startupConfig)
         {
+            var imageEncoderType = SkiaEncoder.IsNativeLibAvailable()
+                ? typeof(SkiaEncoder)
+                : typeof(NullImageEncoder);
+            serviceCollection.AddSingleton(typeof(IImageEncoder), imageEncoderType);
+
             serviceCollection.AddMemoryCache();
 
             serviceCollection.AddSingleton(ConfigurationManager);
@@ -672,8 +669,7 @@ namespace Emby.Server.Implementations
                 FileSystemManager);
             serviceCollection.AddSingleton<IDisplayPreferencesRepository>(_displayPreferencesRepository);
 
-            ItemRepository = new SqliteItemRepository(ServerConfigurationManager, this, LoggerFactory.CreateLogger<SqliteItemRepository>(), LocalizationManager);
-            serviceCollection.AddSingleton<IItemRepository>(ItemRepository);
+            serviceCollection.AddSingleton<IItemRepository, SqliteItemRepository>();
 
             AuthenticationRepository = GetAuthenticationRepository();
             serviceCollection.AddSingleton(AuthenticationRepository);
@@ -685,7 +681,7 @@ namespace Emby.Server.Implementations
                 _userRepository,
                 XmlSerializer,
                 NetworkManager,
-                () => ImageProcessor,
+                Resolve<IImageProcessor>,
                 Resolve<IDtoService>,
                 this,
                 JsonSerializer,
@@ -723,8 +719,7 @@ namespace Emby.Server.Implementations
             serviceCollection.AddSingleton<IHttpListener, WebSocketSharpListener>();
             serviceCollection.AddSingleton<IHttpServer, HttpListenerHost>();
 
-            ImageProcessor = new ImageProcessor(LoggerFactory.CreateLogger<ImageProcessor>(), ServerConfigurationManager.ApplicationPaths, FileSystemManager, ImageEncoder, () => MediaEncoder);
-            serviceCollection.AddSingleton(ImageProcessor);
+            serviceCollection.AddSingleton<IImageProcessor, ImageProcessor>();
 
             serviceCollection.AddSingleton<ITVSeriesManager, TVSeriesManager>();
 
@@ -797,8 +792,10 @@ namespace Emby.Server.Implementations
             ((UserManager)UserManager).Initialize();
 
             ((UserDataManager)UserDataManager).Repository = userDataRepo;
-            ItemRepository.Initialize(userDataRepo, UserManager);
-            ((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
+
+            var itemRepo = (SqliteItemRepository)Resolve<IItemRepository>();
+            itemRepo.Initialize(userDataRepo, UserManager);
+            ((LibraryManager)LibraryManager).ItemRepository = itemRepo;
 
             FindParts();
         }
@@ -898,15 +895,13 @@ namespace Emby.Server.Implementations
         /// </summary>
         private void SetStaticProperties()
         {
-            ItemRepository.ImageProcessor = ImageProcessor;
-
             // For now there's no real way to inject these properly
             BaseItem.Logger = LoggerFactory.CreateLogger("BaseItem");
             BaseItem.ConfigurationManager = ServerConfigurationManager;
             BaseItem.LibraryManager = LibraryManager;
             BaseItem.ProviderManager = Resolve<IProviderManager>();
             BaseItem.LocalizationManager = LocalizationManager;
-            BaseItem.ItemRepository = ItemRepository;
+            BaseItem.ItemRepository = Resolve<IItemRepository>();
             User.UserManager = UserManager;
             BaseItem.FileSystem = FileSystemManager;
             BaseItem.UserDataManager = UserDataManager;

+ 6 - 7
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -39,12 +39,11 @@ namespace Emby.Server.Implementations.Data
     {
         private const string ChaptersTableName = "Chapters2";
 
-        /// <summary>
-        /// The _app paths
-        /// </summary>
         private readonly IServerConfigurationManager _config;
         private readonly IServerApplicationHost _appHost;
         private readonly ILocalizationManager _localization;
+        // TODO: Remove this dependency
+        private readonly IImageProcessor _imageProcessor;
 
         private readonly TypeMapper _typeMapper;
         private readonly JsonSerializerOptions _jsonOptions;
@@ -71,7 +70,8 @@ namespace Emby.Server.Implementations.Data
             IServerConfigurationManager config,
             IServerApplicationHost appHost,
             ILogger<SqliteItemRepository> logger,
-            ILocalizationManager localization)
+            ILocalizationManager localization,
+            IImageProcessor imageProcessor)
             : base(logger)
         {
             if (config == null)
@@ -82,6 +82,7 @@ namespace Emby.Server.Implementations.Data
             _config = config;
             _appHost = appHost;
             _localization = localization;
+            _imageProcessor = imageProcessor;
 
             _typeMapper = new TypeMapper();
             _jsonOptions = JsonDefaults.GetOptions();
@@ -98,8 +99,6 @@ namespace Emby.Server.Implementations.Data
         /// <inheritdoc />
         protected override TempStoreMode TempStore => TempStoreMode.Memory;
 
-        public IImageProcessor ImageProcessor { get; set; }
-
         /// <summary>
         /// Opens the connection to the database
         /// </summary>
@@ -1991,7 +1990,7 @@ namespace Emby.Server.Implementations.Data
 
                 if (!string.IsNullOrEmpty(chapter.ImagePath))
                 {
-                    chapter.ImageTag = ImageProcessor.GetImageCacheTag(item, chapter);
+                    chapter.ImageTag = _imageProcessor.GetImageCacheTag(item, chapter);
                 }
             }
 

+ 1 - 0
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -4,6 +4,7 @@
     <ProjectReference Include="..\Emby.Naming\Emby.Naming.csproj" />
     <ProjectReference Include="..\Emby.Notifications\Emby.Notifications.csproj" />
     <ProjectReference Include="..\Jellyfin.Api\Jellyfin.Api.csproj" />
+    <ProjectReference Include="..\Jellyfin.Drawing.Skia\Jellyfin.Drawing.Skia.csproj" />
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
     <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
     <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />

+ 13 - 4
Jellyfin.Drawing.Skia/SkiaEncoder.cs

@@ -78,12 +78,21 @@ namespace Jellyfin.Drawing.Skia
             => new HashSet<ImageFormat>() { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png };
 
         /// <summary>
-        /// Test to determine if the native lib is available.
+        /// Check if the native lib is available.
         /// </summary>
-        public static void TestSkia()
+        /// <returns>True if the native lib is available, otherwise false.</returns>
+        public static bool IsNativeLibAvailable()
         {
-            // test an operation that requires the native library
-            SKPMColor.PreMultiply(SKColors.Black);
+            try
+            {
+                // test an operation that requires the native library
+                SKPMColor.PreMultiply(SKColors.Black);
+                return true;
+            }
+            catch (Exception)
+            {
+                return false;
+            }
         }
 
         private static bool IsTransparent(SKColor color)

+ 0 - 3
Jellyfin.Server/CoreAppHost.cs

@@ -20,21 +20,18 @@ namespace Jellyfin.Server
         /// <param name="loggerFactory">The <see cref="ILoggerFactory" /> to be used by the <see cref="CoreAppHost" />.</param>
         /// <param name="options">The <see cref="StartupOptions" /> to be used by the <see cref="CoreAppHost" />.</param>
         /// <param name="fileSystem">The <see cref="IFileSystem" /> to be used by the <see cref="CoreAppHost" />.</param>
-        /// <param name="imageEncoder">The <see cref="IImageEncoder" /> to be used by the <see cref="CoreAppHost" />.</param>
         /// <param name="networkManager">The <see cref="INetworkManager" /> to be used by the <see cref="CoreAppHost" />.</param>
         public CoreAppHost(
             ServerApplicationPaths applicationPaths,
             ILoggerFactory loggerFactory,
             StartupOptions options,
             IFileSystem fileSystem,
-            IImageEncoder imageEncoder,
             INetworkManager networkManager)
             : base(
                 applicationPaths,
                 loggerFactory,
                 options,
                 fileSystem,
-                imageEncoder,
                 networkManager)
         {
         }

+ 0 - 20
Jellyfin.Server/Program.cs

@@ -183,7 +183,6 @@ namespace Jellyfin.Server
                 _loggerFactory,
                 options,
                 new ManagedFileSystem(_loggerFactory.CreateLogger<ManagedFileSystem>(), appPaths),
-                GetImageEncoder(appPaths),
                 new NetworkManager(_loggerFactory.CreateLogger<NetworkManager>()));
 
             try
@@ -553,25 +552,6 @@ namespace Jellyfin.Server
             }
         }
 
-        private static IImageEncoder GetImageEncoder(IApplicationPaths appPaths)
-        {
-            try
-            {
-                // Test if the native lib is available
-                SkiaEncoder.TestSkia();
-
-                return new SkiaEncoder(
-                    _loggerFactory.CreateLogger<SkiaEncoder>(),
-                    appPaths);
-            }
-            catch (Exception ex)
-            {
-                _logger.LogWarning(ex, $"Skia not available. Will fallback to {nameof(NullImageEncoder)}.");
-            }
-
-            return new NullImageEncoder();
-        }
-
         private static void StartNewInstance(StartupOptions options)
         {
             _logger.LogInformation("Starting new instance");