Browse Source

support audio sync transcoding

Luke Pulverenti 10 years ago
parent
commit
c93740461e

+ 4 - 1
MediaBrowser.Api/ApiEntryPoint.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Session;
 using System;
@@ -85,7 +86,9 @@ namespace MediaBrowser.Api
         /// </summary>
         private void DeleteEncodedMediaCache()
         {
-            foreach (var file in Directory.EnumerateFiles(_config.ApplicationPaths.TranscodingTempPath, "*", SearchOption.AllDirectories)
+            var path = Path.Combine(_config.ApplicationPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower());
+
+            foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories)
                 .ToList())
             {
                 File.Delete(file);

+ 2 - 2
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -119,8 +119,8 @@ namespace MediaBrowser.Api.Playback
         /// <returns>System.String.</returns>
         private string GetOutputFilePath(StreamState state)
         {
-            var folder = ServerConfigurationManager.ApplicationPaths.TranscodingTempPath;
-
+            var folder = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower());
+            
             var outputFileExtension = GetOutputFileExtension(state);
 
             var data = GetCommandLineArguments("dummy\\dummy", "dummyTranscodingId", state, false);

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

@@ -1,4 +1,5 @@
 using MediaBrowser.Controller;
+using MediaBrowser.Model.Dlna;
 using ServiceStack;
 using System;
 using System.IO;
@@ -65,7 +66,7 @@ namespace MediaBrowser.Api.Playback.Hls
         {
             var file = request.PlaylistId + Path.GetExtension(Request.PathInfo);
 
-            file = Path.Combine(_appPaths.TranscodingTempPath, file);
+            file = Path.Combine(_appPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower(), file);
 
             return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite);
         }
@@ -84,7 +85,7 @@ namespace MediaBrowser.Api.Playback.Hls
         {
             var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
 
-            file = Path.Combine(_appPaths.TranscodingTempPath, file);
+            file = Path.Combine(_appPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower(), file);
 
             return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite);
         }

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

@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.IO;
 using ServiceStack;
 using System;
@@ -70,7 +71,7 @@ namespace MediaBrowser.Api.Playback.Hls
         {
             var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
 
-            file = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, file);
+            file = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower(), file);
 
             return ResultFactory.GetStaticFileResult(Request, file);
         }

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

@@ -199,6 +199,7 @@
     <Compile Include="LiveTv\TimerInfo.cs" />
     <Compile Include="Localization\ILocalizationManager.cs" />
     <Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" />
+    <Compile Include="MediaEncoding\EncodingJobOptions.cs" />
     <Compile Include="MediaEncoding\IEncodingManager.cs" />
     <Compile Include="MediaEncoding\ImageEncodingOptions.cs" />
     <Compile Include="MediaEncoding\IMediaEncoder.cs" />

+ 11 - 0
MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs

@@ -96,5 +96,16 @@ namespace MediaBrowser.Controller.MediaEncoding
         /// <param name="ticks">The ticks.</param>
         /// <returns>System.String.</returns>
         string GetTimeParameter(long ticks);
+
+        /// <summary>
+        /// Encodes the audio.
+        /// </summary>
+        /// <param name="options">The options.</param>
+        /// <param name="progress">The progress.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        Task<string> EncodeAudio(EncodingJobOptions options,
+            IProgress<double> progress,
+            CancellationToken cancellationToken);
     }
 }

+ 2 - 1
MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs

@@ -112,7 +112,8 @@ namespace MediaBrowser.LocalMetadata.Savers
                     "Website",
                     "Zap2ItId",
                     "CollectionItems",
-                    "PlaylistItems"
+                    "PlaylistItems",
+                    "Shares"
 
         }.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
 

+ 43 - 2
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -1,10 +1,16 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Controller.Session;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Serialization;
 using System;
-using System.Collections.Concurrent;
 using System.Diagnostics;
 using System.Globalization;
 using System.IO;
@@ -51,11 +57,26 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
         public string Version { get; private set; }
 
-        public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version)
+        protected readonly IServerConfigurationManager ConfigurationManager;
+        protected readonly IFileSystem FileSystem;
+        protected readonly ILiveTvManager LiveTvManager;
+        protected readonly IIsoManager IsoManager;
+        protected readonly ILibraryManager LibraryManager;
+        protected readonly IChannelManager ChannelManager;
+        protected readonly ISessionManager SessionManager;
+        
+        public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager)
         {
             _logger = logger;
             _jsonSerializer = jsonSerializer;
             Version = version;
+            ConfigurationManager = configurationManager;
+            FileSystem = fileSystem;
+            LiveTvManager = liveTvManager;
+            IsoManager = isoManager;
+            LibraryManager = libraryManager;
+            ChannelManager = channelManager;
+            SessionManager = sessionManager;
             FFProbePath = ffProbePath;
             FFMpegPath = ffMpegPath;
         }
@@ -511,5 +532,25 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 throw new ApplicationException(msg);
             }
         }
+
+        public async Task<string> EncodeAudio(EncodingJobOptions options,
+            IProgress<double> progress,
+            CancellationToken cancellationToken)
+        {
+            var job = await new AudioEncoder(this, 
+                _logger, 
+                ConfigurationManager, 
+                FileSystem, 
+                LiveTvManager,
+                IsoManager, 
+                LibraryManager, 
+                ChannelManager, 
+                SessionManager)
+                .Start(options, progress, cancellationToken).ConfigureAwait(false);
+
+            await job.TaskCompletionSource.Task.ConfigureAwait(false);
+
+            return job.OutputFilePath;
+        }
     }
 }

+ 5 - 0
MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj

@@ -57,7 +57,12 @@
     </Compile>
     <Compile Include="BdInfo\BdInfoExaminer.cs" />
     <Compile Include="Configuration\EncodingConfigurationFactory.cs" />
+    <Compile Include="Encoder\AudioEncoder.cs" />
+    <Compile Include="Encoder\BaseEncoder.cs" />
+    <Compile Include="Encoder\EncodingJob.cs" />
+    <Compile Include="Encoder\EncodingJobFactory.cs" />
     <Compile Include="Encoder\EncodingUtils.cs" />
+    <Compile Include="Encoder\JobLogger.cs" />
     <Compile Include="Encoder\MediaEncoder.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Subtitles\ISubtitleParser.cs" />

+ 4 - 2
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -109,7 +109,8 @@ namespace MediaBrowser.Model.Dlna
                 ItemId = options.ItemId,
                 MediaType = DlnaProfileType.Audio,
                 MediaSource = item,
-                RunTimeTicks = item.RunTimeTicks
+                RunTimeTicks = item.RunTimeTicks,
+                Context = options.Context
             };
 
             int? maxBitrateSetting = options.GetMaxBitrate();
@@ -240,7 +241,8 @@ namespace MediaBrowser.Model.Dlna
                 ItemId = options.ItemId,
                 MediaType = DlnaProfileType.Video,
                 MediaSource = item,
-                RunTimeTicks = item.RunTimeTicks
+                RunTimeTicks = item.RunTimeTicks,
+                Context = options.Context
             };
 
             int? audioStreamIndex = options.AudioStreamIndex ?? item.DefaultAudioStreamIndex;

+ 1 - 0
MediaBrowser.Model/Dlna/StreamInfo.cs

@@ -18,6 +18,7 @@ namespace MediaBrowser.Model.Dlna
         public string ItemId { get; set; }
 
         public PlayMethod PlayMethod { get; set; }
+        public EncodingContext Context { get; set; }
 
         public DlnaProfileType MediaType { get; set; }
 

+ 1 - 1
MediaBrowser.Model/Sync/LocalItem.cs

@@ -23,7 +23,7 @@ namespace MediaBrowser.Model.Sync
         /// Gets or sets the unique identifier.
         /// </summary>
         /// <value>The unique identifier.</value>
-        public string UniqueId { get; set; }
+        public string Id { get; set; }
         /// <summary>
         /// Gets or sets the item identifier.
         /// </summary>

+ 1 - 1
MediaBrowser.Server.Implementations/Devices/DeviceManager.cs

@@ -9,12 +9,12 @@ using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Session;
+using MediaBrowser.Model.Users;
 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
-using MediaBrowser.Model.Users;
 
 namespace MediaBrowser.Server.Implementations.Devices
 {

+ 4 - 2
MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Common;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Model.Logging;
@@ -21,6 +22,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
         private readonly IHttpClient _httpClient;
         private readonly ILogger _logger;
         private readonly ISessionManager _sessionManager;
+        private readonly IUserManager _userManager;
 
         private Timer _timer;
         private readonly TimeSpan _frequency = TimeSpan.FromHours(24);
@@ -65,7 +67,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
         {
             try
             {
-                await new UsageReporter(_applicationHost, _networkManager, _httpClient)
+                await new UsageReporter(_applicationHost, _networkManager, _httpClient, _userManager)
                     .ReportAppUsage(client, CancellationToken.None)
                     .ConfigureAwait(false);
             }
@@ -107,7 +109,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
         {
             try
             {
-                await new UsageReporter(_applicationHost, _networkManager, _httpClient)
+                await new UsageReporter(_applicationHost, _networkManager, _httpClient, _userManager)
                     .ReportServerUsage(CancellationToken.None)
                     .ConfigureAwait(false);
             }

+ 13 - 1
MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs

@@ -1,7 +1,11 @@
 using MediaBrowser.Common;
 using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Connect;
 using System;
 using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -12,13 +16,15 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
         private readonly IApplicationHost _applicationHost;
         private readonly INetworkManager _networkManager;
         private readonly IHttpClient _httpClient;
+        private readonly IUserManager _userManager;
         private const string MbAdminUrl = "http://www.mb3admin.com/admin/";
 
-        public UsageReporter(IApplicationHost applicationHost, INetworkManager networkManager, IHttpClient httpClient)
+        public UsageReporter(IApplicationHost applicationHost, INetworkManager networkManager, IHttpClient httpClient, IUserManager userManager)
         {
             _applicationHost = applicationHost;
             _networkManager = networkManager;
             _httpClient = httpClient;
+            _userManager = userManager;
         }
 
         public Task ReportServerUsage(CancellationToken cancellationToken)
@@ -38,6 +44,12 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
                 { "isservice", _applicationHost.IsRunningAsService.ToString().ToLower()}
             };
 
+            var users = _userManager.Users.ToList();
+
+            data["localusers"] = users.Count(i => !i.ConnectLinkType.HasValue).ToString(CultureInfo.InvariantCulture);
+            data["guests"] = users.Count(i => i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest).ToString(CultureInfo.InvariantCulture);
+            data["linkedusers"] = users.Count(i => i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.LinkedUser).ToString(CultureInfo.InvariantCulture);
+
             return _httpClient.Post(MbAdminUrl + "service/registration/ping", data, cancellationToken);
         }
 

+ 7 - 7
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -1556,25 +1556,25 @@ namespace MediaBrowser.Server.Implementations.Library
         {
             // Types cannot be overridden, so go from the top down until we find a configured content type
 
-            var type = GetTopFolderContentType(item);
+            var type = GetInheritedContentType(item);
 
             if (!string.IsNullOrWhiteSpace(type))
             {
                 return type;
             }
 
-            type = GetInheritedContentType(item);
+            return GetConfiguredContentType(item);
+        }
+
+        public string GetInheritedContentType(BaseItem item)
+        {
+            var type = GetTopFolderContentType(item);
 
             if (!string.IsNullOrWhiteSpace(type))
             {
                 return type;
             }
 
-            return GetConfiguredContentType(item);
-        }
-
-        public string GetInheritedContentType(BaseItem item)
-        {
             return item.Parents
                 .Select(GetConfiguredContentType)
                 .LastOrDefault(i => !string.IsNullOrWhiteSpace(i));

+ 1 - 0
MediaBrowser.Server.Implementations/Localization/Server/server.json

@@ -1317,5 +1317,6 @@
     "NameSeasonUnknown": "Season Unknown",
     "NameSeasonNumber": "Season {0}",
     "LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)",
+    "TabJobs": "Jobs",
     "TabSyncJobs": "Sync Jobs"
 }

+ 3 - 1
MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs

@@ -46,7 +46,9 @@ namespace MediaBrowser.Server.Implementations.Sync
 
         public DeviceProfile GetDeviceProfile(SyncTarget target)
         {
-            return new DeviceProfile();
+            var caps = _deviceManager.GetCapabilities(target.Id);
+
+            return caps == null || caps.DeviceProfile == null ? new DeviceProfile() : caps.DeviceProfile;
         }
 
         public string Name

+ 20 - 11
MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Sync;
 using MediaBrowser.Controller.TV;
 using MediaBrowser.Model.Dlna;
@@ -28,8 +29,9 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly ILogger _logger;
         private readonly IUserManager _userManager;
         private readonly ITVSeriesManager _tvSeriesManager;
+        private readonly IMediaEncoder MediaEncoder;
 
-        public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager)
+        public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder)
         {
             _libraryManager = libraryManager;
             _syncRepo = syncRepo;
@@ -37,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _logger = logger;
             _userManager = userManager;
             _tvSeriesManager = tvSeriesManager;
+            MediaEncoder = mediaEncoder;
         }
 
         public async Task EnsureJobItems(SyncJob job)
@@ -392,7 +395,7 @@ namespace MediaBrowser.Server.Implementations.Sync
         {
             var options = new VideoOptions
             {
-                Context = EncodingContext.Streaming,
+                Context = EncodingContext.Static,
                 ItemId = item.Id.ToString("N"),
                 DeviceId = jobItem.TargetId,
                 Profile = profile,
@@ -406,7 +409,10 @@ namespace MediaBrowser.Server.Implementations.Sync
 
             if (streamInfo.PlayMethod == PlayMethod.Transcode)
             {
+                jobItem.Status = SyncJobItemStatus.Converting;
                 await _syncRepo.Update(jobItem).ConfigureAwait(false);
+
+                //jobItem.OutputPath = await MediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, profile), new Progress<double>(), cancellationToken);
             }
             else
             {
@@ -418,12 +424,12 @@ namespace MediaBrowser.Server.Implementations.Sync
                 {
                     jobItem.OutputPath = await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
                 }
-                throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
+                else
+                {
+                    throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
+                }
             }
 
-            // TODO: Transcode
-            jobItem.OutputPath = mediaSource.Path;
-
             jobItem.Progress = 50;
             jobItem.Status = SyncJobItemStatus.Transferring;
             await _syncRepo.Update(jobItem).ConfigureAwait(false);
@@ -433,7 +439,7 @@ namespace MediaBrowser.Server.Implementations.Sync
         {
             var options = new AudioOptions
             {
-                Context = EncodingContext.Streaming,
+                Context = EncodingContext.Static,
                 ItemId = item.Id.ToString("N"),
                 DeviceId = jobItem.TargetId,
                 Profile = profile,
@@ -447,7 +453,10 @@ namespace MediaBrowser.Server.Implementations.Sync
 
             if (streamInfo.PlayMethod == PlayMethod.Transcode)
             {
+                jobItem.Status = SyncJobItemStatus.Converting;
                 await _syncRepo.Update(jobItem).ConfigureAwait(false);
+                
+                jobItem.OutputPath = await MediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, profile), new Progress<double>(), cancellationToken);
             }
             else
             {
@@ -459,12 +468,12 @@ namespace MediaBrowser.Server.Implementations.Sync
                 {
                     jobItem.OutputPath = await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
                 }
-                throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
+                else
+                {
+                    throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
+                }
             }
 
-            // TODO: Transcode
-            jobItem.OutputPath = mediaSource.Path;
-
             jobItem.Progress = 50;
             jobItem.Status = SyncJobItemStatus.Transferring;
             await _syncRepo.Update(jobItem).ConfigureAwait(false);

+ 7 - 4
MediaBrowser.Server.Implementations/Sync/SyncManager.cs

@@ -8,6 +8,7 @@ using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Sync;
 using MediaBrowser.Controller.TV;
 using MediaBrowser.Model.Dlna;
@@ -36,10 +37,11 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly Func<IDtoService> _dtoService;
         private readonly IApplicationHost _appHost;
         private readonly ITVSeriesManager _tvSeriesManager;
+        private readonly Func<IMediaEncoder> MediaEncoder;
 
         private ISyncProvider[] _providers = { };
 
-        public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager)
+        public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder)
         {
             _libraryManager = libraryManager;
             _repo = repo;
@@ -49,6 +51,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _dtoService = dtoService;
             _appHost = appHost;
             _tvSeriesManager = tvSeriesManager;
+            MediaEncoder = mediaEncoder;
         }
 
         public void AddParts(IEnumerable<ISyncProvider> providers)
@@ -58,7 +61,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
         public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request)
         {
-            var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager);
+            var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager, MediaEncoder());
 
             var user = _userManager.GetUserById(request.UserId);
 
@@ -162,7 +165,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
             if (item == null)
             {
-                var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager);
+                var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager, MediaEncoder());
 
                 var user = _userManager.GetUserById(job.UserId);
 
@@ -392,7 +395,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
             await _repo.Update(jobItem).ConfigureAwait(false);
 
-            var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager);
+            var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager, MediaEncoder());
 
             await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
         }

+ 5 - 2
MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Sync;
 using MediaBrowser.Controller.TV;
 using MediaBrowser.Model.Logging;
@@ -18,8 +19,9 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly ILogger _logger;
         private readonly IUserManager _userManager;
         private readonly ITVSeriesManager _tvSeriesManager;
+        private readonly IMediaEncoder MediaEncoder;
 
-        public SyncScheduledTask(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager)
+        public SyncScheduledTask(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder)
         {
             _libraryManager = libraryManager;
             _syncRepo = syncRepo;
@@ -27,6 +29,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _logger = logger;
             _userManager = userManager;
             _tvSeriesManager = tvSeriesManager;
+            MediaEncoder = mediaEncoder;
         }
 
         public string Name
@@ -49,7 +52,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         {
-            return new SyncJobProcessor(_libraryManager, _syncRepo, _syncManager, _logger, _userManager, _tvSeriesManager).Sync(progress,
+            return new SyncJobProcessor(_libraryManager, _syncRepo, _syncManager, _logger, _userManager, _tvSeriesManager, MediaEncoder).Sync(progress,
                 cancellationToken);
         }
 

+ 16 - 5
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -476,16 +476,13 @@ namespace MediaBrowser.Server.Startup.Common
             var innerProgress = new ActionableProgress<double>();
             innerProgress.RegisterAction(p => progress.Report((.75 * p) + 15));
 
-            await RegisterMediaEncoder(innerProgress).ConfigureAwait(false);
-            progress.Report(90);
-
             ImageProcessor = new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, MediaEncoder);
             RegisterSingleInstance(ImageProcessor);
 
             TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager);
             RegisterSingleInstance(TVSeriesManager);
 
-            SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager);
+            SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder);
             RegisterSingleInstance(SyncManager);
 
             DtoService = new DtoService(Logger, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this);
@@ -547,6 +544,9 @@ namespace MediaBrowser.Server.Startup.Common
             ChapterManager = new ChapterManager(LibraryManager, LogManager.GetLogger("ChapterManager"), ServerConfigurationManager, ItemRepository);
             RegisterSingleInstance(ChapterManager);
 
+            await RegisterMediaEncoder(innerProgress).ConfigureAwait(false);
+            progress.Report(90);
+
             EncodingManager = new EncodingManager(FileSystemManager, Logger,
                 MediaEncoder, ChapterManager);
             RegisterSingleInstance(EncodingManager);
@@ -591,7 +591,18 @@ namespace MediaBrowser.Server.Startup.Common
 
             new FFmpegValidator(Logger, ApplicationPaths).Validate(info);
 
-            MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), JsonSerializer, info.EncoderPath, info.ProbePath, info.Version);
+            MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), 
+                JsonSerializer, 
+                info.EncoderPath, 
+                info.ProbePath, 
+                info.Version,
+                ServerConfigurationManager,
+                FileSystemManager,
+                LiveTvManager,
+                IsoManager,
+                LibraryManager,
+                ChannelManager,
+                SessionManager);
             RegisterSingleInstance(MediaEncoder);
         }