Prechádzať zdrojové kódy

added encoding manager interface

Luke Pulverenti 11 rokov pred
rodič
commit
888b8d619a
30 zmenil súbory, kde vykonal 223 pridanie a 290 odobranie
  1. 0 1
      MediaBrowser.Api/MediaBrowser.Api.csproj
  2. 7 5
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  3. 0 119
      MediaBrowser.Api/Playback/Hls/AudioHlsService.cs
  4. 2 3
      MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
  5. 2 3
      MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
  6. 2 3
      MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
  7. 2 3
      MediaBrowser.Api/Playback/Progressive/AudioService.cs
  8. 5 5
      MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
  9. 2 3
      MediaBrowser.Api/Playback/Progressive/VideoService.cs
  10. 5 4
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  11. 17 0
      MediaBrowser.Controller/MediaEncoding/ChapterImageRefreshOptions.cs
  12. 33 0
      MediaBrowser.Controller/MediaEncoding/IEncodingManager.cs
  13. 1 1
      MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
  14. 3 3
      MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs
  15. 4 4
      MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
  16. 1 1
      MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs
  17. 1 1
      MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
  18. 1 1
      MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
  19. 1 1
      MediaBrowser.Providers/MediaInfo/FFProbeHelpers.cs
  20. 4 3
      MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
  21. 12 3
      MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
  22. 1 1
      MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
  23. 0 3
      MediaBrowser.Providers/Omdb/OmdbProvider.cs
  24. 1 1
      MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs
  25. 1 1
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  26. 1 0
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  27. 70 107
      MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs
  28. 1 1
      MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
  29. 27 6
      MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
  30. 16 3
      MediaBrowser.ServerApplication/ApplicationHost.cs

+ 0 - 1
MediaBrowser.Api/MediaBrowser.Api.csproj

@@ -96,7 +96,6 @@
     <Compile Include="PackageReviewService.cs" />
     <Compile Include="PackageService.cs" />
     <Compile Include="Playback\EndlessStreamCopy.cs" />
-    <Compile Include="Playback\Hls\AudioHlsService.cs" />
     <Compile Include="Playback\Hls\BaseHlsService.cs" />
     <Compile Include="Playback\Hls\DynamicHlsService.cs" />
     <Compile Include="Playback\Hls\HlsSegmentService.cs" />

+ 7 - 5
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Drawing;
@@ -58,6 +58,7 @@ namespace MediaBrowser.Api.Playback
         /// </summary>
         /// <value>The media encoder.</value>
         protected IMediaEncoder MediaEncoder { get; private set; }
+        protected IEncodingManager EncodingManager { get; private set; }
         protected IDtoService DtoService { get; private set; }
 
         protected IFileSystem FileSystem { get; private set; }
@@ -76,8 +77,9 @@ namespace MediaBrowser.Api.Playback
         /// <param name="dtoService">The dto service.</param>
         /// <param name="fileSystem">The file system.</param>
         /// <param name="itemRepository">The item repository.</param>
-        protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager)
+        protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager)
         {
+            EncodingManager = encodingManager;
             LiveTvManager = liveTvManager;
             ItemRepository = itemRepository;
             FileSystem = fileSystem;
@@ -589,8 +591,8 @@ namespace MediaBrowser.Api.Playback
         /// <returns>System.String.</returns>
         private string GetExtractedAssPath(StreamState state, bool performConversion)
         {
-            var path = FFMpegManager.Instance.GetSubtitleCachePath(state.MediaPath, state.SubtitleStream, ".ass");
-
+            var path = EncodingManager.GetSubtitleCachePath(state.MediaPath, state.SubtitleStream.Index, ".ass");
+            
             if (performConversion)
             {
                 InputType type;
@@ -629,7 +631,7 @@ namespace MediaBrowser.Api.Playback
         /// <returns>System.String.</returns>
         private string GetConvertedAssPath(string mediaPath, MediaStream subtitleStream, bool performConversion)
         {
-            var path = FFMpegManager.Instance.GetSubtitleCachePath(mediaPath, subtitleStream, ".ass");
+            var path = EncodingManager.GetSubtitleCachePath(subtitleStream.Path, ".ass");
 
             if (performConversion)
             {

+ 0 - 119
MediaBrowser.Api/Playback/Hls/AudioHlsService.cs

@@ -1,119 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.MediaInfo;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.IO;
-using ServiceStack;
-using System;
-
-namespace MediaBrowser.Api.Playback.Hls
-{
-    /// <summary>
-    /// Class GetHlsAudioStream
-    /// </summary>
-    [Route("/Audio/{Id}/stream.m3u8", "GET")]
-    [Api(Description = "Gets an audio stream using HTTP live streaming.")]
-    public class GetHlsAudioStream : StreamRequest
-    {
-
-    }
-
-    /// <summary>
-    /// Class AudioHlsService
-    /// </summary>
-    public class AudioHlsService : BaseHlsService
-    {
-        public AudioHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager)
-            : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager)
-        {
-        }
-
-        /// <summary>
-        /// Gets the specified request.
-        /// </summary>
-        /// <param name="request">The request.</param>
-        /// <returns>System.Object.</returns>
-        public object Get(GetHlsAudioStream request)
-        {
-            return ProcessRequest(request);
-        }
-
-        /// <summary>
-        /// Gets the audio arguments.
-        /// </summary>
-        /// <param name="state">The state.</param>
-        /// <returns>System.String.</returns>
-        protected override string GetAudioArguments(StreamState state)
-        {
-            var codec = GetAudioCodec(state.Request);
-
-            var args = "-codec:a " + codec;
-
-            var channels = GetNumAudioChannelsParam(state.Request, state.AudioStream);
-
-            if (channels.HasValue)
-            {
-                args += " -ac " + channels.Value;
-            }
-
-            if (state.Request.AudioSampleRate.HasValue)
-            {
-                args += " -ar " + state.Request.AudioSampleRate.Value;
-            }
-
-            if (state.Request.AudioBitRate.HasValue)
-            {
-                args += " -ab " + state.Request.AudioBitRate.Value;
-            }
-
-            return args;
-        }
-
-        /// <summary>
-        /// Gets the video arguments.
-        /// </summary>
-        /// <param name="state">The state.</param>
-        /// <param name="performSubtitleConversion">if set to <c>true</c> [perform subtitle conversion].</param>
-        /// <returns>System.String.</returns>
-        protected override string GetVideoArguments(StreamState state, bool performSubtitleConversion)
-        {
-            // No video
-            return string.Empty;
-        }
-
-        /// <summary>
-        /// Gets the segment file extension.
-        /// </summary>
-        /// <param name="state">The state.</param>
-        /// <returns>System.String.</returns>
-        /// <exception cref="System.ArgumentException">Must specify either aac or mp3 audio codec.</exception>
-        /// <exception cref="System.InvalidOperationException">Only aac and mp3 audio codecs are supported.</exception>
-        protected override string GetSegmentFileExtension(StreamState state)
-        {
-            if (state.Request.AudioCodec == AudioCodecs.Aac)
-            {
-                return ".aac";
-            }
-            if (state.Request.AudioCodec == AudioCodecs.Mp3)
-            {
-                return ".mp3";
-            }
-
-            throw new ArgumentException("Must specify either aac or mp3 audio codec.");
-        }
-
-        /// <summary>
-        /// Gets the map args.
-        /// </summary>
-        /// <param name="state">The state.</param>
-        /// <returns>System.String.</returns>
-        protected override string GetMapArgs(StreamState state)
-        {
-            return string.Format("-map 0:{0}", state.AudioStream.Index);
-        }
-    }
-}

+ 2 - 3
MediaBrowser.Api/Playback/Hls/BaseHlsService.cs

@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Dto;
@@ -24,8 +24,7 @@ namespace MediaBrowser.Api.Playback.Hls
     /// </summary>
     public abstract class BaseHlsService : BaseStreamingService
     {
-        protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager) 
-            : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager)
+        protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager)
         {
         }
 

+ 2 - 3
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -4,7 +4,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.IO;
@@ -60,8 +60,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
     public class DynamicHlsService : BaseHlsService
     {
-        public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager)
-            : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager)
+        public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager)
         {
         }
 

+ 2 - 3
MediaBrowser.Api/Playback/Hls/VideoHlsService.cs

@@ -3,7 +3,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.IO;
 using ServiceStack;
@@ -52,8 +52,7 @@ namespace MediaBrowser.Api.Playback.Hls
     /// </summary>
     public class VideoHlsService : BaseHlsService
     {
-        public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager)
-            : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager)
+        public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager)
         {
         }
 

+ 2 - 3
MediaBrowser.Api/Playback/Progressive/AudioService.cs

@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.IO;
 using ServiceStack;
@@ -43,8 +43,7 @@ namespace MediaBrowser.Api.Playback.Progressive
     /// </summary>
     public class AudioService : BaseProgressiveStreamingService
     {
-        public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IImageProcessor imageProcessor, IHttpClient httpClient)
-            : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, imageProcessor, httpClient)
+        public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IHttpClient httpClient, IImageProcessor imageProcessor) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, httpClient, imageProcessor)
         {
         }
 

+ 5 - 5
MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs

@@ -5,16 +5,16 @@ using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.IO;
+using ServiceStack.Web;
 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
-using ServiceStack.Web;
 
 namespace MediaBrowser.Api.Playback.Progressive
 {
@@ -26,11 +26,11 @@ namespace MediaBrowser.Api.Playback.Progressive
         protected readonly IImageProcessor ImageProcessor;
         protected readonly IHttpClient HttpClient;
 
-        protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IImageProcessor imageProcessor, IHttpClient httpClient)
-            : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager)
+        protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IHttpClient httpClient, IImageProcessor imageProcessor)
+            : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager)
         {
-            ImageProcessor = imageProcessor;
             HttpClient = httpClient;
+            ImageProcessor = imageProcessor;
         }
 
         /// <summary>

+ 2 - 3
MediaBrowser.Api/Playback/Progressive/VideoService.cs

@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.IO;
 using ServiceStack;
@@ -58,8 +58,7 @@ namespace MediaBrowser.Api.Playback.Progressive
     /// </summary>
     public class VideoService : BaseProgressiveStreamingService
     {
-        public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IImageProcessor imageProcessor, IHttpClient httpClient)
-            : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, imageProcessor, httpClient)
+        public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IHttpClient httpClient, IImageProcessor imageProcessor) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, httpClient, imageProcessor)
         {
         }
 

+ 5 - 4
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -135,8 +135,10 @@
     <Compile Include="LiveTv\SeriesTimerInfo.cs" />
     <Compile Include="LiveTv\TimerInfo.cs" />
     <Compile Include="Localization\ILocalizationManager.cs" />
-    <Compile Include="MediaInfo\IMediaEncoder.cs" />
-    <Compile Include="MediaInfo\InternalMediaInfoResult.cs" />
+    <Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" />
+    <Compile Include="MediaEncoding\IEncodingManager.cs" />
+    <Compile Include="MediaEncoding\IMediaEncoder.cs" />
+    <Compile Include="MediaEncoding\InternalMediaInfoResult.cs" />
     <Compile Include="Net\IHasResultFactory.cs" />
     <Compile Include="Net\IHttpResultFactory.cs" />
     <Compile Include="Net\IHttpServer.cs" />
@@ -198,7 +200,7 @@
     <Compile Include="IServerApplicationPaths.cs" />
     <Compile Include="Library\SearchHintInfo.cs" />
     <Compile Include="Providers\IProviderManager.cs" />
-    <Compile Include="MediaInfo\MediaEncoderHelpers.cs" />
+    <Compile Include="MediaEncoding\MediaEncoderHelpers.cs" />
     <Compile Include="Providers\MetadataProviderPriority.cs" />
     <Compile Include="Resolvers\BaseItemResolver.cs" />
     <Compile Include="Resolvers\BaseVideoResolver.cs" />
@@ -209,7 +211,6 @@
     <Compile Include="Localization\BaseStrings.cs" />
     <Compile Include="Localization\LocalizedStringData.cs" />
     <Compile Include="Localization\LocalizedStrings.cs" />
-    <Compile Include="MediaInfo\FFMpegManager.cs" />
     <Compile Include="Persistence\IDisplayPreferencesRepository.cs" />
     <Compile Include="Persistence\IItemRepository.cs" />
     <Compile Include="Persistence\IRepository.cs" />

+ 17 - 0
MediaBrowser.Controller/MediaEncoding/ChapterImageRefreshOptions.cs

@@ -0,0 +1,17 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Entities;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.MediaEncoding
+{
+    public class ChapterImageRefreshOptions
+    {
+        public Video Video { get; set; }
+
+        public List<ChapterInfo> Chapters { get; set; }
+
+        public bool SaveChapters { get; set; }
+
+        public bool ExtractImages { get; set; }
+    }
+}

+ 33 - 0
MediaBrowser.Controller/MediaEncoding/IEncodingManager.cs

@@ -0,0 +1,33 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.MediaEncoding
+{
+    public interface IEncodingManager
+    {
+        /// <summary>
+        /// Gets the subtitle cache path.
+        /// </summary>
+        /// <param name="originalSubtitlePath">The original subtitle path.</param>
+        /// <param name="outputSubtitleExtension">The output subtitle extension.</param>
+        /// <returns>System.String.</returns>
+        string GetSubtitleCachePath(string originalSubtitlePath, string outputSubtitleExtension);
+
+        /// <summary>
+        /// Gets the subtitle cache path.
+        /// </summary>
+        /// <param name="mediaPath">The media path.</param>
+        /// <param name="subtitleStreamIndex">Index of the subtitle stream.</param>
+        /// <param name="outputSubtitleExtension">The output subtitle extension.</param>
+        /// <returns>System.String.</returns>
+        string GetSubtitleCachePath(string mediaPath, int subtitleStreamIndex, string outputSubtitleExtension);
+
+        /// <summary>
+        /// Refreshes the chapter images.
+        /// </summary>
+        /// <param name="options">The options.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task{System.Boolean}.</returns>
+        Task<bool> RefreshChapterImages(ChapterImageRefreshOptions options, CancellationToken cancellationToken);
+    }
+}

+ 1 - 1
MediaBrowser.Controller/MediaInfo/IMediaEncoder.cs → MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs

@@ -4,7 +4,7 @@ using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
 
-namespace MediaBrowser.Controller.MediaInfo
+namespace MediaBrowser.Controller.MediaEncoding
 {
     /// <summary>
     /// Interface IMediaEncoder

+ 3 - 3
MediaBrowser.Controller/MediaInfo/InternalMediaInfoResult.cs → MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs

@@ -1,7 +1,7 @@
-using System.Collections.Generic;
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Entities;
+using System.Collections.Generic;
 
-namespace MediaBrowser.Controller.MediaInfo
+namespace MediaBrowser.Controller.MediaEncoding
 {
     /// <summary>
     /// Class MediaInfoResult

+ 4 - 4
MediaBrowser.Controller/MediaInfo/MediaEncoderHelpers.cs → MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs

@@ -1,12 +1,12 @@
-using System;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.IO;
+using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Linq;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.IO;
 
-namespace MediaBrowser.Controller.MediaInfo
+namespace MediaBrowser.Controller.MediaEncoding
 {
     /// <summary>
     /// Class MediaEncoderHelpers

+ 1 - 1
MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs

@@ -236,7 +236,7 @@ namespace MediaBrowser.Providers.BoxSets
 
         private static string GetCollectionsDataPath(IApplicationPaths appPaths)
         {
-            var dataPath = Path.Combine(appPaths.DataPath, "tmdb-collections");
+            var dataPath = Path.Combine(appPaths.CachePath, "tmdb-collections");
 
             return dataPath;
         }

+ 1 - 1
MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs

@@ -3,7 +3,7 @@ using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;

+ 1 - 1
MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs

@@ -3,7 +3,7 @@ using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Serialization;

+ 1 - 1
MediaBrowser.Providers/MediaInfo/FFProbeHelpers.cs

@@ -1,4 +1,4 @@
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using System;
 using System.Collections.Generic;
 

+ 4 - 3
MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs

@@ -6,7 +6,7 @@ using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Localization;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
@@ -42,6 +42,7 @@ namespace MediaBrowser.Providers.MediaInfo
         private readonly ILocalizationManager _localization;
         private readonly IApplicationPaths _appPaths;
         private readonly IJsonSerializer _json;
+        private readonly IEncodingManager _encodingManager;
 
         public string Name
         {
@@ -124,7 +125,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 return _cachedTask;
             }
 
-            var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json);
+            var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json, _encodingManager);
 
             return prober.ProbeVideo(item, directoryService, cancellationToken);
         }
@@ -155,7 +156,7 @@ namespace MediaBrowser.Providers.MediaInfo
 
                 if (video != null)
                 {
-                    var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json);
+                    var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json, _encodingManager);
 
                     return !video.SubtitleFiles.SequenceEqual(prober.GetSubtitleFiles(video, directoryService).Select(i => i.FullName).OrderBy(i => i), StringComparer.OrdinalIgnoreCase);
                 }

+ 12 - 3
MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs

@@ -3,7 +3,7 @@ using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Localization;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
@@ -31,10 +31,11 @@ namespace MediaBrowser.Providers.MediaInfo
         private readonly ILocalizationManager _localization;
         private readonly IApplicationPaths _appPaths;
         private readonly IJsonSerializer _json;
+        private readonly IEncodingManager _encodingManager;
 
         private readonly CultureInfo _usCulture = new CultureInfo("en-US");
 
-        public FFProbeVideoInfo(ILogger logger, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepo, IBlurayExaminer blurayExaminer, ILocalizationManager localization, IApplicationPaths appPaths, IJsonSerializer json)
+        public FFProbeVideoInfo(ILogger logger, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepo, IBlurayExaminer blurayExaminer, ILocalizationManager localization, IApplicationPaths appPaths, IJsonSerializer json, IEncodingManager encodingManager)
         {
             _logger = logger;
             _isoManager = isoManager;
@@ -44,6 +45,7 @@ namespace MediaBrowser.Providers.MediaInfo
             _localization = localization;
             _appPaths = appPaths;
             _json = json;
+            _encodingManager = encodingManager;
         }
 
         public async Task<ItemUpdateType> ProbeVideo<T>(T item, IDirectoryService directoryService, CancellationToken cancellationToken)
@@ -167,7 +169,14 @@ namespace MediaBrowser.Providers.MediaInfo
 
             video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);
 
-            await FFMpegManager.Instance.PopulateChapterImages(video, chapters, false, false, cancellationToken).ConfigureAwait(false);
+            await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions
+            {
+                Chapters = chapters,
+                Video = video,
+                ExtractImages = false,
+                SaveChapters = false
+
+            }, cancellationToken).ConfigureAwait(false);
 
             await _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken).ConfigureAwait(false);
 

+ 1 - 1
MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs

@@ -1,7 +1,7 @@
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;

+ 0 - 3
MediaBrowser.Providers/Omdb/OmdbProvider.cs

@@ -1,8 +1,5 @@
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Serialization;
 using System;
 using System.Globalization;

+ 1 - 1
MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs

@@ -202,7 +202,7 @@ namespace MediaBrowser.Providers.TV
 
         internal static string GetSeriesDataPath(IApplicationPaths appPaths)
         {
-            var dataPath = Path.Combine(appPaths.DataPath, "tmdb-tv");
+            var dataPath = Path.Combine(appPaths.CachePath, "tmdb-tv");
 
             return dataPath;
         }

+ 1 - 1
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -7,7 +7,7 @@ using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Sorting;

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

@@ -179,6 +179,7 @@
     <Compile Include="LiveTv\RecordingImageProvider.cs" />
     <Compile Include="LiveTv\RefreshChannelsScheduledTask.cs" />
     <Compile Include="Localization\LocalizationManager.cs" />
+    <Compile Include="MediaEncoder\EncodingManager.cs" />
     <Compile Include="MediaEncoder\MediaEncoder.cs" />
     <Compile Include="News\NewsEntryPoint.cs" />
     <Compile Include="News\NewsService.cs" />

+ 70 - 107
MediaBrowser.Controller/MediaInfo/FFMpegManager.cs → MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
@@ -15,63 +16,65 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 
-namespace MediaBrowser.Controller.MediaInfo
+namespace MediaBrowser.Server.Implementations.MediaEncoder
 {
-    /// <summary>
-    /// Class FFMpegManager
-    /// </summary>
-    public class FFMpegManager
+    public class EncodingManager : IEncodingManager
     {
         private readonly IServerConfigurationManager _config;
-        private readonly IMediaEncoder _encoder;
+        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
+        private readonly IFileSystem _fileSystem;
         private readonly ILogger _logger;
         private readonly IItemRepository _itemRepo;
+        private readonly IMediaEncoder _encoder;
 
-        private readonly IFileSystem _fileSystem;
-
-        public static FFMpegManager Instance { get; private set; }
-        
-        /// <summary>
-        /// Initializes a new instance of the <see cref="FFMpegManager" /> class.
-        /// </summary>
-        /// <param name="encoder">The encoder.</param>
-        /// <param name="logger">The logger.</param>
-        /// <param name="itemRepo">The item repo.</param>
-        /// <exception cref="System.ArgumentNullException">zipClient</exception>
-        public FFMpegManager(IMediaEncoder encoder, ILogger logger, IItemRepository itemRepo, IFileSystem fileSystem, IServerConfigurationManager config)
+        public EncodingManager(IServerConfigurationManager config, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IMediaEncoder encoder)
         {
-            _encoder = encoder;
+            _config = config;
+            _fileSystem = fileSystem;
             _logger = logger;
             _itemRepo = itemRepo;
-            _fileSystem = fileSystem;
-            _config = config;
-
-            // TODO: Remove this static instance
-            Instance = this;
+            _encoder = encoder;
         }
 
-        /// <summary>
-        /// Gets the chapter images data path.
-        /// </summary>
-        /// <value>The chapter images data path.</value>
-        public string ChapterImagesPath
+        private string SubtitleCachePath
         {
             get
             {
-                return Path.Combine(_config.ApplicationPaths.DataPath, "chapter-images");
+                return Path.Combine(_config.ApplicationPaths.CachePath, "subtitles");
             }
         }
+        
+        public string GetSubtitleCachePath(string originalSubtitlePath, string outputSubtitleExtension)
+        {
+            var ticksParam = _fileSystem.GetLastWriteTimeUtc(originalSubtitlePath).Ticks;
+
+            var filename = (originalSubtitlePath + ticksParam).GetMD5() + outputSubtitleExtension;
+
+            var prefix = filename.Substring(0, 1);
+
+            return Path.Combine(SubtitleCachePath, prefix, filename);
+        }
+
+        public string GetSubtitleCachePath(string mediaPath, int subtitleStreamIndex, string outputSubtitleExtension)
+        {
+            var ticksParam = string.Empty;
+
+            var date = _fileSystem.GetLastWriteTimeUtc(mediaPath);
+
+            var filename = (mediaPath + "_" + subtitleStreamIndex.ToString(_usCulture) + "_" + date.Ticks.ToString(_usCulture) + ticksParam).GetMD5() + outputSubtitleExtension;
+
+            var prefix = filename.Substring(0, 1);
+
+            return Path.Combine(SubtitleCachePath, prefix, filename);
+        }
 
         /// <summary>
-        /// Gets the subtitle cache path.
+        /// Gets the chapter images data path.
         /// </summary>
-        /// <value>The subtitle cache path.</value>
-        private string SubtitleCachePath
+        /// <value>The chapter images data path.</value>
+        private string GetChapterImagesPath(Guid itemId)
         {
-            get
-            {
-                return Path.Combine(_config.ApplicationPaths.CachePath, "subtitles");
-            }
+            return Path.Combine(_config.ApplicationPaths.GetInternalMetadataPath(itemId), "chapters");
         }
 
         /// <summary>
@@ -95,7 +98,7 @@ namespace MediaBrowser.Controller.MediaInfo
                     return false;
                 }
             }
-            else 
+            else
             {
                 if (!_config.Configuration.EnableOtherVideoChapterImageExtraction)
                 {
@@ -112,18 +115,13 @@ namespace MediaBrowser.Controller.MediaInfo
         /// </summary>
         private static readonly long FirstChapterTicks = TimeSpan.FromSeconds(15).Ticks;
 
-        /// <summary>
-        /// Extracts the chapter images.
-        /// </summary>
-        /// <param name="video">The video.</param>
-        /// <param name="chapters">The chapters.</param>
-        /// <param name="extractImages">if set to <c>true</c> [extract images].</param>
-        /// <param name="saveChapters">if set to <c>true</c> [save chapters].</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>Task.</returns>
-        /// <exception cref="System.ArgumentNullException"></exception>
-        public async Task<bool> PopulateChapterImages(Video video, List<ChapterInfo> chapters, bool extractImages, bool saveChapters, CancellationToken cancellationToken)
+        public async Task<bool> RefreshChapterImages(ChapterImageRefreshOptions options, CancellationToken cancellationToken)
         {
+            var extractImages = options.ExtractImages;
+            var video = options.Video;
+            var chapters = options.Chapters;
+            var saveChapters = options.SaveChapters;
+
             if (!IsEligibleForChapterImageExtraction(video))
             {
                 extractImages = false;
@@ -173,9 +171,7 @@ namespace MediaBrowser.Controller.MediaInfo
 
                         try
                         {
-                            var parentPath = Path.GetDirectoryName(path);
-
-                            Directory.CreateDirectory(parentPath);
+                            Directory.CreateDirectory(Path.GetDirectoryName(path));
 
                             using (var stream = await _encoder.ExtractImage(inputPath, type, false, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false))
                             {
@@ -217,6 +213,28 @@ namespace MediaBrowser.Controller.MediaInfo
             return success;
         }
 
+        private string GetChapterImagePath(Video video, long chapterPositionTicks)
+        {
+            var filename = video.DateModified.Ticks.ToString(_usCulture) + "_" + chapterPositionTicks.ToString(_usCulture) + ".jpg";
+
+            return Path.Combine(GetChapterImagesPath(video.Id), filename);
+        }
+
+        private List<string> GetSavedChapterImages(Video video)
+        {
+            var path = GetChapterImagesPath(video.Id);
+
+            try
+            {
+                return Directory.EnumerateFiles(path)
+                    .ToList();
+            }
+            catch (DirectoryNotFoundException)
+            {
+                return new List<string>();
+            }
+        }
+
         private void DeleteDeadImages(IEnumerable<string> images, IEnumerable<ChapterInfo> chapters)
         {
             var deadImages = images
@@ -238,60 +256,5 @@ namespace MediaBrowser.Controller.MediaInfo
                 }
             }
         }
-
-        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
-
-        /// <summary>
-        /// Gets the subtitle cache path.
-        /// </summary>
-        /// <param name="mediaPath">The media path.</param>
-        /// <param name="subtitleStream">The subtitle stream.</param>
-        /// <param name="outputExtension">The output extension.</param>
-        /// <returns>System.String.</returns>
-        public string GetSubtitleCachePath(string mediaPath, MediaStream subtitleStream, string outputExtension)
-        {
-            var ticksParam = string.Empty;
-
-            if (subtitleStream.IsExternal)
-            {
-                ticksParam += _fileSystem.GetLastWriteTimeUtc(subtitleStream.Path).Ticks;
-            }
-
-            var date = _fileSystem.GetLastWriteTimeUtc(mediaPath);
-
-            var filename = (mediaPath + "_" + subtitleStream.Index.ToString(_usCulture) + "_" + date.Ticks.ToString(_usCulture) + ticksParam).GetMD5() + outputExtension;
-
-            var prefix = filename.Substring(0, 1);
-
-            return Path.Combine(SubtitleCachePath, prefix, filename);
-        }
-
-        public string GetChapterImagePath(Video video, long chapterPositionTicks)
-        {
-            var filename = video.DateModified.Ticks.ToString(_usCulture) + "_" + chapterPositionTicks.ToString(_usCulture) + ".jpg";
-
-            var videoId = video.Id.ToString();
-            var prefix = videoId.Substring(0, 1);
-
-            return Path.Combine(ChapterImagesPath, prefix, videoId, filename);
-        }
-
-        public List<string> GetSavedChapterImages(Video video)
-        {
-            var videoId = video.Id.ToString();
-            var prefix = videoId.Substring(0, 1);
-
-            var path = Path.Combine(ChapterImagesPath, prefix, videoId);
-
-            try
-            {
-                return Directory.EnumerateFiles(path)
-                    .ToList();
-            }
-            catch (DirectoryNotFoundException)
-            {
-                return new List<string>();
-            }
-        }
     }
 }

+ 1 - 1
MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs

@@ -1,6 +1,6 @@
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Serialization;

+ 27 - 6
MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs

@@ -1,7 +1,8 @@
-using MediaBrowser.Common.ScheduledTasks;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
@@ -41,17 +42,23 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
 
         private readonly IItemRepository _itemRepo;
 
+        private readonly IApplicationPaths _appPaths;
+
+        private readonly IEncodingManager _encodingManager;
+
         /// <summary>
         /// Initializes a new instance of the <see cref="ChapterImagesTask" /> class.
         /// </summary>
         /// <param name="logManager">The log manager.</param>
         /// <param name="libraryManager">The library manager.</param>
         /// <param name="itemRepo">The item repo.</param>
-        public ChapterImagesTask(ILogManager logManager, ILibraryManager libraryManager, IItemRepository itemRepo)
+        public ChapterImagesTask(ILogManager logManager, ILibraryManager libraryManager, IItemRepository itemRepo, IApplicationPaths appPaths, IEncodingManager encodingManager)
         {
             _logger = logManager.GetLogger(GetType().Name);
             _libraryManager = libraryManager;
             _itemRepo = itemRepo;
+            _appPaths = appPaths;
+            _encodingManager = encodingManager;
 
             libraryManager.ItemAdded += libraryManager_ItemAdded;
             libraryManager.ItemUpdated += libraryManager_ItemAdded;
@@ -102,7 +109,14 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
                 {
                     var chapters = _itemRepo.GetChapters(item.Id).ToList();
 
-                    await FFMpegManager.Instance.PopulateChapterImages(item, chapters, true, true, CancellationToken.None);
+                    await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions
+                    {
+                        SaveChapters = true,
+                        ExtractImages = true,
+                        Video = item,
+                        Chapters = chapters
+
+                    }, CancellationToken.None);
                 }
                 catch (Exception ex)
                 {
@@ -137,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
 
             var numComplete = 0;
 
-            var failHistoryPath = Path.Combine(FFMpegManager.Instance.ChapterImagesPath, "failures.txt");
+            var failHistoryPath = Path.Combine(_appPaths.CachePath, "chapter-failures.txt");
 
             List<string> previouslyFailedImages;
 
@@ -166,7 +180,14 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
 
                 var chapters = _itemRepo.GetChapters(video.Id).ToList();
 
-                var success = await FFMpegManager.Instance.PopulateChapterImages(video, chapters, extract, true, cancellationToken);
+                var success = await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions
+                {
+                    SaveChapters = true,
+                    ExtractImages = extract,
+                    Video = video,
+                    Chapters = chapters
+
+                }, CancellationToken.None);
 
                 if (!success)
                 {

+ 16 - 3
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -17,7 +17,7 @@ using MediaBrowser.Controller.FileOrganization;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Localization;
-using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.News;
 using MediaBrowser.Controller.Notifications;
@@ -161,6 +161,8 @@ namespace MediaBrowser.ServerApplication
 
         private ILocalizationManager LocalizationManager { get; set; }
 
+        private IEncodingManager EncodingManager { get; set; }
+        
         /// <summary>
         /// Gets or sets the user data repository.
         /// </summary>
@@ -270,6 +272,15 @@ namespace MediaBrowser.ServerApplication
                     // Not there, no big deal
                 }
 
+                try
+                {
+                    Directory.Delete(Path.Combine(ApplicationPaths.DataPath, "chapter-images"), true);
+                }
+                catch (IOException)
+                {
+                    // Not there, no big deal
+                }
+
                 try
                 {
                     Directory.Delete(Path.Combine(ApplicationPaths.DataPath, "extracted-video-images"), true);
@@ -374,6 +385,10 @@ namespace MediaBrowser.ServerApplication
             await RegisterMediaEncoder(innerProgress).ConfigureAwait(false);
             progress.Report(90);
 
+            EncodingManager = new EncodingManager(ServerConfigurationManager, FileSystemManager, Logger, ItemRepository,
+                MediaEncoder);
+            RegisterSingleInstance(EncodingManager);
+
             LiveTvManager = new LiveTvManager(ServerConfigurationManager, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, MediaEncoder, TaskManager);
             RegisterSingleInstance(LiveTvManager);
 
@@ -419,8 +434,6 @@ namespace MediaBrowser.ServerApplication
         /// </summary>
         private void SetKernelProperties()
         {
-            new FFMpegManager(MediaEncoder, Logger, ItemRepository, FileSystemManager, ServerConfigurationManager);
-
             LocalizedStrings.StringFiles = GetExports<LocalizedStringData>();
 
             SetStaticProperties();