diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index a7b91b8681..9024479999 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -239,7 +239,7 @@ namespace MediaBrowser.Controller.Entities.Audio { Id = i.Id.ToString("N"), Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File, - MediaStreams = ItemRepository.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }).ToList(), + MediaStreams = MediaSourceManager.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }).ToList(), Name = i.Name, Path = enablePathSubstituion ? GetMappedPath(i.Path, locationType) : i.Path, RunTimeTicks = i.RunTimeTicks, diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 1443d99d32..1379ba829e 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -300,6 +300,7 @@ namespace MediaBrowser.Controller.Entities public static IChannelManager ChannelManager { get; set; } public static ICollectionManager CollectionManager { get; set; } public static IImageProcessor ImageProcessor { get; set; } + public static IMediaSourceManager MediaSourceManager { get; set; } /// /// Returns a that represents this instance. diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 12c377c906..d4507bc337 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -422,7 +422,7 @@ namespace MediaBrowser.Controller.Entities public virtual IEnumerable GetMediaStreams() { - return ItemRepository.GetMediaStreams(new MediaStreamQuery + return MediaSourceManager.GetMediaStreams(new MediaStreamQuery { ItemId = Id }); @@ -435,7 +435,7 @@ namespace MediaBrowser.Controller.Entities return null; } - return ItemRepository.GetMediaStreams(new MediaStreamQuery + return MediaSourceManager.GetMediaStreams(new MediaStreamQuery { ItemId = Id, Index = DefaultVideoStreamIndex.Value @@ -474,7 +474,8 @@ namespace MediaBrowser.Controller.Entities private static MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, Video i, MediaSourceType type) { - var mediaStreams = ItemRepository.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }).ToList(); + var mediaStreams = MediaSourceManager.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }) + .ToList(); var locationType = i.LocationType; diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs new file mode 100644 index 0000000000..4378bc85d9 --- /dev/null +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -0,0 +1,11 @@ +using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Entities; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Library +{ + public interface IMediaSourceManager + { + IEnumerable GetMediaStreams(MediaStreamQuery query); + } +} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 27beabcc1f..e9531e0571 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -170,6 +170,7 @@ + diff --git a/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs b/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs index b18651a68f..57fddb2b1f 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs @@ -90,10 +90,16 @@ namespace MediaBrowser.Controller.MediaEncoding return index == -1 ? 100 : index; }) - .ThenBy(i => i.IsDefault) - .ThenBy(i => i.IsTextSubtitleStream) - .ThenBy(i => i.IsExternal) + .ThenBy(i => GetBooleanOrderBy(i.IsDefault)) + .ThenBy(i => GetBooleanOrderBy(i.SupportsExternalStream)) + .ThenBy(i => GetBooleanOrderBy(i.IsTextSubtitleStream)) + .ThenBy(i => GetBooleanOrderBy(i.IsExternal)) .ThenBy(i => i.Index); } + + private static int GetBooleanOrderBy(bool value) + { + return value ? 0 : 1; + } } } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 6076637b44..6fa29a533b 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -543,9 +543,12 @@ namespace MediaBrowser.Model.Dlna // Look for an external profile that matches the stream type (text/graphical) foreach (SubtitleProfile profile in deviceProfile.SubtitleProfiles) { - if (profile.Method == SubtitleDeliveryMethod.External && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format)) + if (subtitleStream.SupportsExternalStream) { - return profile; + if (profile.Method == SubtitleDeliveryMethod.External && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format)) + { + return profile; + } } } diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index db4a68cffb..4af32bb500 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -50,7 +50,7 @@ namespace MediaBrowser.Model.Entities /// /// The reference frames. public int? RefFrames { get; set; } - + /// /// Gets or sets the length of the packet. /// @@ -156,6 +156,12 @@ namespace MediaBrowser.Model.Entities !StringHelper.EqualsIgnoreCase(codec, "sub"); } + /// + /// Gets or sets a value indicating whether [supports external stream]. + /// + /// true if [supports external stream]; otherwise, false. + public bool SupportsExternalStream { get; set; } + /// /// Gets or sets the filename. /// diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs index 187f8814bc..c449edd071 100644 --- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs +++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs @@ -27,18 +27,18 @@ namespace MediaBrowser.Providers.Subtitles private readonly IFileSystem _fileSystem; private readonly ILibraryMonitor _monitor; private readonly ILibraryManager _libraryManager; - private readonly IItemRepository _itemRepo; + private readonly IMediaSourceManager _mediaSourceManager; public event EventHandler SubtitlesDownloaded; public event EventHandler SubtitleDownloadFailure; - public SubtitleManager(ILogger logger, IFileSystem fileSystem, ILibraryMonitor monitor, ILibraryManager libraryManager, IItemRepository itemRepo) + public SubtitleManager(ILogger logger, IFileSystem fileSystem, ILibraryMonitor monitor, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager) { _logger = logger; _fileSystem = fileSystem; _monitor = monitor; _libraryManager = libraryManager; - _itemRepo = itemRepo; + _mediaSourceManager = mediaSourceManager; } public void AddParts(IEnumerable subtitleProviders) @@ -232,7 +232,7 @@ namespace MediaBrowser.Providers.Subtitles public Task DeleteSubtitles(string itemId, int index) { - var stream = _itemRepo.GetMediaStreams(new MediaStreamQuery + var stream = _mediaSourceManager.GetMediaStreams(new MediaStreamQuery { Index = index, ItemId = new Guid(itemId), diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs new file mode 100644 index 0000000000..a45757d135 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -0,0 +1,51 @@ +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Entities; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Server.Implementations.Library +{ + public class MediaSourceManager : IMediaSourceManager + { + private readonly IItemRepository _itemRepo; + + public MediaSourceManager(IItemRepository itemRepo) + { + _itemRepo = itemRepo; + } + + public IEnumerable GetMediaStreams(MediaStreamQuery query) + { + var list = _itemRepo.GetMediaStreams(query) + .ToList(); + + foreach (var stream in list) + { + stream.SupportsExternalStream = StreamSupportsExternalStream(stream); + } + + return list; + } + + private bool StreamSupportsExternalStream(MediaStream stream) + { + if (stream.IsExternal) + { + return true; + } + + if (stream.IsTextSubtitleStream) + { + return InternalTextStreamSupportsExternalStream(stream); + } + + return false; + } + + private bool InternalTextStreamSupportsExternalStream(MediaStream stream) + { + return true; + } + } +} diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index bf11e4ef67..ce77b3db1e 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -185,6 +185,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 6166e3d65c..308f46c23b 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -56,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.Session private readonly IMusicManager _musicManager; private readonly IDtoService _dtoService; private readonly IImageProcessor _imageProcessor; - private readonly IItemRepository _itemRepo; + private readonly IMediaSourceManager _mediaSourceManager; private readonly IHttpClient _httpClient; private readonly IJsonSerializer _jsonSerializer; @@ -97,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.Session private readonly SemaphoreSlim _sessionLock = new SemaphoreSlim(1, 1); - public SessionManager(IUserDataManager userDataRepository, ILogger logger, IUserRepository userRepository, ILibraryManager libraryManager, IUserManager userManager, IMusicManager musicManager, IDtoService dtoService, IImageProcessor imageProcessor, IItemRepository itemRepo, IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IHttpClient httpClient, IAuthenticationRepository authRepo, IDeviceManager deviceManager) + public SessionManager(IUserDataManager userDataRepository, ILogger logger, IUserRepository userRepository, ILibraryManager libraryManager, IUserManager userManager, IMusicManager musicManager, IDtoService dtoService, IImageProcessor imageProcessor, IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IHttpClient httpClient, IAuthenticationRepository authRepo, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager) { _userDataRepository = userDataRepository; _logger = logger; @@ -107,12 +107,12 @@ namespace MediaBrowser.Server.Implementations.Session _musicManager = musicManager; _dtoService = dtoService; _imageProcessor = imageProcessor; - _itemRepo = itemRepo; _jsonSerializer = jsonSerializer; _appHost = appHost; _httpClient = httpClient; _authRepo = authRepo; _deviceManager = deviceManager; + _mediaSourceManager = mediaSourceManager; _deviceManager.DeviceOptionsUpdated += _deviceManager_DeviceOptionsUpdated; } @@ -1560,7 +1560,7 @@ namespace MediaBrowser.Server.Implementations.Session if (!string.IsNullOrWhiteSpace(mediaSourceId)) { - info.MediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery + info.MediaStreams = _mediaSourceManager.GetMediaStreams(new MediaStreamQuery { ItemId = new Guid(mediaSourceId) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index c299bf1553..e9d9dc46f3 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -616,7 +616,8 @@ namespace MediaBrowser.Server.Implementations.Sync IsForced = subtitle.IsForced, IsExternal = true, Language = subtitle.Language, - Path = fileInfo.Path + Path = fileInfo.Path, + SupportsExternalStream = true }); startingIndex++; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 0bf9b91425..08c32204f4 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -196,6 +196,7 @@ namespace MediaBrowser.Server.Startup.Common private ISyncRepository SyncRepository { get; set; } private ITVSeriesManager TVSeriesManager { get; set; } private ICollectionManager CollectionManager { get; set; } + private IMediaSourceManager MediaSourceManager { get; set; } private readonly StartupOptions _startupOptions; private readonly string _remotePackageName; @@ -459,7 +460,10 @@ namespace MediaBrowser.Server.Startup.Common DeviceManager = new DeviceManager(new DeviceRepository(ApplicationPaths, JsonSerializer, Logger, FileSystemManager), UserManager, FileSystemManager, LibraryMonitor, ConfigurationManager, LogManager.GetLogger("DeviceManager")); RegisterSingleInstance(DeviceManager); - SessionManager = new SessionManager(UserDataManager, Logger, UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, ItemRepository, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager); + MediaSourceManager = new MediaSourceManager(ItemRepository); + RegisterSingleInstance(MediaSourceManager); + + SessionManager = new SessionManager(UserDataManager, Logger, UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager); RegisterSingleInstance(SessionManager); var newsService = new Implementations.News.NewsService(ApplicationPaths, JsonSerializer); @@ -503,7 +507,7 @@ namespace MediaBrowser.Server.Startup.Common NotificationManager = new NotificationManager(LogManager, UserManager, ServerConfigurationManager); RegisterSingleInstance(NotificationManager); - SubtitleManager = new SubtitleManager(LogManager.GetLogger("SubtitleManager"), FileSystemManager, LibraryMonitor, LibraryManager, ItemRepository); + SubtitleManager = new SubtitleManager(LogManager.GetLogger("SubtitleManager"), FileSystemManager, LibraryMonitor, LibraryManager, MediaSourceManager); RegisterSingleInstance(SubtitleManager); ChapterManager = new ChapterManager(LibraryManager, LogManager.GetLogger("ChapterManager"), ServerConfigurationManager, ItemRepository); @@ -696,6 +700,7 @@ namespace MediaBrowser.Server.Startup.Common Folder.UserViewManager = UserViewManager; UserView.TVSeriesManager = TVSeriesManager; BaseItem.CollectionManager = CollectionManager; + BaseItem.MediaSourceManager = MediaSourceManager; } ///