Browse Source

add methods to media source manager

Luke Pulverenti 10 years ago
parent
commit
75018055b2
34 changed files with 390 additions and 264 deletions
  1. 15 49
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  2. 1 1
      MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
  3. 5 6
      MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
  4. 1 2
      MediaBrowser.Api/Playback/Hls/MpegDashService.cs
  5. 1 2
      MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
  6. 23 35
      MediaBrowser.Api/Playback/MediaInfoService.cs
  7. 1 1
      MediaBrowser.Api/Playback/Progressive/AudioService.cs
  8. 1 3
      MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
  9. 1 2
      MediaBrowser.Api/Playback/Progressive/VideoService.cs
  10. 4 3
      MediaBrowser.Api/Subtitles/SubtitleService.cs
  11. 1 53
      MediaBrowser.Controller/Entities/IHasMediaSources.cs
  12. 1 2
      MediaBrowser.Controller/Entities/Video.cs
  13. 46 1
      MediaBrowser.Controller/Library/IMediaSourceManager.cs
  14. 19 0
      MediaBrowser.Controller/Library/IMediaSourceProvider.cs
  15. 1 0
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  16. 3 2
      MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
  17. 5 3
      MediaBrowser.Dlna/Didl/DidlBuilder.cs
  18. 5 6
      MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
  19. 15 16
      MediaBrowser.Dlna/PlayTo/PlayToController.cs
  20. 6 7
      MediaBrowser.Dlna/PlayTo/PlayToManager.cs
  21. 9 41
      MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
  22. 3 0
      MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
  23. 3 0
      MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
  24. 1 0
      MediaBrowser.Model/MediaBrowser.Model.csproj
  25. 10 11
      MediaBrowser.Model/Sync/SyncDialogOptions.cs
  26. 17 0
      MediaBrowser.Model/Sync/SyncQualityOption.cs
  27. 4 2
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  28. 148 2
      MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
  29. 1 0
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  30. 4 2
      MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs
  31. 5 3
      MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
  32. 6 4
      MediaBrowser.Server.Implementations/Sync/SyncManager.cs
  33. 17 0
      MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs
  34. 7 5
      MediaBrowser.Server.Startup.Common/ApplicationHost.cs

+ 15 - 49
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -1,10 +1,9 @@
-using MediaBrowser.Controller.Devices;
-using MediaBrowser.Controller.Diagnostics;
-using MediaBrowser.Model.Extensions;
-using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Devices;
+using MediaBrowser.Controller.Diagnostics;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
@@ -15,6 +14,7 @@ using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Drawing;
 using MediaBrowser.Model.Drawing;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
 using System;
 using System;
@@ -69,19 +69,19 @@ namespace MediaBrowser.Api.Playback
         protected ILiveTvManager LiveTvManager { get; private set; }
         protected ILiveTvManager LiveTvManager { get; private set; }
         protected IDlnaManager DlnaManager { get; private set; }
         protected IDlnaManager DlnaManager { get; private set; }
         protected IDeviceManager DeviceManager { get; private set; }
         protected IDeviceManager DeviceManager { get; private set; }
-        protected IChannelManager ChannelManager { get; private set; }
         protected ISubtitleEncoder SubtitleEncoder { get; private set; }
         protected ISubtitleEncoder SubtitleEncoder { get; private set; }
         protected IProcessManager ProcessManager { get; private set; }
         protected IProcessManager ProcessManager { get; private set; }
+        protected IMediaSourceManager MediaSourceManager { get; private set; }
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
         /// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
         /// </summary>
         /// </summary>
-        protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager)
+        protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IMediaSourceManager mediaSourceManager)
         {
         {
+            MediaSourceManager = mediaSourceManager;
             ProcessManager = processManager;
             ProcessManager = processManager;
             DeviceManager = deviceManager;
             DeviceManager = deviceManager;
             SubtitleEncoder = subtitleEncoder;
             SubtitleEncoder = subtitleEncoder;
-            ChannelManager = channelManager;
             DlnaManager = dlnaManager;
             DlnaManager = dlnaManager;
             LiveTvManager = liveTvManager;
             LiveTvManager = liveTvManager;
             FileSystem = fileSystem;
             FileSystem = fileSystem;
@@ -1657,8 +1657,8 @@ namespace MediaBrowser.Api.Playback
 
 
                 var source = string.IsNullOrEmpty(request.MediaSourceId)
                 var source = string.IsNullOrEmpty(request.MediaSourceId)
                     ? recording.GetMediaSources(false).First()
                     ? recording.GetMediaSources(false).First()
-                    : recording.GetMediaSources(false).First(i => string.Equals(i.Id, request.MediaSourceId));
-
+                    : MediaSourceManager.GetStaticMediaSource(recording, request.MediaSourceId, false);
+                
                 mediaStreams = source.MediaStreams;
                 mediaStreams = source.MediaStreams;
 
 
                 // Just to prevent this from being null and causing other methods to fail
                 // Just to prevent this from being null and causing other methods to fail
@@ -1696,25 +1696,13 @@ namespace MediaBrowser.Api.Playback
                 // Just to prevent this from being null and causing other methods to fail
                 // Just to prevent this from being null and causing other methods to fail
                 state.MediaPath = string.Empty;
                 state.MediaPath = string.Empty;
             }
             }
-            else if (item is IChannelMediaItem)
-            {
-                var mediaSource = await GetChannelMediaInfo(request.Id, request.MediaSourceId, cancellationToken).ConfigureAwait(false);
-                state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
-                state.InputProtocol = mediaSource.Protocol;
-                state.MediaPath = mediaSource.Path;
-                state.RunTimeTicks = item.RunTimeTicks;
-                state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders;
-                state.InputBitrate = mediaSource.Bitrate;
-                state.InputFileSize = mediaSource.Size;
-                state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
-                mediaStreams = mediaSource.MediaStreams;
-            }
             else
             else
             {
             {
-                var hasMediaSources = (IHasMediaSources)item;
+                var mediaSources = await MediaSourceManager.GetPlayackMediaSources(request.Id, cancellationToken).ConfigureAwait(false);
+
                 var mediaSource = string.IsNullOrEmpty(request.MediaSourceId)
                 var mediaSource = string.IsNullOrEmpty(request.MediaSourceId)
-                    ? hasMediaSources.GetMediaSources(false).First()
-                    : hasMediaSources.GetMediaSources(false).First(i => string.Equals(i.Id, request.MediaSourceId));
+                    ? mediaSources.First()
+                    : mediaSources.First(i => string.Equals(i.Id, request.MediaSourceId));
 
 
                 mediaStreams = mediaSource.MediaStreams;
                 mediaStreams = mediaSource.MediaStreams;
 
 
@@ -1724,6 +1712,8 @@ namespace MediaBrowser.Api.Playback
                 state.InputFileSize = mediaSource.Size;
                 state.InputFileSize = mediaSource.Size;
                 state.InputBitrate = mediaSource.Bitrate;
                 state.InputBitrate = mediaSource.Bitrate;
                 state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
                 state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
+                state.RunTimeTicks = mediaSource.RunTimeTicks;
+                state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders;
 
 
                 var video = item as Video;
                 var video = item as Video;
 
 
@@ -1746,7 +1736,6 @@ namespace MediaBrowser.Api.Playback
                     }
                     }
                 }
                 }
 
 
-                state.RunTimeTicks = mediaSource.RunTimeTicks;
             }
             }
 
 
             var videoRequest = request as VideoStreamRequest;
             var videoRequest = request as VideoStreamRequest;
@@ -1869,29 +1858,6 @@ namespace MediaBrowser.Api.Playback
             state.AllMediaStreams = mediaStreams;
             state.AllMediaStreams = mediaStreams;
         }
         }
 
 
-        private async Task<MediaSourceInfo> GetChannelMediaInfo(string id,
-            string mediaSourceId,
-            CancellationToken cancellationToken)
-        {
-            var channelMediaSources = await ChannelManager.GetChannelItemMediaSources(id, true, cancellationToken)
-                .ConfigureAwait(false);
-
-            var list = channelMediaSources.ToList();
-
-            if (!string.IsNullOrWhiteSpace(mediaSourceId))
-            {
-                var source = list
-                    .FirstOrDefault(i => string.Equals(mediaSourceId, i.Id));
-
-                if (source != null)
-                {
-                    return source;
-                }
-            }
-
-            return list.First();
-        }
-
         private bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream)
         private bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream)
         {
         {
             if (videoStream.IsInterlaced)
             if (videoStream.IsInterlaced)

+ 1 - 1
MediaBrowser.Api/Playback/Hls/BaseHlsService.cs

@@ -24,7 +24,7 @@ namespace MediaBrowser.Api.Playback.Hls
     /// </summary>
     /// </summary>
     public abstract class BaseHlsService : BaseStreamingService
     public abstract class BaseHlsService : BaseStreamingService
     {
     {
-        protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, processManager)
+        protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IMediaSourceManager mediaSourceManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, subtitleEncoder, deviceManager, processManager, mediaSourceManager)
         {
         {
         }
         }
 
 

+ 5 - 6
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -1,10 +1,8 @@
-using MediaBrowser.Controller.Devices;
-using MediaBrowser.Controller.Diagnostics;
-using MediaBrowser.Model.Extensions;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Devices;
+using MediaBrowser.Controller.Diagnostics;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.LiveTv;
@@ -12,6 +10,7 @@ using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using ServiceStack;
 using ServiceStack;
 using System;
 using System;
@@ -64,7 +63,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
 
     public class DynamicHlsService : BaseHlsService
     public class DynamicHlsService : BaseHlsService
     {
     {
-        public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, processManager)
+        public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IMediaSourceManager mediaSourceManager, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, subtitleEncoder, deviceManager, processManager, mediaSourceManager)
         {
         {
             NetworkManager = networkManager;
             NetworkManager = networkManager;
         }
         }

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

@@ -1,6 +1,5 @@
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Diagnostics;
 using MediaBrowser.Controller.Diagnostics;
@@ -52,7 +51,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
 
     public class MpegDashService : BaseHlsService
     public class MpegDashService : BaseHlsService
     {
     {
-        public MpegDashService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, processManager)
+        public MpegDashService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IMediaSourceManager mediaSourceManager, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, subtitleEncoder, deviceManager, processManager, mediaSourceManager)
         {
         {
             NetworkManager = networkManager;
             NetworkManager = networkManager;
         }
         }

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

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Diagnostics;
 using MediaBrowser.Controller.Diagnostics;
@@ -58,7 +57,7 @@ namespace MediaBrowser.Api.Playback.Hls
     /// </summary>
     /// </summary>
     public class VideoHlsService : BaseHlsService
     public class VideoHlsService : BaseHlsService
     {
     {
-        public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, processManager)
+        public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IMediaSourceManager mediaSourceManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, subtitleEncoder, deviceManager, processManager, mediaSourceManager)
         {
         {
         }
         }
 
 

+ 23 - 35
MediaBrowser.Api/Playback/MediaInfoService.cs

@@ -1,18 +1,13 @@
-using MediaBrowser.Controller.Channels;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
 using ServiceStack;
 using ServiceStack;
-using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
 namespace MediaBrowser.Api.Playback
 namespace MediaBrowser.Api.Playback
 {
 {
-    [Route("/Items/{Id}/MediaInfo", "GET", Summary = "Gets live playback media info for an item")]
     [Route("/Items/{Id}/PlaybackInfo", "GET", Summary = "Gets live playback media info for an item")]
     [Route("/Items/{Id}/PlaybackInfo", "GET", Summary = "Gets live playback media info for an item")]
     public class GetLiveMediaInfo : IReturn<LiveMediaInfoResult>
     public class GetLiveMediaInfo : IReturn<LiveMediaInfoResult>
     {
     {
@@ -23,46 +18,39 @@ namespace MediaBrowser.Api.Playback
         public string UserId { get; set; }
         public string UserId { get; set; }
     }
     }
 
 
+    [Route("/Items/{Id}/PlaybackInfo", "GET", Summary = "Gets live playback media info for an item")]
+    public class GetPlaybackInfo : IReturn<LiveMediaInfoResult>
+    {
+        [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+        public string Id { get; set; }
+
+        [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public string UserId { get; set; }
+    }
+
     [Authenticated]
     [Authenticated]
     public class MediaInfoService : BaseApiService
     public class MediaInfoService : BaseApiService
     {
     {
-        private readonly ILibraryManager _libraryManager;
-        private readonly IChannelManager _channelManager;
-        private readonly IUserManager _userManager;
+        private readonly IMediaSourceManager _mediaSourceManager;
 
 
-        public MediaInfoService(ILibraryManager libraryManager, IChannelManager channelManager, IUserManager userManager)
+        public MediaInfoService(IMediaSourceManager mediaSourceManager)
         {
         {
-            _libraryManager = libraryManager;
-            _channelManager = channelManager;
-            _userManager = userManager;
+            _mediaSourceManager = mediaSourceManager;
         }
         }
 
 
-        public async Task<object> Get(GetLiveMediaInfo request)
+        public async Task<object> Get(GetPlaybackInfo request)
         {
         {
-            var item = _libraryManager.GetItemById(request.Id);
-            IEnumerable<MediaSourceInfo> mediaSources;
-
-            var channelItem = item as IChannelMediaItem;
-            var user = _userManager.GetUserById(request.UserId);
+            var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.Id, request.UserId, CancellationToken.None).ConfigureAwait(false);
 
 
-            if (channelItem != null)
-            {
-                mediaSources = await _channelManager.GetChannelItemMediaSources(request.Id, true, CancellationToken.None)
-                        .ConfigureAwait(false);
-            }
-            else
+            return ToOptimizedResult(new LiveMediaInfoResult
             {
             {
-                var hasMediaSources = (IHasMediaSources)item;
+                MediaSources = mediaSources.ToList()
+            });
+        }
 
 
-                if (user == null)
-                {
-                    mediaSources = hasMediaSources.GetMediaSources(true);
-                }
-                else
-                {
-                    mediaSources = hasMediaSources.GetMediaSources(true, user);
-                }
-            }
+        public async Task<object> Get(GetLiveMediaInfo request)
+        {
+            var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.Id, request.UserId, CancellationToken.None).ConfigureAwait(false);
 
 
             return ToOptimizedResult(new LiveMediaInfoResult
             return ToOptimizedResult(new LiveMediaInfoResult
             {
             {

+ 1 - 1
MediaBrowser.Api/Playback/Progressive/AudioService.cs

@@ -33,7 +33,7 @@ namespace MediaBrowser.Api.Playback.Progressive
     /// </summary>
     /// </summary>
     public class AudioService : BaseProgressiveStreamingService
     public class AudioService : BaseProgressiveStreamingService
     {
     {
-        public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, processManager, imageProcessor, httpClient)
+        public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IMediaSourceManager mediaSourceManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, subtitleEncoder, deviceManager, processManager, mediaSourceManager, imageProcessor, httpClient)
         {
         {
         }
         }
 
 

+ 1 - 3
MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs

@@ -1,6 +1,5 @@
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Diagnostics;
 using MediaBrowser.Controller.Diagnostics;
@@ -16,7 +15,6 @@ using ServiceStack.Web;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.IO;
 using System.IO;
-using System.Linq;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
@@ -30,7 +28,7 @@ namespace MediaBrowser.Api.Playback.Progressive
         protected readonly IImageProcessor ImageProcessor;
         protected readonly IImageProcessor ImageProcessor;
         protected readonly IHttpClient HttpClient;
         protected readonly IHttpClient HttpClient;
 
 
-        protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, processManager)
+        protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IMediaSourceManager mediaSourceManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, subtitleEncoder, deviceManager, processManager, mediaSourceManager)
         {
         {
             ImageProcessor = imageProcessor;
             ImageProcessor = imageProcessor;
             HttpClient = httpClient;
             HttpClient = httpClient;

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

@@ -1,6 +1,5 @@
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Diagnostics;
 using MediaBrowser.Controller.Diagnostics;
@@ -64,7 +63,7 @@ namespace MediaBrowser.Api.Playback.Progressive
     /// </summary>
     /// </summary>
     public class VideoService : BaseProgressiveStreamingService
     public class VideoService : BaseProgressiveStreamingService
     {
     {
-        public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, processManager, imageProcessor, httpClient)
+        public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IProcessManager processManager, IMediaSourceManager mediaSourceManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, subtitleEncoder, deviceManager, processManager, mediaSourceManager, imageProcessor, httpClient)
         {
         {
         }
         }
 
 

+ 4 - 3
MediaBrowser.Api/Subtitles/SubtitleService.cs

@@ -124,20 +124,21 @@ namespace MediaBrowser.Api.Subtitles
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
         private readonly ISubtitleManager _subtitleManager;
         private readonly ISubtitleManager _subtitleManager;
         private readonly ISubtitleEncoder _subtitleEncoder;
         private readonly ISubtitleEncoder _subtitleEncoder;
+        private readonly IMediaSourceManager _mediaSourceManager;
 
 
-        public SubtitleService(ILibraryManager libraryManager, ISubtitleManager subtitleManager, ISubtitleEncoder subtitleEncoder)
+        public SubtitleService(ILibraryManager libraryManager, ISubtitleManager subtitleManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager)
         {
         {
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _subtitleManager = subtitleManager;
             _subtitleManager = subtitleManager;
             _subtitleEncoder = subtitleEncoder;
             _subtitleEncoder = subtitleEncoder;
+            _mediaSourceManager = mediaSourceManager;
         }
         }
 
 
         public object Get(GetSubtitlePlaylist request)
         public object Get(GetSubtitlePlaylist request)
         {
         {
             var item = (Video)_libraryManager.GetItemById(new Guid(request.Id));
             var item = (Video)_libraryManager.GetItemById(new Guid(request.Id));
 
 
-            var mediaSource = item.GetMediaSources(false)
-                .First(i => string.Equals(i.Id, request.MediaSourceId ?? request.Id));
+            var mediaSource = _mediaSourceManager.GetStaticMediaSource(item, request.MediaSourceId, false);
 
 
             var builder = new StringBuilder();
             var builder = new StringBuilder();
 
 

+ 1 - 53
MediaBrowser.Controller/Entities/IHasMediaSources.cs

@@ -1,9 +1,6 @@
-using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Dto;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Linq;
 
 
 namespace MediaBrowser.Controller.Entities
 namespace MediaBrowser.Controller.Entities
 {
 {
@@ -22,53 +19,4 @@ namespace MediaBrowser.Controller.Entities
         /// <returns>Task{IEnumerable{MediaSourceInfo}}.</returns>
         /// <returns>Task{IEnumerable{MediaSourceInfo}}.</returns>
         IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
         IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
     }
     }
-
-    public static class HasMediaSourceExtensions
-    {
-        public static IEnumerable<MediaSourceInfo> GetMediaSources(this IHasMediaSources item, bool enablePathSubstitution, User user)
-        {
-            if (item == null)
-            {
-                throw new ArgumentNullException("item");
-            }
-
-            if (!(item is Video))
-            {
-                return item.GetMediaSources(enablePathSubstitution);
-            }
-
-            if (user == null)
-            {
-                throw new ArgumentNullException("user");
-            }
-
-            var sources = item.GetMediaSources(enablePathSubstitution).ToList();
-
-            var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference)
-            ? new string[] { }
-            : new[] { user.Configuration.AudioLanguagePreference };
-
-            var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference)
-                ? new List<string> { }
-                : new List<string> { user.Configuration.SubtitleLanguagePreference };
-
-            foreach (var source in sources)
-            {
-                source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(
-                    source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack);
-
-                var defaultAudioIndex = source.DefaultAudioStreamIndex;
-                var audioLangage = defaultAudioIndex == null
-                    ? null
-                    : source.MediaStreams.Where(i => i.Type == MediaStreamType.Audio && i.Index == defaultAudioIndex).Select(i => i.Language).FirstOrDefault();
-
-                source.DefaultSubtitleStreamIndex = MediaStreamSelector.GetDefaultSubtitleStreamIndex(source.MediaStreams,
-                    preferredSubs,
-                    user.Configuration.SubtitleMode,
-                    audioLangage);
-            }
-
-            return sources;
-        }
-    }
 }
 }

+ 1 - 2
MediaBrowser.Controller/Entities/Video.cs

@@ -460,7 +460,7 @@ namespace MediaBrowser.Controller.Entities
 
 
             return result.OrderBy(i =>
             return result.OrderBy(i =>
             {
             {
-                if (item.VideoType == VideoType.VideoFile)
+                if (i.VideoType == VideoType.VideoFile)
                 {
                 {
                     return 0;
                     return 0;
                 }
                 }
@@ -556,7 +556,6 @@ namespace MediaBrowser.Controller.Entities
             return info;
             return info;
         }
         }
 
 
-
         private static string GetMediaSourceName(Video video, List<MediaStream> mediaStreams)
         private static string GetMediaSourceName(Video video, List<MediaStream> mediaStreams)
         {
         {
             var terms = new List<string>();
             var terms = new List<string>();

+ 46 - 1
MediaBrowser.Controller/Library/IMediaSourceManager.cs

@@ -1,12 +1,22 @@
-using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
 
 
 namespace MediaBrowser.Controller.Library
 namespace MediaBrowser.Controller.Library
 {
 {
     public interface IMediaSourceManager
     public interface IMediaSourceManager
     {
     {
+        /// <summary>
+        /// Adds the parts.
+        /// </summary>
+        /// <param name="providers">The providers.</param>
+        void AddParts(IEnumerable<IMediaSourceProvider> providers);
+
         /// <summary>
         /// <summary>
         /// Gets the media streams.
         /// Gets the media streams.
         /// </summary>
         /// </summary>
@@ -25,5 +35,40 @@ namespace MediaBrowser.Controller.Library
         /// <param name="query">The query.</param>
         /// <param name="query">The query.</param>
         /// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
         /// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
         IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query);
         IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query);
+
+        /// <summary>
+        /// Gets the playack media sources.
+        /// </summary>
+        /// <param name="id">The identifier.</param>
+        /// <param name="userId">The user identifier.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>IEnumerable&lt;MediaSourceInfo&gt;.</returns>
+        Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, string userId, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Gets the playack media sources.
+        /// </summary>
+        /// <param name="id">The identifier.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task&lt;IEnumerable&lt;MediaSourceInfo&gt;&gt;.</returns>
+        Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Gets the static media sources.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
+        /// <param name="user">The user.</param>
+        /// <returns>IEnumerable&lt;MediaSourceInfo&gt;.</returns>
+        IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user);
+
+        /// <summary>
+        /// Gets the static media source.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="mediaSourceId">The media source identifier.</param>
+        /// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
+        /// <returns>MediaSourceInfo.</returns>
+        MediaSourceInfo GetStaticMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution);
     }
     }
 }
 }

+ 19 - 0
MediaBrowser.Controller/Library/IMediaSourceProvider.cs

@@ -0,0 +1,19 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Dto;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Library
+{
+    public interface IMediaSourceProvider
+    {
+        /// <summary>
+        /// Gets the media sources.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task&lt;IEnumerable&lt;MediaSourceInfo&gt;&gt;.</returns>
+        Task<IEnumerable<MediaSourceInfo>> GetMediaSources(IHasMediaSources item, CancellationToken cancellationToken);
+    }
+}

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

@@ -172,6 +172,7 @@
     <Compile Include="Library\DeleteOptions.cs" />
     <Compile Include="Library\DeleteOptions.cs" />
     <Compile Include="Library\ILibraryPostScanTask.cs" />
     <Compile Include="Library\ILibraryPostScanTask.cs" />
     <Compile Include="Library\IMediaSourceManager.cs" />
     <Compile Include="Library\IMediaSourceManager.cs" />
+    <Compile Include="Library\IMediaSourceProvider.cs" />
     <Compile Include="Library\IMetadataFileSaver.cs" />
     <Compile Include="Library\IMetadataFileSaver.cs" />
     <Compile Include="Library\IMetadataSaver.cs" />
     <Compile Include="Library\IMetadataSaver.cs" />
     <Compile Include="Library\IMusicManager.cs" />
     <Compile Include="Library\IMusicManager.cs" />

+ 3 - 2
MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs

@@ -32,7 +32,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
         private readonly IChannelManager _channelManager;
         private readonly IChannelManager _channelManager;
         private readonly IUserDataManager _userDataManager;
         private readonly IUserDataManager _userDataManager;
-        private IServerConfigurationManager _config;
+        private readonly IServerConfigurationManager _config;
         private readonly User _user;
         private readonly User _user;
 
 
         private const string NS_DC = "http://purl.org/dc/elements/1.1/";
         private const string NS_DC = "http://purl.org/dc/elements/1.1/";
@@ -46,6 +46,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
         private readonly DidlBuilder _didlBuilder;
         private readonly DidlBuilder _didlBuilder;
 
 
         private readonly DeviceProfile _profile;
         private readonly DeviceProfile _profile;
+        private readonly IMediaSourceManager _mediaSourceManager;
 
 
         public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager)
         public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager)
             : base(config, logger)
             : base(config, logger)
@@ -58,7 +59,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
             _profile = profile;
             _profile = profile;
             _config = config;
             _config = config;
 
 
-            _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization);
+            _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, _mediaSourceManager);
         }
         }
 
 
         protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, Headers methodParams)
         protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, Headers methodParams)

+ 5 - 3
MediaBrowser.Dlna/Didl/DidlBuilder.cs

@@ -37,14 +37,16 @@ namespace MediaBrowser.Dlna.Didl
         private readonly User _user;
         private readonly User _user;
         private readonly IUserDataManager _userDataManager;
         private readonly IUserDataManager _userDataManager;
         private readonly ILocalizationManager _localization;
         private readonly ILocalizationManager _localization;
+        private readonly IMediaSourceManager _mediaSourceManager;
 
 
-        public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, string accessToken, IUserDataManager userDataManager, ILocalizationManager localization)
+        public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, string accessToken, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager)
         {
         {
             _profile = profile;
             _profile = profile;
             _imageProcessor = imageProcessor;
             _imageProcessor = imageProcessor;
             _serverAddress = serverAddress;
             _serverAddress = serverAddress;
             _userDataManager = userDataManager;
             _userDataManager = userDataManager;
             _localization = localization;
             _localization = localization;
+            _mediaSourceManager = mediaSourceManager;
             _accessToken = accessToken;
             _accessToken = accessToken;
             _user = user;
             _user = user;
         }
         }
@@ -122,7 +124,7 @@ namespace MediaBrowser.Dlna.Didl
         {
         {
             if (streamInfo == null)
             if (streamInfo == null)
             {
             {
-                var sources = _user == null ? video.GetMediaSources(true).ToList() : video.GetMediaSources(true, _user).ToList();
+                var sources = _user == null ? video.GetMediaSources(true).ToList() : _mediaSourceManager.GetStaticMediaSources(video, true, _user).ToList();
 
 
                 streamInfo = new StreamBuilder().BuildVideoItem(new VideoOptions
                 streamInfo = new StreamBuilder().BuildVideoItem(new VideoOptions
                 {
                 {
@@ -342,7 +344,7 @@ namespace MediaBrowser.Dlna.Didl
 
 
             if (streamInfo == null)
             if (streamInfo == null)
             {
             {
-                var sources = _user == null ? audio.GetMediaSources(true).ToList() : audio.GetMediaSources(true, _user).ToList();
+                var sources = _user == null ? audio.GetMediaSources(true).ToList() : _mediaSourceManager.GetStaticMediaSources(audio, true, _user).ToList();
 
 
                 streamInfo = new StreamBuilder().BuildAudioItem(new AudioOptions
                 streamInfo = new StreamBuilder().BuildAudioItem(new AudioOptions
                {
                {

+ 5 - 6
MediaBrowser.Dlna/Main/DlnaEntryPoint.cs

@@ -7,7 +7,6 @@ using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Localization;
-using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Dlna.Channels;
 using MediaBrowser.Dlna.Channels;
@@ -30,13 +29,13 @@ namespace MediaBrowser.Dlna.Main
         private PlayToManager _manager;
         private PlayToManager _manager;
         private readonly ISessionManager _sessionManager;
         private readonly ISessionManager _sessionManager;
         private readonly IHttpClient _httpClient;
         private readonly IHttpClient _httpClient;
-        private readonly IItemRepository _itemRepo;
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
         private readonly IUserManager _userManager;
         private readonly IUserManager _userManager;
         private readonly IDlnaManager _dlnaManager;
         private readonly IDlnaManager _dlnaManager;
         private readonly IImageProcessor _imageProcessor;
         private readonly IImageProcessor _imageProcessor;
         private readonly IUserDataManager _userDataManager;
         private readonly IUserDataManager _userDataManager;
         private readonly ILocalizationManager _localization;
         private readonly ILocalizationManager _localization;
+        private readonly IMediaSourceManager _mediaSourceManager;
 
 
         private SsdpHandler _ssdpHandler;
         private SsdpHandler _ssdpHandler;
         private DeviceDiscovery _deviceDiscovery;
         private DeviceDiscovery _deviceDiscovery;
@@ -44,20 +43,20 @@ namespace MediaBrowser.Dlna.Main
         private readonly List<string> _registeredServerIds = new List<string>();
         private readonly List<string> _registeredServerIds = new List<string>();
         private bool _dlnaServerStarted;
         private bool _dlnaServerStarted;
 
 
-        public DlnaEntryPoint(IServerConfigurationManager config, ILogManager logManager, IServerApplicationHost appHost, INetworkManager network, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IImageProcessor imageProcessor, IUserDataManager userDataManager, ILocalizationManager localization)
+        public DlnaEntryPoint(IServerConfigurationManager config, ILogManager logManager, IServerApplicationHost appHost, INetworkManager network, ISessionManager sessionManager, IHttpClient httpClient, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IImageProcessor imageProcessor, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager)
         {
         {
             _config = config;
             _config = config;
             _appHost = appHost;
             _appHost = appHost;
             _network = network;
             _network = network;
             _sessionManager = sessionManager;
             _sessionManager = sessionManager;
             _httpClient = httpClient;
             _httpClient = httpClient;
-            _itemRepo = itemRepo;
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _userManager = userManager;
             _userManager = userManager;
             _dlnaManager = dlnaManager;
             _dlnaManager = dlnaManager;
             _imageProcessor = imageProcessor;
             _imageProcessor = imageProcessor;
             _userDataManager = userDataManager;
             _userDataManager = userDataManager;
             _localization = localization;
             _localization = localization;
+            _mediaSourceManager = mediaSourceManager;
             _logger = logManager.GetLogger("Dlna");
             _logger = logManager.GetLogger("Dlna");
         }
         }
 
 
@@ -217,7 +216,6 @@ namespace MediaBrowser.Dlna.Main
                 {
                 {
                     _manager = new PlayToManager(_logger,
                     _manager = new PlayToManager(_logger,
                         _sessionManager,
                         _sessionManager,
-                        _itemRepo,
                         _libraryManager,
                         _libraryManager,
                         _userManager,
                         _userManager,
                         _dlnaManager,
                         _dlnaManager,
@@ -227,7 +225,8 @@ namespace MediaBrowser.Dlna.Main
                         _httpClient,
                         _httpClient,
                         _config,
                         _config,
                         _userDataManager,
                         _userDataManager,
-                        _localization);
+                        _localization,
+                        _mediaSourceManager);
 
 
                     _manager.Start();
                     _manager.Start();
                 }
                 }

+ 15 - 16
MediaBrowser.Dlna/PlayTo/PlayToController.cs

@@ -3,7 +3,6 @@ using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Localization;
-using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Dlna.Didl;
 using MediaBrowser.Dlna.Didl;
 using MediaBrowser.Dlna.Ssdp;
 using MediaBrowser.Dlna.Ssdp;
@@ -27,7 +26,6 @@ namespace MediaBrowser.Dlna.PlayTo
         private Device _device;
         private Device _device;
         private readonly SessionInfo _session;
         private readonly SessionInfo _session;
         private readonly ISessionManager _sessionManager;
         private readonly ISessionManager _sessionManager;
-        private readonly IItemRepository _itemRepository;
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly IDlnaManager _dlnaManager;
         private readonly IDlnaManager _dlnaManager;
@@ -35,6 +33,7 @@ namespace MediaBrowser.Dlna.PlayTo
         private readonly IImageProcessor _imageProcessor;
         private readonly IImageProcessor _imageProcessor;
         private readonly IUserDataManager _userDataManager;
         private readonly IUserDataManager _userDataManager;
         private readonly ILocalizationManager _localization;
         private readonly ILocalizationManager _localization;
+        private readonly IMediaSourceManager _mediaSourceManager;
 
 
         private readonly DeviceDiscovery _deviceDiscovery;
         private readonly DeviceDiscovery _deviceDiscovery;
         private readonly string _serverAddress;
         private readonly string _serverAddress;
@@ -55,10 +54,9 @@ namespace MediaBrowser.Dlna.PlayTo
 
 
         private Timer _updateTimer;
         private Timer _updateTimer;
 
 
-        public PlayToController(SessionInfo session, ISessionManager sessionManager, IItemRepository itemRepository, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, string accessToken, DeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization)
+        public PlayToController(SessionInfo session, ISessionManager sessionManager, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, string accessToken, DeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager)
         {
         {
             _session = session;
             _session = session;
-            _itemRepository = itemRepository;
             _sessionManager = sessionManager;
             _sessionManager = sessionManager;
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _dlnaManager = dlnaManager;
             _dlnaManager = dlnaManager;
@@ -68,6 +66,7 @@ namespace MediaBrowser.Dlna.PlayTo
             _deviceDiscovery = deviceDiscovery;
             _deviceDiscovery = deviceDiscovery;
             _userDataManager = userDataManager;
             _userDataManager = userDataManager;
             _localization = localization;
             _localization = localization;
+            _mediaSourceManager = mediaSourceManager;
             _accessToken = accessToken;
             _accessToken = accessToken;
             _logger = logger;
             _logger = logger;
         }
         }
@@ -140,7 +139,7 @@ namespace MediaBrowser.Dlna.PlayTo
         {
         {
             try
             try
             {
             {
-                var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager);
+                var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager, _mediaSourceManager);
                 if (streamInfo.Item != null)
                 if (streamInfo.Item != null)
                 {
                 {
                     var progress = GetProgressInfo(e.OldMediaInfo, streamInfo);
                     var progress = GetProgressInfo(e.OldMediaInfo, streamInfo);
@@ -150,7 +149,7 @@ namespace MediaBrowser.Dlna.PlayTo
                     ReportPlaybackStopped(e.OldMediaInfo, streamInfo, positionTicks);
                     ReportPlaybackStopped(e.OldMediaInfo, streamInfo, positionTicks);
                 }
                 }
 
 
-                streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager);
+                streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager);
                 if (streamInfo.Item == null) return;
                 if (streamInfo.Item == null) return;
                 
                 
                 var newItemProgress = GetProgressInfo(e.NewMediaInfo, streamInfo);
                 var newItemProgress = GetProgressInfo(e.NewMediaInfo, streamInfo);
@@ -167,7 +166,7 @@ namespace MediaBrowser.Dlna.PlayTo
         {
         {
             try
             try
             {
             {
-                var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager);
+                var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
 
 
                 if (streamInfo.Item == null) return;
                 if (streamInfo.Item == null) return;
 
 
@@ -229,7 +228,7 @@ namespace MediaBrowser.Dlna.PlayTo
         {
         {
             try
             try
             {
             {
-                var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager);
+                var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
 
 
                 if (info.Item != null)
                 if (info.Item != null)
                 {
                 {
@@ -248,7 +247,7 @@ namespace MediaBrowser.Dlna.PlayTo
         {
         {
             try
             try
             {
             {
-                var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager);
+                var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
 
 
                 if (info.Item != null)
                 if (info.Item != null)
                 {
                 {
@@ -376,7 +375,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
 
             if (media != null)
             if (media != null)
             {
             {
-                var info = StreamParams.ParseFromUrl(media.Url, _libraryManager);
+                var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
 
 
                 if (info.Item != null && !info.IsDirectStream)
                 if (info.Item != null && !info.IsDirectStream)
                 {
                 {
@@ -472,7 +471,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
 
             var hasMediaSources = item as IHasMediaSources;
             var hasMediaSources = item as IHasMediaSources;
             var mediaSources = hasMediaSources != null
             var mediaSources = hasMediaSources != null
-                ? (user == null ? hasMediaSources.GetMediaSources(true) : hasMediaSources.GetMediaSources(true, user)).ToList()
+                ? (user == null ? hasMediaSources.GetMediaSources(true) : _mediaSourceManager.GetStaticMediaSources(hasMediaSources, true, user)).ToList()
                 : new List<MediaSourceInfo>();
                 : new List<MediaSourceInfo>();
 
 
             var playlistItem = GetPlaylistItem(item, mediaSources, profile, _session.DeviceId, mediaSourceId, audioStreamIndex, subtitleStreamIndex);
             var playlistItem = GetPlaylistItem(item, mediaSources, profile, _session.DeviceId, mediaSourceId, audioStreamIndex, subtitleStreamIndex);
@@ -480,7 +479,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
 
             playlistItem.StreamUrl = playlistItem.StreamInfo.ToUrl(_serverAddress, _accessToken);
             playlistItem.StreamUrl = playlistItem.StreamInfo.ToUrl(_serverAddress, _accessToken);
 
 
-            var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization)
+            var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager)
                 .GetItemDidl(item, null, _session.DeviceId, new Filter(), playlistItem.StreamInfo);
                 .GetItemDidl(item, null, _session.DeviceId, new Filter(), playlistItem.StreamInfo);
 
 
             playlistItem.Didl = itemXml;
             playlistItem.Didl = itemXml;
@@ -737,7 +736,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
 
             if (media != null)
             if (media != null)
             {
             {
-                var info = StreamParams.ParseFromUrl(media.Url, _libraryManager);
+                var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
 
 
                 if (info.Item != null)
                 if (info.Item != null)
                 {
                 {
@@ -763,7 +762,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
 
             if (media != null)
             if (media != null)
             {
             {
-                var info = StreamParams.ParseFromUrl(media.Url, _libraryManager);
+                var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
 
 
                 if (info.Item != null)
                 if (info.Item != null)
                 {
                 {
@@ -824,7 +823,7 @@ namespace MediaBrowser.Dlna.PlayTo
                 return null;
                 return null;
             }
             }
 
 
-            public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManager)
+            public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager)
             {
             {
                 var request = new StreamParams
                 var request = new StreamParams
                 {
                 {
@@ -892,7 +891,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
 
                 request.MediaSource = hasMediaSources == null ?
                 request.MediaSource = hasMediaSources == null ?
                     null :
                     null :
-                    hasMediaSources.GetMediaSources(false).FirstOrDefault(i => string.Equals(i.Id, request.MediaSourceId, StringComparison.OrdinalIgnoreCase));
+                    mediaSourceManager.GetStaticMediaSource(hasMediaSources, request.MediaSourceId, false);
 
 
 
 
 
 

+ 6 - 7
MediaBrowser.Dlna/PlayTo/PlayToManager.cs

@@ -5,7 +5,6 @@ using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Localization;
-using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Dlna.Ssdp;
 using MediaBrowser.Dlna.Ssdp;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
@@ -22,7 +21,6 @@ namespace MediaBrowser.Dlna.PlayTo
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly ISessionManager _sessionManager;
         private readonly ISessionManager _sessionManager;
 
 
-        private readonly IItemRepository _itemRepository;
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
         private readonly IUserManager _userManager;
         private readonly IUserManager _userManager;
         private readonly IDlnaManager _dlnaManager;
         private readonly IDlnaManager _dlnaManager;
@@ -34,12 +32,12 @@ namespace MediaBrowser.Dlna.PlayTo
         private readonly ILocalizationManager _localization;
         private readonly ILocalizationManager _localization;
 
 
         private readonly DeviceDiscovery _deviceDiscovery;
         private readonly DeviceDiscovery _deviceDiscovery;
-        
-        public PlayToManager(ILogger logger, ISessionManager sessionManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, DeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization)
+        private readonly IMediaSourceManager _mediaSourceManager;
+
+        public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, DeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager)
         {
         {
             _logger = logger;
             _logger = logger;
             _sessionManager = sessionManager;
             _sessionManager = sessionManager;
-            _itemRepository = itemRepository;
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _userManager = userManager;
             _userManager = userManager;
             _dlnaManager = dlnaManager;
             _dlnaManager = dlnaManager;
@@ -50,6 +48,7 @@ namespace MediaBrowser.Dlna.PlayTo
             _config = config;
             _config = config;
             _userDataManager = userDataManager;
             _userDataManager = userDataManager;
             _localization = localization;
             _localization = localization;
+            _mediaSourceManager = mediaSourceManager;
         }
         }
 
 
         public void Start()
         public void Start()
@@ -102,7 +101,6 @@ namespace MediaBrowser.Dlna.PlayTo
 
 
                         sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
                         sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
                             _sessionManager,
                             _sessionManager,
-                            _itemRepository,
                             _libraryManager,
                             _libraryManager,
                             _logger,
                             _logger,
                             _dlnaManager,
                             _dlnaManager,
@@ -112,7 +110,8 @@ namespace MediaBrowser.Dlna.PlayTo
                             accessToken,
                             accessToken,
                             _deviceDiscovery,
                             _deviceDiscovery,
                             _userDataManager,
                             _userDataManager,
-                            _localization);
+                            _localization,
+                            _mediaSourceManager);
 
 
                         controller.Init(device);
                         controller.Init(device);
 
 

+ 9 - 41
MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs

@@ -23,6 +23,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         private readonly ILiveTvManager _liveTvManager;
         private readonly ILiveTvManager _liveTvManager;
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
         private readonly IChannelManager _channelManager;
         private readonly IChannelManager _channelManager;
+        private IMediaSourceManager _mediaSourceManager;
 
 
         protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
         protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
         
         
@@ -71,10 +72,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
 
                 var path = recording.RecordingInfo.Path;
                 var path = recording.RecordingInfo.Path;
                 var mediaUrl = recording.RecordingInfo.Url;
                 var mediaUrl = recording.RecordingInfo.Url;
-
+                
                 var source = string.IsNullOrEmpty(request.MediaSourceId)
                 var source = string.IsNullOrEmpty(request.MediaSourceId)
                     ? recording.GetMediaSources(false).First()
                     ? recording.GetMediaSources(false).First()
-                    : recording.GetMediaSources(false).First(i => string.Equals(i.Id, request.MediaSourceId));
+                    : _mediaSourceManager.GetStaticMediaSource(recording, request.MediaSourceId, false);
 
 
                 mediaStreams = source.MediaStreams;
                 mediaStreams = source.MediaStreams;
 
 
@@ -113,25 +114,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 // Just to prevent this from being null and causing other methods to fail
                 // Just to prevent this from being null and causing other methods to fail
                 state.MediaPath = string.Empty;
                 state.MediaPath = string.Empty;
             }
             }
-            else if (item is IChannelMediaItem)
-            {
-                var mediaSource = await GetChannelMediaInfo(request.ItemId, request.MediaSourceId, cancellationToken).ConfigureAwait(false);
-                state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
-                state.InputProtocol = mediaSource.Protocol;
-                state.MediaPath = mediaSource.Path;
-                state.RunTimeTicks = item.RunTimeTicks;
-                state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders;
-                state.InputBitrate = mediaSource.Bitrate;
-                state.InputFileSize = mediaSource.Size;
-                state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
-                mediaStreams = mediaSource.MediaStreams;
-            }
             else
             else
             {
             {
-                var hasMediaSources = (IHasMediaSources)item;
+                var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.ItemId, cancellationToken).ConfigureAwait(false);
+
                 var mediaSource = string.IsNullOrEmpty(request.MediaSourceId)
                 var mediaSource = string.IsNullOrEmpty(request.MediaSourceId)
-                    ? hasMediaSources.GetMediaSources(false).First()
-                    : hasMediaSources.GetMediaSources(false).First(i => string.Equals(i.Id, request.MediaSourceId));
+                    ? mediaSources.First()
+                    : mediaSources.First(i => string.Equals(i.Id, request.MediaSourceId));
 
 
                 mediaStreams = mediaSource.MediaStreams;
                 mediaStreams = mediaSource.MediaStreams;
 
 
@@ -141,6 +130,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 state.InputFileSize = mediaSource.Size;
                 state.InputFileSize = mediaSource.Size;
                 state.InputBitrate = mediaSource.Bitrate;
                 state.InputBitrate = mediaSource.Bitrate;
                 state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
                 state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
+                state.RunTimeTicks = mediaSource.RunTimeTicks;
+                state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders;
 
 
                 var video = item as Video;
                 var video = item as Video;
 
 
@@ -424,29 +415,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
             return bitrate;
             return bitrate;
         }
         }
 
 
-        private async Task<MediaSourceInfo> GetChannelMediaInfo(string id,
-            string mediaSourceId,
-            CancellationToken cancellationToken)
-        {
-            var channelMediaSources = await _channelManager.GetChannelItemMediaSources(id, true, cancellationToken)
-                .ConfigureAwait(false);
-
-            var list = channelMediaSources.ToList();
-
-            if (!string.IsNullOrWhiteSpace(mediaSourceId))
-            {
-                var source = list
-                    .FirstOrDefault(i => string.Equals(mediaSourceId, i.Id));
-
-                if (source != null)
-                {
-                    return source;
-                }
-            }
-
-            return list.First();
-        }
-
         protected string GetVideoBitrateParam(EncodingJob state, string videoCodec, bool isHls)
         protected string GetVideoBitrateParam(EncodingJob state, string videoCodec, bool isHls)
         {
         {
             var bitrate = state.OutputVideoBitrate;
             var bitrate = state.OutputVideoBitrate;

+ 3 - 0
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -1124,6 +1124,9 @@
     <Compile Include="..\MediaBrowser.Model\Sync\SyncQuality.cs">
     <Compile Include="..\MediaBrowser.Model\Sync\SyncQuality.cs">
       <Link>Sync\SyncQuality.cs</Link>
       <Link>Sync\SyncQuality.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Sync\SyncQualityOption.cs">
+      <Link>Sync\SyncQualityOption.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Sync\SyncTarget.cs">
     <Compile Include="..\MediaBrowser.Model\Sync\SyncTarget.cs">
       <Link>Sync\SyncTarget.cs</Link>
       <Link>Sync\SyncTarget.cs</Link>
     </Compile>
     </Compile>

+ 3 - 0
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -1083,6 +1083,9 @@
     <Compile Include="..\MediaBrowser.Model\Sync\SyncQuality.cs">
     <Compile Include="..\MediaBrowser.Model\Sync\SyncQuality.cs">
       <Link>Sync\SyncQuality.cs</Link>
       <Link>Sync\SyncQuality.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Sync\SyncQualityOption.cs">
+      <Link>Sync\SyncQualityOption.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Sync\SyncTarget.cs">
     <Compile Include="..\MediaBrowser.Model\Sync\SyncTarget.cs">
       <Link>Sync\SyncTarget.cs</Link>
       <Link>Sync\SyncTarget.cs</Link>
     </Compile>
     </Compile>

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

@@ -395,6 +395,7 @@
     <Compile Include="Sync\SyncOptions.cs" />
     <Compile Include="Sync\SyncOptions.cs" />
     <Compile Include="Sync\SyncParameter.cs" />
     <Compile Include="Sync\SyncParameter.cs" />
     <Compile Include="Sync\SyncQuality.cs" />
     <Compile Include="Sync\SyncQuality.cs" />
+    <Compile Include="Sync\SyncQualityOption.cs" />
     <Compile Include="Sync\SyncTarget.cs" />
     <Compile Include="Sync\SyncTarget.cs" />
     <Compile Include="System\LogFile.cs" />
     <Compile Include="System\LogFile.cs" />
     <Compile Include="System\PublicSystemInfo.cs" />
     <Compile Include="System\PublicSystemInfo.cs" />

+ 10 - 11
MediaBrowser.Model/Sync/SyncDialogOptions.cs

@@ -1,5 +1,4 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
-using MediaBrowser.Model.Dto;
 
 
 namespace MediaBrowser.Model.Sync
 namespace MediaBrowser.Model.Sync
 {
 {
@@ -19,33 +18,33 @@ namespace MediaBrowser.Model.Sync
         /// Gets or sets the quality options.
         /// Gets or sets the quality options.
         /// </summary>
         /// </summary>
         /// <value>The quality options.</value>
         /// <value>The quality options.</value>
-        public List<NameValuePair> QualityOptions { get; set; }
+        public List<SyncQualityOption> QualityOptions { get; set; }
         
         
         public SyncDialogOptions()
         public SyncDialogOptions()
         {
         {
             Targets = new List<SyncTarget>();
             Targets = new List<SyncTarget>();
             Options = new List<SyncJobOption>();
             Options = new List<SyncJobOption>();
-            QualityOptions = new List<NameValuePair>
+            QualityOptions = new List<SyncQualityOption>
             {
             {
-                new NameValuePair
+                new SyncQualityOption
                 {
                 {
                     Name = SyncQuality.Original.ToString(),
                     Name = SyncQuality.Original.ToString(),
-                    Value = SyncQuality.Original.ToString()
+                    Id = SyncQuality.Original.ToString()
                 },
                 },
-                new NameValuePair
+                new SyncQualityOption
                 {
                 {
                     Name = SyncQuality.High.ToString(),
                     Name = SyncQuality.High.ToString(),
-                    Value = SyncQuality.High.ToString()
+                    Id = SyncQuality.High.ToString()
                 },
                 },
-                new NameValuePair
+                new SyncQualityOption
                 {
                 {
                     Name = SyncQuality.Medium.ToString(),
                     Name = SyncQuality.Medium.ToString(),
-                    Value = SyncQuality.Medium.ToString()
+                    Id = SyncQuality.Medium.ToString()
                 },
                 },
-                new NameValuePair
+                new SyncQualityOption
                 {
                 {
                     Name = SyncQuality.Low.ToString(),
                     Name = SyncQuality.Low.ToString(),
-                    Value = SyncQuality.Low.ToString()
+                    Id = SyncQuality.Low.ToString()
                 }
                 }
             };
             };
         }
         }

+ 17 - 0
MediaBrowser.Model/Sync/SyncQualityOption.cs

@@ -0,0 +1,17 @@
+
+namespace MediaBrowser.Model.Sync
+{
+    public class SyncQualityOption
+    {
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        /// <value>The name.</value>
+        public string Name { get; set; }
+        /// <summary>
+        /// Gets or sets the identifier.
+        /// </summary>
+        /// <value>The identifier.</value>
+        public string Id { get; set; }
+    }
+}

+ 4 - 2
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -45,8 +45,9 @@ namespace MediaBrowser.Server.Implementations.Dto
         private readonly ISyncManager _syncManager;
         private readonly ISyncManager _syncManager;
         private readonly IApplicationHost _appHost;
         private readonly IApplicationHost _appHost;
         private readonly Func<IDeviceManager> _deviceManager;
         private readonly Func<IDeviceManager> _deviceManager;
+        private readonly Func<IMediaSourceManager> _mediaSourceManager;
 
 
-        public DtoService(ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func<IChannelManager> channelManagerFactory, ISyncManager syncManager, IApplicationHost appHost, Func<IDeviceManager> deviceManager)
+        public DtoService(ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func<IChannelManager> channelManagerFactory, ISyncManager syncManager, IApplicationHost appHost, Func<IDeviceManager> deviceManager, Func<IMediaSourceManager> mediaSourceManager)
         {
         {
             _logger = logger;
             _logger = logger;
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
@@ -60,6 +61,7 @@ namespace MediaBrowser.Server.Implementations.Dto
             _syncManager = syncManager;
             _syncManager = syncManager;
             _appHost = appHost;
             _appHost = appHost;
             _deviceManager = deviceManager;
             _deviceManager = deviceManager;
+            _mediaSourceManager = mediaSourceManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -257,7 +259,7 @@ namespace MediaBrowser.Server.Implementations.Dto
                     }
                     }
                     else
                     else
                     {
                     {
-                        dto.MediaSources = hasMediaSources.GetMediaSources(true, user).ToList();
+                        dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true, user).ToList();
                     }
                     }
                 }
                 }
             }
             }

+ 148 - 2
MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs

@@ -1,19 +1,38 @@
-using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
 
 
 namespace MediaBrowser.Server.Implementations.Library
 namespace MediaBrowser.Server.Implementations.Library
 {
 {
     public class MediaSourceManager : IMediaSourceManager
     public class MediaSourceManager : IMediaSourceManager
     {
     {
         private readonly IItemRepository _itemRepo;
         private readonly IItemRepository _itemRepo;
+        private readonly IUserManager _userManager;
+        private readonly ILibraryManager _libraryManager;
+        private readonly IChannelManager _channelManager;
 
 
-        public MediaSourceManager(IItemRepository itemRepo)
+        private IMediaSourceProvider[] _providers;
+
+        public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, IChannelManager channelManager)
         {
         {
             _itemRepo = itemRepo;
             _itemRepo = itemRepo;
+            _userManager = userManager;
+            _libraryManager = libraryManager;
+            _channelManager = channelManager;
+        }
+
+        public void AddParts(IEnumerable<IMediaSourceProvider> providers)
+        {
+            _providers = providers.ToArray();
         }
         }
 
 
         public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query)
         public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query)
@@ -102,5 +121,132 @@ namespace MediaBrowser.Server.Implementations.Library
 
 
             return list;
             return list;
         }
         }
+
+        public async Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, string userId, CancellationToken cancellationToken)
+        {
+            var item = _libraryManager.GetItemById(id);
+            IEnumerable<MediaSourceInfo> mediaSources;
+
+            var channelItem = item as IChannelMediaItem;
+
+            if (channelItem != null)
+            {
+                mediaSources = await _channelManager.GetChannelItemMediaSources(id, true, cancellationToken)
+                        .ConfigureAwait(false);
+            }
+            else
+            {
+                var hasMediaSources = (IHasMediaSources)item;
+
+                if (string.IsNullOrWhiteSpace(userId))
+                {
+                    mediaSources = hasMediaSources.GetMediaSources(true);
+                }
+                else
+                {
+                    var user = _userManager.GetUserById(userId);
+                    mediaSources = GetStaticMediaSources(hasMediaSources, true, user);
+                }
+            }
+
+            return mediaSources;
+        }
+
+        public Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, CancellationToken cancellationToken)
+        {
+            return GetPlayackMediaSources(id, null, cancellationToken);
+        }
+
+        public IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution)
+        {
+            if (item == null)
+            {
+                throw new ArgumentNullException("item");
+            }
+
+            if (!(item is Video))
+            {
+                return item.GetMediaSources(enablePathSubstitution);
+            }
+
+            return item.GetMediaSources(enablePathSubstitution);
+        }
+
+        public IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user)
+        {
+            if (item == null)
+            {
+                throw new ArgumentNullException("item");
+            }
+
+            if (!(item is Video))
+            {
+                return item.GetMediaSources(enablePathSubstitution);
+            }
+
+            if (user == null)
+            {
+                throw new ArgumentNullException("user");
+            }
+
+            var sources = item.GetMediaSources(enablePathSubstitution).ToList();
+
+            foreach (var source in sources)
+            {
+                SetUserProperties(source, user);
+            }
+
+            return sources;
+        }
+
+        private void SetUserProperties(MediaSourceInfo source, User user)
+        {
+            var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference)
+            ? new string[] { }
+            : new[] { user.Configuration.AudioLanguagePreference };
+
+            var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference)
+                ? new List<string> { }
+                : new List<string> { user.Configuration.SubtitleLanguagePreference };
+
+            source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack);
+
+            var defaultAudioIndex = source.DefaultAudioStreamIndex;
+            var audioLangage = defaultAudioIndex == null
+                ? null
+                : source.MediaStreams.Where(i => i.Type == MediaStreamType.Audio && i.Index == defaultAudioIndex).Select(i => i.Language).FirstOrDefault();
+
+            source.DefaultSubtitleStreamIndex = MediaStreamSelector.GetDefaultSubtitleStreamIndex(source.MediaStreams,
+                preferredSubs,
+                user.Configuration.SubtitleMode,
+                audioLangage);
+        }
+
+        private IEnumerable<MediaSourceInfo> SortMediaSources(IEnumerable<MediaSourceInfo> sources)
+        {
+            return sources.OrderBy(i =>
+            {
+                if (i.VideoType.HasValue && i.VideoType.Value == VideoType.VideoFile)
+                {
+                    return 0;
+                }
+
+                return 1;
+
+            }).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0)
+            .ThenByDescending(i =>
+            {
+                var stream = i.VideoStream;
+
+                return stream == null || stream.Width == null ? 0 : stream.Width.Value;
+            })
+            .ToList();
+        }
+
+
+        public MediaSourceInfo GetStaticMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution)
+        {
+            return GetStaticMediaSources(item, enablePathSubstitution).FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase));
+        }
     }
     }
 }
 }

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

@@ -309,6 +309,7 @@
     <Compile Include="Sync\MediaSync.cs" />
     <Compile Include="Sync\MediaSync.cs" />
     <Compile Include="Sync\MultiProviderSync.cs" />
     <Compile Include="Sync\MultiProviderSync.cs" />
     <Compile Include="Sync\ServerSyncScheduledTask.cs" />
     <Compile Include="Sync\ServerSyncScheduledTask.cs" />
+    <Compile Include="Sync\SyncedMediaSourceProvider.cs" />
     <Compile Include="Sync\SyncRegistrationInfo.cs" />
     <Compile Include="Sync\SyncRegistrationInfo.cs" />
     <Compile Include="Sync\SyncConfig.cs" />
     <Compile Include="Sync\SyncConfig.cs" />
     <Compile Include="Sync\SyncJobProcessor.cs" />
     <Compile Include="Sync\SyncJobProcessor.cs" />

+ 4 - 2
MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs

@@ -25,8 +25,9 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly ISubtitleEncoder _subtitleEncoder;
         private readonly ISubtitleEncoder _subtitleEncoder;
         private readonly IConfigurationManager _config;
         private readonly IConfigurationManager _config;
         private readonly IFileSystem _fileSystem;
         private readonly IFileSystem _fileSystem;
+        private readonly IMediaSourceManager _mediaSourceManager;
 
 
-        public SyncConvertScheduledTask(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder, ISubtitleEncoder subtitleEncoder, IConfigurationManager config, IFileSystem fileSystem)
+        public SyncConvertScheduledTask(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder, ISubtitleEncoder subtitleEncoder, IConfigurationManager config, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager)
         {
         {
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _syncRepo = syncRepo;
             _syncRepo = syncRepo;
@@ -38,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _subtitleEncoder = subtitleEncoder;
             _subtitleEncoder = subtitleEncoder;
             _config = config;
             _config = config;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
+            _mediaSourceManager = mediaSourceManager;
         }
         }
 
 
         public string Name
         public string Name
@@ -60,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
 
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         {
         {
-            return new SyncJobProcessor(_libraryManager, _syncRepo, (SyncManager)_syncManager, _logger, _userManager, _tvSeriesManager, _mediaEncoder, _subtitleEncoder, _config, _fileSystem)
+            return new SyncJobProcessor(_libraryManager, _syncRepo, (SyncManager)_syncManager, _logger, _userManager, _tvSeriesManager, _mediaEncoder, _subtitleEncoder, _config, _fileSystem, _mediaSourceManager)
                 .Sync(progress, cancellationToken);
                 .Sync(progress, cancellationToken);
         }
         }
 
 

+ 5 - 3
MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs

@@ -38,8 +38,9 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly ISubtitleEncoder _subtitleEncoder;
         private readonly ISubtitleEncoder _subtitleEncoder;
         private readonly IConfigurationManager _config;
         private readonly IConfigurationManager _config;
         private readonly IFileSystem _fileSystem;
         private readonly IFileSystem _fileSystem;
+        private readonly IMediaSourceManager _mediaSourceManager;
 
 
-        public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo, SyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder, ISubtitleEncoder subtitleEncoder, IConfigurationManager config, IFileSystem fileSystem)
+        public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo, SyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder, ISubtitleEncoder subtitleEncoder, IConfigurationManager config, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager)
         {
         {
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _syncRepo = syncRepo;
             _syncRepo = syncRepo;
@@ -51,6 +52,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _subtitleEncoder = subtitleEncoder;
             _subtitleEncoder = subtitleEncoder;
             _config = config;
             _config = config;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
+            _mediaSourceManager = mediaSourceManager;
         }
         }
 
 
         public async Task EnsureJobItems(SyncJob job)
         public async Task EnsureJobItems(SyncJob job)
@@ -491,7 +493,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             options.Context = EncodingContext.Static;
             options.Context = EncodingContext.Static;
             options.Profile = profile;
             options.Profile = profile;
             options.ItemId = item.Id.ToString("N");
             options.ItemId = item.Id.ToString("N");
-            options.MediaSources = item.GetMediaSources(false, user).ToList();
+            options.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList();
 
 
             var streamInfo = new StreamBuilder().BuildVideoItem(options);
             var streamInfo = new StreamBuilder().BuildVideoItem(options);
             var mediaSource = streamInfo.MediaSource;
             var mediaSource = streamInfo.MediaSource;
@@ -682,7 +684,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             options.Context = EncodingContext.Static;
             options.Context = EncodingContext.Static;
             options.Profile = profile;
             options.Profile = profile;
             options.ItemId = item.Id.ToString("N");
             options.ItemId = item.Id.ToString("N");
-            options.MediaSources = item.GetMediaSources(false, user).ToList();
+            options.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList();
 
 
             var streamInfo = new StreamBuilder().BuildAudioItem(options);
             var streamInfo = new StreamBuilder().BuildAudioItem(options);
             var mediaSource = streamInfo.MediaSource;
             var mediaSource = streamInfo.MediaSource;

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

@@ -47,7 +47,8 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly IFileSystem _fileSystem;
         private readonly IFileSystem _fileSystem;
         private readonly Func<ISubtitleEncoder> _subtitleEncoder;
         private readonly Func<ISubtitleEncoder> _subtitleEncoder;
         private readonly IConfigurationManager _config;
         private readonly IConfigurationManager _config;
-        private IUserDataManager _userDataManager;
+        private readonly IUserDataManager _userDataManager;
+        private readonly Func<IMediaSourceManager> _mediaSourceManager;
 
 
         private ISyncProvider[] _providers = { };
         private ISyncProvider[] _providers = { };
 
 
@@ -57,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Sync
         public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated;
         public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated;
         public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemCreated;
         public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemCreated;
 
 
-        public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager)
+        public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager)
         {
         {
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _repo = repo;
             _repo = repo;
@@ -72,6 +73,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _subtitleEncoder = subtitleEncoder;
             _subtitleEncoder = subtitleEncoder;
             _config = config;
             _config = config;
             _userDataManager = userDataManager;
             _userDataManager = userDataManager;
+            _mediaSourceManager = mediaSourceManager;
         }
         }
 
 
         public void AddParts(IEnumerable<ISyncProvider> providers)
         public void AddParts(IEnumerable<ISyncProvider> providers)
@@ -610,7 +612,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
 
         private SyncJobProcessor GetSyncJobProcessor()
         private SyncJobProcessor GetSyncJobProcessor()
         {
         {
-            return new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager, _mediaEncoder(), _subtitleEncoder(), _config, _fileSystem);
+            return new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager, _mediaEncoder(), _subtitleEncoder(), _config, _fileSystem, _mediaSourceManager());
         }
         }
 
 
         public SyncJobItem GetJobItem(string id)
         public SyncJobItem GetJobItem(string id)
@@ -677,7 +679,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             dtoOptions.Fields.Remove(ItemFields.SyncInfo);
             dtoOptions.Fields.Remove(ItemFields.SyncInfo);
 
 
             syncedItem.Item = _dtoService().GetBaseItemDto(libraryItem, dtoOptions);
             syncedItem.Item = _dtoService().GetBaseItemDto(libraryItem, dtoOptions);
-
+            
             var mediaSource = syncedItem.Item.MediaSources
             var mediaSource = syncedItem.Item.MediaSources
                .FirstOrDefault(i => string.Equals(i.Id, jobItem.MediaSourceId));
                .FirstOrDefault(i => string.Equals(i.Id, jobItem.MediaSourceId));
 
 

+ 17 - 0
MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs

@@ -0,0 +1,17 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Dto;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Sync
+{
+    public class SyncedMediaSourceProvider : IMediaSourceProvider
+    {
+        public async Task<IEnumerable<MediaSourceInfo>> GetMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
+        {
+            return new List<MediaSourceInfo>();
+        }
+    }
+}

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

@@ -447,10 +447,10 @@ namespace MediaBrowser.Server.Startup.Common
             TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager);
             TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager);
             RegisterSingleInstance(TVSeriesManager);
             RegisterSingleInstance(TVSeriesManager);
 
 
-            SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager);
+            SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager, () => MediaSourceManager);
             RegisterSingleInstance(SyncManager);
             RegisterSingleInstance(SyncManager);
 
 
-            DtoService = new DtoService(Logger, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager);
+            DtoService = new DtoService(Logger, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager);
             RegisterSingleInstance(DtoService);
             RegisterSingleInstance(DtoService);
 
 
             var encryptionManager = new EncryptionManager();
             var encryptionManager = new EncryptionManager();
@@ -462,9 +462,6 @@ namespace MediaBrowser.Server.Startup.Common
             DeviceManager = new DeviceManager(new DeviceRepository(ApplicationPaths, JsonSerializer, Logger, FileSystemManager), UserManager, FileSystemManager, LibraryMonitor, ConfigurationManager, LogManager.GetLogger("DeviceManager"));
             DeviceManager = new DeviceManager(new DeviceRepository(ApplicationPaths, JsonSerializer, Logger, FileSystemManager), UserManager, FileSystemManager, LibraryMonitor, ConfigurationManager, LogManager.GetLogger("DeviceManager"));
             RegisterSingleInstance(DeviceManager);
             RegisterSingleInstance(DeviceManager);
 
 
-            MediaSourceManager = new MediaSourceManager(ItemRepository);
-            RegisterSingleInstance(MediaSourceManager);
-
             SessionManager = new SessionManager(UserDataManager, Logger, UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager);
             SessionManager = new SessionManager(UserDataManager, Logger, UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager);
             RegisterSingleInstance(SessionManager);
             RegisterSingleInstance(SessionManager);
 
 
@@ -479,6 +476,9 @@ namespace MediaBrowser.Server.Startup.Common
             ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, Logger, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient);
             ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, Logger, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient);
             RegisterSingleInstance(ChannelManager);
             RegisterSingleInstance(ChannelManager);
 
 
+            MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, ChannelManager);
+            RegisterSingleInstance(MediaSourceManager);
+
             var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
             var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
             RegisterSingleInstance<IAppThemeManager>(appThemeManager);
             RegisterSingleInstance<IAppThemeManager>(appThemeManager);
 
 
@@ -754,6 +754,8 @@ namespace MediaBrowser.Server.Startup.Common
 
 
             ChannelManager.AddParts(GetExports<IChannel>(), GetExports<IChannelFactory>());
             ChannelManager.AddParts(GetExports<IChannel>(), GetExports<IChannelFactory>());
 
 
+            MediaSourceManager.AddParts(GetExports<IMediaSourceProvider>());
+            
             NotificationManager.AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>());
             NotificationManager.AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>());
             SyncManager.AddParts(GetExports<ISyncProvider>());
             SyncManager.AddParts(GetExports<ISyncProvider>());
         }
         }