From d155139e2859166d1f609ee3d2de8121aa631138 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 19 Feb 2015 19:34:05 -0500 Subject: search fixes --- MediaBrowser.Server.Implementations/Library/UserViewManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index a8ca1a2e06..71a3609001 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller.Collections; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Localization; @@ -11,12 +10,12 @@ using MediaBrowser.Model.Channels; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Library; using MediaBrowser.Model.Querying; +using MoreLinq; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MoreLinq; namespace MediaBrowser.Server.Implementations.Library { -- cgit v1.2.3 From a0c6c259e691e42905a80112993cfd419c82138d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 Feb 2015 00:45:29 -0500 Subject: dispose image magick environment on shutdown --- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 2 -- MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs | 1 + MediaBrowser.Server.Implementations/Library/UserViewManager.cs | 3 +-- .../Localization/JavaScript/javascript.json | 2 +- MediaBrowser.ServerApplication/MainStartup.cs | 5 +++-- 5 files changed, 6 insertions(+), 7 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index a28d3bd5db..bb57e9d471 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -203,8 +203,6 @@ namespace MediaBrowser.Model.Configuration public bool EnableAudioArchiveFiles { get; set; } public bool EnableVideoArchiveFiles { get; set; } - public bool EnableLegacyCollectionInView { get; set; } - /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index e942b183bc..85eadd73cf 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -822,6 +822,7 @@ namespace MediaBrowser.Server.Implementations.Drawing public void Dispose() { + Wand.CloseEnvironment(); _saveImageSizeTimer.Dispose(); } } diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index 71a3609001..8b7cfa9f2f 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -85,8 +85,7 @@ namespace MediaBrowser.Server.Implementations.Library list.Add(await GetUserView(CollectionType.Movies, string.Empty, cancellationToken).ConfigureAwait(false)); } - if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Games, StringComparison.OrdinalIgnoreCase)) - || _config.Configuration.EnableLegacyCollectionInView) + if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Games, StringComparison.OrdinalIgnoreCase))) { list.Add(await GetUserView(CollectionType.Games, string.Empty, cancellationToken).ConfigureAwait(false)); } diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 09045be9bd..691e17d781 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -69,7 +69,7 @@ "ButtonAddToCollection": "Add to collection", "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", - "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", + "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to sync, premium plugins, internet channel content, and more. {0}Learn more{1}.", "LabelSyncNoTargetsHelp": "It looks like you don't currently have any apps that support sync.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", "HeaderWelcomeToMediaBrowserWebClient": "Welcome to the Media Browser Web Client", diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index bc3bef1a0e..4bf51bc6b1 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Implementations.Logging; +using ImageMagickSharp; +using MediaBrowser.Common.Implementations.Logging; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations; using MediaBrowser.Server.Startup.Common; @@ -40,7 +41,7 @@ namespace MediaBrowser.ServerApplication var applicationPath = currentProcess.MainModule.FileName; - ImageMagickSharp.Wand.SetMagickCoderModulePath(Path.Combine(Path.GetDirectoryName(applicationPath), "ImageMagickCoders", "x86")); + Wand.SetMagickCoderModulePath(Path.Combine(Path.GetDirectoryName(applicationPath), "ImageMagickCoders", "x86")); var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService); var logManager = new NlogManager(appPaths.LogDirectoryPath, "server"); -- cgit v1.2.3 From 7fd26410a9c49e84a146dfd77a2732b2330c3834 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 Feb 2015 13:55:38 -0500 Subject: added connection manager events --- MediaBrowser.Server.Implementations/Library/UserManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 59fecc857c..bf87924613 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -192,10 +192,10 @@ namespace MediaBrowser.Server.Implementations.Library public bool IsValidUsername(string username) { // Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.) - return username.All(IsValidCharacter); + return username.All(IsValidUsernameCharacter); } - private bool IsValidCharacter(char i) + private bool IsValidUsernameCharacter(char i) { return char.IsLetterOrDigit(i) || char.Equals(i, '-') || char.Equals(i, '_') || char.Equals(i, '\'') || char.Equals(i, '.'); @@ -213,7 +213,7 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var c in username) { - if (IsValidCharacter(c)) + if (IsValidUsernameCharacter(c)) { builder.Append(c); } -- cgit v1.2.3 From 42b07f0e03762abd1d943e82970e8beba4a1dad8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 28 Feb 2015 08:43:06 -0500 Subject: support lockout after several unsuccessful login attempts --- .../Configuration/UserConfiguration.cs | 12 --------- .../Library/UserManager.cs | 30 +++++++++++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index aa49ee50d5..a78161140f 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -33,20 +33,12 @@ namespace MediaBrowser.Model.Configuration public bool DisplayMissingEpisodes { get; set; } public bool DisplayUnairedEpisodes { get; set; } - public bool EnableLiveTvManagement { get; set; } - public bool EnableLiveTvAccess { get; set; } - - public bool EnableMediaPlayback { get; set; } - public bool EnableContentDeletion { get; set; } - public bool GroupMoviesIntoBoxSets { get; set; } public string[] DisplayChannelsWithinViews { get; set; } public string[] ExcludeFoldersFromGrouping { get; set; } - public UnratedItem[] BlockUnratedItems { get; set; } - public SubtitlePlaybackMode SubtitleMode { get; set; } public bool DisplayCollectionsView { get; set; } public bool DisplayFoldersView { get; set; } @@ -69,14 +61,10 @@ namespace MediaBrowser.Model.Configuration public UserConfiguration() { PlayDefaultAudioTrack = true; - EnableLiveTvManagement = true; - EnableMediaPlayback = true; - EnableLiveTvAccess = true; LatestItemsExcludes = new string[] { }; OrderedViews = new string[] { }; DisplayChannelsWithinViews = new string[] { }; - BlockUnratedItems = new UnratedItem[] { }; ExcludeFoldersFromGrouping = new string[] { }; DisplayCollectionsView = true; diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index bf87924613..0f160bc2ec 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -259,6 +259,11 @@ namespace MediaBrowser.Server.Implementations.Library { user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow; await UpdateUser(user).ConfigureAwait(false); + await UpdateInvalidLoginAttemptCount(user, 0).ConfigureAwait(false); + } + else + { + await UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1).ConfigureAwait(false); } _logger.Info("Authentication request for {0} {1}.", user.Name, (success ? "has succeeded" : "has been denied")); @@ -266,6 +271,22 @@ namespace MediaBrowser.Server.Implementations.Library return success; } + private async Task UpdateInvalidLoginAttemptCount(User user, int newValue) + { + if (user.Policy.InvalidLoginAttemptCount != newValue || newValue > 0) + { + user.Policy.InvalidLoginAttemptCount = newValue; + + if (newValue >= 3) + { + _logger.Debug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue.ToString(CultureInfo.InvariantCulture)); + user.Policy.IsDisabled = true; + } + + await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); + } + } + private string GetPasswordHash(User user) { return string.IsNullOrEmpty(user.Password) @@ -332,11 +353,6 @@ namespace MediaBrowser.Server.Implementations.Library { if (!user.Configuration.HasMigratedToPolicy) { - user.Policy.BlockUnratedItems = user.Configuration.BlockUnratedItems; - user.Policy.EnableContentDeletion = user.Configuration.EnableContentDeletion; - user.Policy.EnableLiveTvAccess = user.Configuration.EnableLiveTvAccess; - user.Policy.EnableLiveTvManagement = user.Configuration.EnableLiveTvManagement; - user.Policy.EnableMediaPlayback = user.Configuration.EnableMediaPlayback; user.Policy.IsAdministrator = user.Configuration.IsAdministrator; await UpdateUserPolicy(user, user.Policy, false); @@ -915,10 +931,6 @@ namespace MediaBrowser.Server.Implementations.Library } user.Configuration.IsAdministrator = user.Policy.IsAdministrator; - user.Configuration.EnableLiveTvManagement = user.Policy.EnableLiveTvManagement; - user.Configuration.EnableLiveTvAccess = user.Policy.EnableLiveTvAccess; - user.Configuration.EnableMediaPlayback = user.Policy.EnableMediaPlayback; - user.Configuration.EnableContentDeletion = user.Policy.EnableContentDeletion; await UpdateConfiguration(user, user.Configuration, true).ConfigureAwait(false); } -- cgit v1.2.3 From 3d22c486700f63034f6735bc6cf3efb2ad18af22 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 28 Feb 2015 13:47:05 -0500 Subject: added IProcessManager --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 22 +++++- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 3 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 3 +- MediaBrowser.Api/Playback/Hls/MpegDashService.cs | 3 +- MediaBrowser.Api/Playback/Hls/VideoHlsService.cs | 3 +- .../Playback/Progressive/AudioService.cs | 3 +- .../Progressive/BaseProgressiveStreamingService.cs | 3 +- .../Playback/Progressive/VideoService.cs | 3 +- MediaBrowser.Api/Playback/StreamState.cs | 24 ++++++- MediaBrowser.Api/Playback/TranscodingThrottler.cs | 53 ++++++++++++--- .../Diagnostics/IProcessManager.cs | 28 ++++++++ .../MediaBrowser.Controller.csproj | 1 + .../Library/UserManager.cs | 6 +- .../Sync/FolderSync/FolderSyncProvider.cs | 1 + .../Diagnostics/LinuxProcessManager.cs | 25 +++++++ .../Diagnostics/ProcessManager.cs | 24 +++++++ .../MediaBrowser.Server.Mono.csproj | 2 + MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 13 ++++ .../ApplicationHost.cs | 2 + MediaBrowser.Server.Startup.Common/INativeApp.cs | 7 ++ .../MediaBrowser.ServerApplication.csproj | 1 + .../Native/WindowsApp.cs | 6 ++ .../Native/WindowsProcessManager.cs | 78 ++++++++++++++++++++++ 23 files changed, 291 insertions(+), 23 deletions(-) create mode 100644 MediaBrowser.Controller/Diagnostics/IProcessManager.cs create mode 100644 MediaBrowser.Server.Mono/Diagnostics/LinuxProcessManager.cs create mode 100644 MediaBrowser.Server.Mono/Diagnostics/ProcessManager.cs create mode 100644 MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index bab0d1a6e4..a40e0f8c3f 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Model.Extensions; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; @@ -70,12 +71,14 @@ namespace MediaBrowser.Api.Playback protected IDeviceManager DeviceManager { get; private set; } protected IChannelManager ChannelManager { get; private set; } protected ISubtitleEncoder SubtitleEncoder { get; private set; } + protected IProcessManager ProcessManager { get; private set; } /// /// Initializes a new instance of the class. /// - protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager) + 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) { + ProcessManager = processManager; DeviceManager = deviceManager; SubtitleEncoder = subtitleEncoder; ChannelManager = channelManager; @@ -1093,9 +1096,26 @@ namespace MediaBrowser.Api.Playback } } + StartThrottler(state, transcodingJob); + return transcodingJob; } + private void StartThrottler(StreamState state, TranscodingJob transcodingJob) + { + if (state.InputProtocol == MediaProtocol.File && + state.RunTimeTicks.HasValue && + state.VideoType == VideoType.VideoFile && + !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) + { + if (state.RunTimeTicks.Value >= TimeSpan.FromMinutes(5).Ticks && state.IsInputVideo) + { + state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, Logger, ProcessManager); + state.TranscodingThrottler.Start(); + } + } + } + private async void StartStreamingLog(TranscodingJob transcodingJob, StreamState state, Stream source, Stream target) { try diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 2da5c33ce8..fdfa6e6d76 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; @@ -23,7 +24,7 @@ namespace MediaBrowser.Api.Playback.Hls /// 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) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) + 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) { } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index e639dbdfe3..1abaf52742 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Model.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; @@ -63,7 +64,7 @@ namespace MediaBrowser.Api.Playback.Hls 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, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) + 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) { NetworkManager = networkManager; } diff --git a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs index 80451c0cc8..05909402c9 100644 --- a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs +++ b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; @@ -51,7 +52,7 @@ namespace MediaBrowser.Api.Playback.Hls 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, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) + 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) { NetworkManager = networkManager; } diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs index 8de52ea028..d27296bfdb 100644 --- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs @@ -2,6 +2,7 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; @@ -57,7 +58,7 @@ namespace MediaBrowser.Api.Playback.Hls /// 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) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) + 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) { } diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs index 37155b8f94..08ec13f4ff 100644 --- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs +++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; @@ -32,7 +33,7 @@ namespace MediaBrowser.Api.Playback.Progressive /// 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, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, imageProcessor, httpClient) + 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) { } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index bc1c86eeee..0af4587b67 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; @@ -29,7 +30,7 @@ namespace MediaBrowser.Api.Playback.Progressive protected readonly IImageProcessor ImageProcessor; protected readonly IHttpClient HttpClient; - protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) + 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) { ImageProcessor = imageProcessor; HttpClient = httpClient; diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index 7e86b867f6..9b161085a9 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; @@ -63,7 +64,7 @@ namespace MediaBrowser.Api.Playback.Progressive /// 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, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, imageProcessor, httpClient) + 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) { } diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index 40e765f1ae..588d3b75cc 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -1,17 +1,16 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Net; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Threading; -using MediaBrowser.Model.Net; namespace MediaBrowser.Api.Playback { @@ -23,6 +22,7 @@ namespace MediaBrowser.Api.Playback public string RequestedUrl { get; set; } public StreamRequest Request { get; set; } + public TranscodingThrottler TranscodingThrottler { get; set; } public VideoStreamRequest VideoRequest { @@ -125,6 +125,7 @@ namespace MediaBrowser.Api.Playback public void Dispose() { + DisposeTranscodingThrottler(); DisposeLiveStream(); DisposeLogStream(); DisposeIsoMount(); @@ -147,6 +148,23 @@ namespace MediaBrowser.Api.Playback } } + private void DisposeTranscodingThrottler() + { + if (TranscodingThrottler != null) + { + try + { + TranscodingThrottler.Dispose(); + } + catch (Exception ex) + { + _logger.ErrorException("Error disposing TranscodingThrottler", ex); + } + + TranscodingThrottler = null; + } + } + private void DisposeIsoMount() { if (IsoMount != null) diff --git a/MediaBrowser.Api/Playback/TranscodingThrottler.cs b/MediaBrowser.Api/Playback/TranscodingThrottler.cs index 50c213655b..432f4667da 100644 --- a/MediaBrowser.Api/Playback/TranscodingThrottler.cs +++ b/MediaBrowser.Api/Playback/TranscodingThrottler.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Logging; +using MediaBrowser.Controller.Diagnostics; +using MediaBrowser.Model.Logging; using System; using System.IO; using System.Threading; @@ -9,11 +10,16 @@ namespace MediaBrowser.Api.Playback { private readonly TranscodingJob _job; private readonly ILogger _logger; + private readonly IProcessManager _processManager; private Timer _timer; + private bool _isPaused; public void Start() { - _timer = new Timer(TimerCallback, null, 5000, 5000); + if (_processManager.SupportsSuspension) + { + _timer = new Timer(TimerCallback, null, 5000, 5000); + } } private void TimerCallback(object state) @@ -36,22 +42,49 @@ namespace MediaBrowser.Api.Playback private void PauseTranscoding() { - _logger.Debug("Sending pause command to ffmpeg"); - _job.Process.StandardInput.WriteLine("p"); + if (!_isPaused) + { + _logger.Debug("Sending pause command to ffmpeg"); + } + + try + { + //_job.Process.StandardInput.WriteLine("p"); + _processManager.SuspendProcess(_job.Process); + _isPaused = true; + } + catch (Exception ex) + { + _logger.ErrorException("Error pausing transcoding", ex); + } } private void UnpauseTranscoding() { - _logger.Debug("Sending unpause command to ffmpeg"); - _job.Process.StandardInput.WriteLine("u"); + if (_isPaused) + { + _logger.Debug("Sending unpause command to ffmpeg"); + } + + try + { + //_job.Process.StandardInput.WriteLine("u"); + _processManager.ResumeProcess(_job.Process); + _isPaused = false; + } + catch (Exception ex) + { + _logger.ErrorException("Error unpausing transcoding", ex); + } } private readonly long _gapLengthInTicks = TimeSpan.FromMinutes(2).Ticks; - public TranscodingThrottler(TranscodingJob job, ILogger logger) + public TranscodingThrottler(TranscodingJob job, ILogger logger, IProcessManager processManager) { _job = job; _logger = logger; + _processManager = processManager; } private bool IsThrottleAllowed(TranscodingJob job) @@ -106,13 +139,11 @@ namespace MediaBrowser.Api.Playback catch { //_logger.Error("Error getting output size"); + return false; } } - else - { - //_logger.Debug("No throttle data for " + path); - } + //_logger.Debug("No throttle data for " + path); return false; } diff --git a/MediaBrowser.Controller/Diagnostics/IProcessManager.cs b/MediaBrowser.Controller/Diagnostics/IProcessManager.cs new file mode 100644 index 0000000000..2e076bd882 --- /dev/null +++ b/MediaBrowser.Controller/Diagnostics/IProcessManager.cs @@ -0,0 +1,28 @@ +using System.Diagnostics; + +namespace MediaBrowser.Controller.Diagnostics +{ + /// + /// Interface IProcessManager + /// + public interface IProcessManager + { + /// + /// Gets a value indicating whether [supports suspension]. + /// + /// true if [supports suspension]; otherwise, false. + bool SupportsSuspension { get; } + + /// + /// Suspends the process. + /// + /// The process. + void SuspendProcess(Process process); + + /// + /// Resumes the process. + /// + /// The process. + void ResumeProcess(Process process); + } +} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 603cb02e0d..36809c5d38 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -104,6 +104,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 0f160bc2ec..846bad214e 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -277,7 +277,11 @@ namespace MediaBrowser.Server.Implementations.Library { user.Policy.InvalidLoginAttemptCount = newValue; - if (newValue >= 3) + var maxCount = user.Policy.IsAdministrator ? + 3 : + 5; + + if (newValue >= maxCount) { _logger.Debug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue.ToString(CultureInfo.InvariantCulture)); user.Policy.IsDisabled = true; diff --git a/MediaBrowser.Server.Implementations/Sync/FolderSync/FolderSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/FolderSync/FolderSyncProvider.cs index 9cf2341064..3183816c8a 100644 --- a/MediaBrowser.Server.Implementations/Sync/FolderSync/FolderSyncProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/FolderSync/FolderSyncProvider.cs @@ -113,6 +113,7 @@ namespace MediaBrowser.Server.Implementations.Sync.FolderSync private IEnumerable GetSyncAccounts() { + return new List(); // Dummy this up return _userManager .Users diff --git a/MediaBrowser.Server.Mono/Diagnostics/LinuxProcessManager.cs b/MediaBrowser.Server.Mono/Diagnostics/LinuxProcessManager.cs new file mode 100644 index 0000000000..a66365212b --- /dev/null +++ b/MediaBrowser.Server.Mono/Diagnostics/LinuxProcessManager.cs @@ -0,0 +1,25 @@ +using MediaBrowser.Controller.Diagnostics; +using System.Diagnostics; + +namespace MediaBrowser.Server.Mono.Diagnostics +{ + public class LinuxProcessManager : IProcessManager + { + public bool SupportsSuspension + { + get { return true; } + } + + public void SuspendProcess(Process process) + { + // http://jumptuck.com/2011/11/23/quick-tip-pause-process-linux/ + process.StandardInput.WriteLine("^Z"); + } + + public void ResumeProcess(Process process) + { + // http://jumptuck.com/2011/11/23/quick-tip-pause-process-linux/ + process.StandardInput.WriteLine("fg"); + } + } +} diff --git a/MediaBrowser.Server.Mono/Diagnostics/ProcessManager.cs b/MediaBrowser.Server.Mono/Diagnostics/ProcessManager.cs new file mode 100644 index 0000000000..05d1a4151a --- /dev/null +++ b/MediaBrowser.Server.Mono/Diagnostics/ProcessManager.cs @@ -0,0 +1,24 @@ +using MediaBrowser.Controller.Diagnostics; +using System; +using System.Diagnostics; + +namespace MediaBrowser.Server.Mono.Diagnostics +{ + public class ProcessManager : IProcessManager + { + public void SuspendProcess(Process process) + { + throw new NotImplementedException(); + } + + public void ResumeProcess(Process process) + { + throw new NotImplementedException(); + } + + public bool SupportsSuspension + { + get { return false; } + } + } +} diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index cd010e1c13..8b4783b5c0 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -74,6 +74,8 @@ Properties\SharedVersion.cs + + diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index 1ec0109ad8..139661aa28 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -1,6 +1,8 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.IsoMounter; using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Mono.Diagnostics; using MediaBrowser.Server.Mono.Networking; using MediaBrowser.Server.Startup.Common; using Mono.Unix.Native; @@ -189,5 +191,16 @@ namespace MediaBrowser.Server.Mono.Native public string sysname = string.Empty; public string machine = string.Empty; } + + + public IProcessManager GetProcessManager() + { + if (Environment.OperatingSystem == Startup.Common.OperatingSystem.Linux) + { + return new LinuxProcessManager(); + } + + return new ProcessManager(); + } } } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index fac704b687..63d30a6069 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -380,6 +380,8 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance(ServerConfigurationManager); + RegisterSingleInstance(NativeApp.GetProcessManager()); + LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer); RegisterSingleInstance(LocalizationManager); diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs index 2dbd844baa..1c4b5b1d58 100644 --- a/MediaBrowser.Server.Startup.Common/INativeApp.cs +++ b/MediaBrowser.Server.Startup.Common/INativeApp.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Model.Logging; using System.Collections.Generic; using System.Reflection; @@ -84,5 +85,11 @@ namespace MediaBrowser.Server.Startup.Common /// Prevents the system stand by. /// void PreventSystemStandby(); + + /// + /// Gets the process manager. + /// + /// IProcessManager. + IProcessManager GetProcessManager(); } } diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 984cca44b7..fcda32a330 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -113,6 +113,7 @@ + diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 476fb58b9d..8d25b4f722 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.IsoMounter; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Startup.Common; @@ -109,5 +110,10 @@ namespace MediaBrowser.ServerApplication.Native { Standby.PreventSystemStandby(); } + + public IProcessManager GetProcessManager() + { + return new WindowsProcessManager(); + } } } diff --git a/MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs b/MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs new file mode 100644 index 0000000000..f3497aef55 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs @@ -0,0 +1,78 @@ +using MediaBrowser.Controller.Diagnostics; +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace MediaBrowser.ServerApplication.Native +{ + public class WindowsProcessManager : IProcessManager + { + public void SuspendProcess(Process process) + { + process.Suspend(); + } + + public void ResumeProcess(Process process) + { + process.Resume(); + } + + public bool SupportsSuspension + { + get { return true; } + } + } + + public static class ProcessExtension + { + [DllImport("kernel32.dll")] + static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId); + [DllImport("kernel32.dll")] + static extern uint SuspendThread(IntPtr hThread); + [DllImport("kernel32.dll")] + static extern int ResumeThread(IntPtr hThread); + + public static void Suspend(this Process process) + { + foreach (ProcessThread thread in process.Threads) + { + var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id); + if (pOpenThread == IntPtr.Zero) + { + break; + } + SuspendThread(pOpenThread); + } + } + public static void Resume(this Process process) + { + foreach (ProcessThread thread in process.Threads) + { + var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id); + if (pOpenThread == IntPtr.Zero) + { + break; + } + ResumeThread(pOpenThread); + } + } + public static void Print(this Process process) + { + Console.WriteLine("{0,8} {1}", process.Id, process.ProcessName); + } + } + + [Flags] + public enum ThreadAccess : int + { + TERMINATE = (0x0001), + SUSPEND_RESUME = (0x0002), + GET_CONTEXT = (0x0008), + SET_CONTEXT = (0x0010), + SET_INFORMATION = (0x0020), + QUERY_INFORMATION = (0x0040), + SET_THREAD_TOKEN = (0x0080), + IMPERSONATE = (0x0100), + DIRECT_IMPERSONATION = (0x0200) + } +} -- cgit v1.2.3 From 0d8636d859cef5d0be4a723402926f05499210d7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 2 Mar 2015 00:16:29 -0500 Subject: update image magick sharp --- MediaBrowser.Controller/Library/IUserManager.cs | 1 + .../Notifications/NotificationType.cs | 3 +- .../Devices/CameraUploadsFolder.cs | 6 ++++ .../Drawing/ImageProcessor.cs | 40 +++------------------- .../EntryPoints/ActivityLogEntryPoint.cs | 12 +++++++ .../EntryPoints/Notifications/Notifications.cs | 18 +++++++++- .../Library/UserManager.cs | 13 +++++++ .../Localization/Server/server.json | 11 ++++++ .../MediaBrowser.Server.Implementations.csproj | 2 +- .../Notifications/CoreNotificationTypes.cs | 11 ++++++ .../Session/SessionManager.cs | 21 +++++++++--- .../packages.config | 2 +- .../MediaBrowser.ServerApplication.csproj | 2 +- MediaBrowser.ServerApplication/packages.config | 2 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 1 + .../MediaBrowser.WebDashboard.csproj | 9 +++++ MediaBrowser.sln | 3 ++ 17 files changed, 111 insertions(+), 46 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index 8119e5afbb..a167cdbed0 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -34,6 +34,7 @@ namespace MediaBrowser.Controller.Library event EventHandler> UserCreated; event EventHandler> UserConfigurationUpdated; event EventHandler> UserPasswordChanged; + event EventHandler> UserLockedOut; /// /// Gets a User by Id diff --git a/MediaBrowser.Model/Notifications/NotificationType.cs b/MediaBrowser.Model/Notifications/NotificationType.cs index 269e27a4fc..f5e3624f00 100644 --- a/MediaBrowser.Model/Notifications/NotificationType.cs +++ b/MediaBrowser.Model/Notifications/NotificationType.cs @@ -19,6 +19,7 @@ namespace MediaBrowser.Model.Notifications NewLibraryContentMultiple, ServerRestartRequired, TaskFailed, - CameraImageUploaded + CameraImageUploaded, + UserLockedOut } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs b/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs index 2fe5d8f742..566f4c5f40 100644 --- a/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs +++ b/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; +using System; using System.IO; using System.Linq; @@ -14,6 +15,11 @@ namespace MediaBrowser.Server.Implementations.Devices public override bool IsVisible(User user) { + if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return false; + } + return GetChildren(user, true).Any() && base.IsVisible(user); } diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index c484a60dba..180faa6bbe 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -350,9 +350,9 @@ namespace MediaBrowser.Server.Implementations.Drawing } /// - /// Increment this when indicator drawings change + /// Increment this when there's a change requiring caches to be invalidated /// - private const string IndicatorVersion = "2"; + private const string Version = "3"; /// /// Gets the cache file path based on a set of parameters @@ -371,29 +371,19 @@ namespace MediaBrowser.Server.Implementations.Drawing filename += "f=" + format; - var hasIndicator = false; - if (addPlayedIndicator) { filename += "pl=true"; - hasIndicator = true; } if (percentPlayed > 0) { filename += "p=" + percentPlayed; - hasIndicator = true; } if (unwatchedCount.HasValue) { filename += "p=" + unwatchedCount.Value; - hasIndicator = true; - } - - if (hasIndicator) - { - filename += "iv=" + IndicatorVersion; } if (!string.IsNullOrEmpty(backgroundColor)) @@ -401,6 +391,8 @@ namespace MediaBrowser.Server.Implementations.Drawing filename += "b=" + backgroundColor; } + filename += "v=" + Version; + return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower()); } @@ -671,30 +663,6 @@ namespace MediaBrowser.Server.Implementations.Drawing return enhancedImagePath; } - private ImageFormat GetFormat(string path) - { - var extension = Path.GetExtension(path); - - if (string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase)) - { - return ImageFormat.Png; - } - if (string.Equals(extension, ".gif", StringComparison.OrdinalIgnoreCase)) - { - return ImageFormat.Gif; - } - if (string.Equals(extension, ".webp", StringComparison.OrdinalIgnoreCase)) - { - return ImageFormat.Webp; - } - if (string.Equals(extension, ".bmp", StringComparison.OrdinalIgnoreCase)) - { - return ImageFormat.Bmp; - } - - return ImageFormat.Jpg; - } - /// /// Executes the image enhancers. /// diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs index 0b06613219..28883e9a21 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs @@ -86,6 +86,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _userManager.UserPasswordChanged += _userManager_UserPasswordChanged; _userManager.UserDeleted += _userManager_UserDeleted; _userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated; + _userManager.UserLockedOut += _userManager_UserLockedOut; //_config.ConfigurationUpdated += _config_ConfigurationUpdated; //_config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated; @@ -95,6 +96,16 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _appHost.ApplicationUpdated += _appHost_ApplicationUpdated; } + void _userManager_UserLockedOut(object sender, GenericEventArgs e) + { + CreateLogEntry(new ActivityLogEntry + { + Name = string.Format(_localization.GetLocalizedString("UserLockedOutWithName"), e.Argument.Name), + Type = "UserLockedOut", + UserId = e.Argument.Id.ToString("N") + }); + } + void _subManager_SubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e) { CreateLogEntry(new ActivityLogEntry @@ -482,6 +493,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _userManager.UserPasswordChanged -= _userManager_UserPasswordChanged; _userManager.UserDeleted -= _userManager_UserDeleted; _userManager.UserConfigurationUpdated -= _userManager_UserConfigurationUpdated; + _userManager.UserLockedOut -= _userManager_UserLockedOut; _config.ConfigurationUpdated -= _config_ConfigurationUpdated; _config.NamedConfigurationUpdated -= _config_NamedConfigurationUpdated; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs index 37bca4ddbc..f6a35973b7 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs @@ -78,6 +78,22 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications _appHost.HasUpdateAvailableChanged += _appHost_HasUpdateAvailableChanged; _appHost.ApplicationUpdated += _appHost_ApplicationUpdated; _deviceManager.CameraImageUploaded +=_deviceManager_CameraImageUploaded; + + _userManager.UserLockedOut += _userManager_UserLockedOut; + } + + async void _userManager_UserLockedOut(object sender, GenericEventArgs e) + { + var type = NotificationType.UserLockedOut.ToString(); + + var notification = new NotificationRequest + { + NotificationType = type + }; + + notification.Variables["UserName"] = e.Argument.Name; + + await SendNotification(notification).ConfigureAwait(false); } async void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs e) @@ -235,7 +251,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications return; } - var notification = new NotificationRequest { NotificationType = type @@ -471,6 +486,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications _appHost.ApplicationUpdated -= _appHost_ApplicationUpdated; _deviceManager.CameraImageUploaded -= _deviceManager_CameraImageUploaded; + _userManager.UserLockedOut -= _userManager_UserLockedOut; } private void DisposeLibraryUpdateTimer() diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 846bad214e..00c6744368 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -97,6 +97,7 @@ namespace MediaBrowser.Server.Implementations.Library /// public event EventHandler> UserUpdated; public event EventHandler> UserConfigurationUpdated; + public event EventHandler> UserLockedOut; /// /// Called when [user updated]. @@ -281,13 +282,25 @@ namespace MediaBrowser.Server.Implementations.Library 3 : 5; + var fireLockout = false; + if (newValue >= maxCount) { _logger.Debug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue.ToString(CultureInfo.InvariantCulture)); user.Policy.IsDisabled = true; + + fireLockout = true; } await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); + + if (fireLockout) + { + if (UserLockedOut != null) + { + EventHelper.FireEventIfNotNull(UserLockedOut, this, new GenericEventArgs(user), _logger); + } + } } } diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 5f221a7bea..2f593efcdc 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -48,8 +48,10 @@ "LabelDashboardSourcePathHelp": "If running the server from source, specify the path to the dashboard-ui folder. All web client files will be served from this location.", "ButtonConvertMedia": "Convert media", "ButtonOrganize": "Organize", + "LabelPinCode": "Pin code:", "ButtonOk": "Ok", "ButtonCancel": "Cancel", + "ButtonExit": "Exit", "ButtonNew": "New", "HeaderTV": "TV", "HeaderAudio": "Audio", @@ -57,6 +59,12 @@ "HeaderPaths": "Paths", "CategorySync": "Sync", "HeaderEasyPinCode": "Easy Pin Code", + "HeaderGrownupsOnly": "Grown-ups Only!", + "DividerOr": "-- or --", + "HeaderToAccessPleaseEnterEasyPinCode": "To access, please enter your easy pin code", + "KidsModeAdultInstruction": "Click the lock icon in the bottom right to configure or leave kids mode. Your pin code will be required.", + "ButtonConfigurePinCode": "Configure pin code", + "HeaderAdultsReadHere": "Adults Read Here!", "RegisterWithPayPal": "Register with PayPal", "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", @@ -670,6 +678,7 @@ "NotificationOptionNewLibraryContent": "New content added", "NotificationOptionNewLibraryContentMultiple": "New content added (multiple)", "NotificationOptionCameraImageUploaded": "Camera image uploaded", + "NotificationOptionUserLockedOut": "User locked out", "SendNotificationHelp": "By default, notifications are delivered to the dashboard inbox. Browse the plugin catalog to install additional notification options.", "NotificationOptionServerRestartRequired": "Server restart required", "LabelNotificationEnabled": "Enable this notification", @@ -1061,6 +1070,7 @@ "OptionBox": "Box", "OptionBoxRear": "Box rear", "OptionDisc": "Disc", + "OptionIcon": "Icon", "OptionLogo": "Logo", "OptionMenu": "Menu", "OptionScreenshot": "Screenshot", @@ -1105,6 +1115,7 @@ "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}", "LabelRunningTimeValue": "Running time: {0}", "LabelIpAddressValue": "Ip address: {0}", + "UserLockedOutWithName": "User {0} has been locked out", "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}", "UserCreatedWithName": "User {0} has been created", "UserPasswordChangedWithName": "Password has been changed for user {0}", diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index fdd53b9072..7833058f44 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -47,7 +47,7 @@ False - ..\packages\ImageMagickSharp.1.0.0.4\lib\net45\ImageMagickSharp.dll + ..\packages\ImageMagickSharp.1.0.0.5\lib\net45\ImageMagickSharp.dll False diff --git a/MediaBrowser.Server.Implementations/Notifications/CoreNotificationTypes.cs b/MediaBrowser.Server.Implementations/Notifications/CoreNotificationTypes.cs index d8acbe06c8..a33fe21477 100644 --- a/MediaBrowser.Server.Implementations/Notifications/CoreNotificationTypes.cs +++ b/MediaBrowser.Server.Implementations/Notifications/CoreNotificationTypes.cs @@ -143,6 +143,13 @@ namespace MediaBrowser.Server.Implementations.Notifications Type = NotificationType.CameraImageUploaded.ToString(), DefaultTitle = "A new camera image has been uploaded from {DeviceName}.", Variables = new List{"DeviceName"} + }, + + new NotificationTypeInfo + { + Type = NotificationType.UserLockedOut.ToString(), + DefaultTitle = "{UserName} has been locked out.", + Variables = new List{"UserName"} } }; @@ -185,6 +192,10 @@ namespace MediaBrowser.Server.Implementations.Notifications { note.Category = _localization.GetLocalizedString("CategorySync"); } + else if (note.Type.IndexOf("UserLockedOut", StringComparison.OrdinalIgnoreCase) != -1) + { + note.Category = _localization.GetLocalizedString("CategoryUser"); + } else { note.Category = _localization.GetLocalizedString("CategorySystem"); diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index d02ef9d270..3ffbf5cb90 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -399,7 +399,7 @@ namespace MediaBrowser.Server.Implementations.Session Client = clientType, DeviceId = deviceId, ApplicationVersion = appVersion, - Id = Guid.NewGuid().ToString("N") + Id = key.GetMD5().ToString("N") }; sessionInfo.DeviceName = deviceName; @@ -798,6 +798,19 @@ namespace MediaBrowser.Server.Implementations.Session return session; } + private SessionInfo GetSessionToRemoteControl(string sessionId) + { + // Accept either device id or session id + var session = Sessions.FirstOrDefault(i => string.Equals(i.Id, sessionId)); + + if (session == null) + { + throw new ResourceNotFoundException(string.Format("Session {0} not found.", sessionId)); + } + + return session; + } + public Task SendMessageCommand(string controllingSessionId, string sessionId, MessageCommand command, CancellationToken cancellationToken) { var generalCommand = new GeneralCommand @@ -818,7 +831,7 @@ namespace MediaBrowser.Server.Implementations.Session public Task SendGeneralCommand(string controllingSessionId, string sessionId, GeneralCommand command, CancellationToken cancellationToken) { - var session = GetSession(sessionId); + var session = GetSessionToRemoteControl(sessionId); var controllingSession = GetSession(controllingSessionId); AssertCanControl(session, controllingSession); @@ -828,7 +841,7 @@ namespace MediaBrowser.Server.Implementations.Session public Task SendPlayCommand(string controllingSessionId, string sessionId, PlayRequest command, CancellationToken cancellationToken) { - var session = GetSession(sessionId); + var session = GetSessionToRemoteControl(sessionId); var user = session.UserId.HasValue ? _userManager.GetUserById(session.UserId.Value) : null; @@ -955,7 +968,7 @@ namespace MediaBrowser.Server.Implementations.Session public Task SendPlaystateCommand(string controllingSessionId, string sessionId, PlaystateRequest command, CancellationToken cancellationToken) { - var session = GetSession(sessionId); + var session = GetSessionToRemoteControl(sessionId); var controllingSession = GetSession(controllingSessionId); AssertCanControl(session, controllingSession); diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index c97792fe00..b83bee17d6 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index fcda32a330..019f1e9776 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -62,7 +62,7 @@ False - ..\packages\ImageMagickSharp.1.0.0.4\lib\net45\ImageMagickSharp.dll + ..\packages\ImageMagickSharp.1.0.0.5\lib\net45\ImageMagickSharp.dll ..\packages\MediaBrowser.IsoMounting.3.0.69\lib\net45\MediaBrowser.IsoMounter.dll diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index 5e4e31b864..cf01ed6666 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 1e188ceae0..8328cf8ab4 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -421,6 +421,7 @@ namespace MediaBrowser.WebDashboard.Api "itembynamedetailpage.js", "itemdetailpage.js", "itemlistpage.js", + "kids.js", "librarypathmapping.js", "reports.js", "librarysettings.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 812deabe11..fa6413b8ba 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -87,6 +87,9 @@ + + PreserveNewest + PreserveNewest @@ -114,6 +117,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -129,6 +135,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 143a3da41b..f73971374a 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -520,4 +520,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection EndGlobal -- cgit v1.2.3 From f3159f3feff6a0ef11edb50cfc456f8c43d26d79 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 2 Mar 2015 13:48:21 -0500 Subject: update ProcessManager --- MediaBrowser.Api/Library/LibraryService.cs | 3 - .../MediaBrowser.Model.Portable.csproj | 6 ++ .../MediaBrowser.Model.net35.csproj | 6 ++ MediaBrowser.Model/Dlna/PlaybackErrorCode.cs | 9 +++ MediaBrowser.Model/Dlna/PlaybackException.cs | 9 +++ MediaBrowser.Model/Dlna/StreamBuilder.cs | 31 ++++++++- MediaBrowser.Model/Dto/MediaSourceInfo.cs | 2 + MediaBrowser.Model/MediaBrowser.Model.csproj | 2 + .../Library/Resolvers/TV/SeriesResolver.cs | 11 ++- .../MediaBrowser.Server.Implementations.csproj | 2 +- .../packages.config | 2 +- .../Diagnostics/ProcessManager.cs | 24 ------- .../MediaBrowser.Server.Mono.csproj | 1 - .../Diagnostics/ProcessManager.cs | 23 +++++++ .../MediaBrowser.Server.Startup.Common.csproj | 1 + .../MediaBrowser.ServerApplication.csproj | 3 +- .../Native/WindowsApp.cs | 3 +- .../Native/WindowsProcessManager.cs | 78 ---------------------- MediaBrowser.ServerApplication/packages.config | 2 +- 19 files changed, 97 insertions(+), 121 deletions(-) create mode 100644 MediaBrowser.Model/Dlna/PlaybackErrorCode.cs create mode 100644 MediaBrowser.Model/Dlna/PlaybackException.cs delete mode 100644 MediaBrowser.Server.Mono/Diagnostics/ProcessManager.cs create mode 100644 MediaBrowser.Server.Startup.Common/Diagnostics/ProcessManager.cs delete mode 100644 MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 85cc879f4f..4d9afa260e 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Activity; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -9,11 +8,9 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; -using MediaBrowser.Controller.Session; using MediaBrowser.Model.Activity; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using ServiceStack; using System; diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 37057f2d74..62677f8182 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -362,6 +362,12 @@ Dlna\MediaFormatProfileResolver.cs + + Dlna\PlaybackErrorCode.cs + + + Dlna\PlaybackException.cs + Dlna\ProfileCondition.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index f38a8f597b..4ed8cceae3 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -327,6 +327,12 @@ Dlna\MediaFormatProfileResolver.cs + + Dlna\PlaybackErrorCode.cs + + + Dlna\PlaybackException.cs + Dlna\ProfileCondition.cs diff --git a/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs b/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs new file mode 100644 index 0000000000..d8d65e91aa --- /dev/null +++ b/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs @@ -0,0 +1,9 @@ + +namespace MediaBrowser.Model.Dlna +{ + public enum PlaybackErrorCode + { + NotAllowed = 0, + NoCompatibleStream = 1 + } +} diff --git a/MediaBrowser.Model/Dlna/PlaybackException.cs b/MediaBrowser.Model/Dlna/PlaybackException.cs new file mode 100644 index 0000000000..761fa1c904 --- /dev/null +++ b/MediaBrowser.Model/Dlna/PlaybackException.cs @@ -0,0 +1,9 @@ +using System; + +namespace MediaBrowser.Model.Dlna +{ + public class PlaybackException : Exception + { + public PlaybackErrorCode ErrorCode { get; set;} + } +} diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index a40e4feb39..559a543f2d 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -31,7 +31,13 @@ namespace MediaBrowser.Model.Dlna List streams = new List(); foreach (MediaSourceInfo i in mediaSources) - streams.Add(BuildAudioItem(i, options)); + { + StreamInfo streamInfo = BuildAudioItem(i, options); + if (streamInfo != null) + { + streams.Add(streamInfo); + } + } foreach (StreamInfo stream in streams) { @@ -63,7 +69,13 @@ namespace MediaBrowser.Model.Dlna List streams = new List(); foreach (MediaSourceInfo i in mediaSources) - streams.Add(BuildVideoItem(i, options)); + { + StreamInfo streamInfo = BuildVideoItem(i, options); + if (streamInfo != null) + { + streams.Add(streamInfo); + } + } foreach (StreamInfo stream in streams) { @@ -97,7 +109,10 @@ namespace MediaBrowser.Model.Dlna { return stream; } - return null; + + PlaybackException error = new PlaybackException(); + error.ErrorCode = PlaybackErrorCode.NoCompatibleStream; + throw error; } private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options) @@ -186,6 +201,11 @@ namespace MediaBrowser.Model.Dlna if (transcodingProfile != null) { + if (!item.SupportsTranscoding) + { + return null; + } + playlistItem.PlayMethod = PlayMethod.Transcode; playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo; playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength; @@ -290,6 +310,11 @@ namespace MediaBrowser.Model.Dlna if (transcodingProfile != null) { + if (!item.SupportsTranscoding) + { + return null; + } + if (subtitleStream != null) { SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile, options.Context); diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs index 068443238b..cdc97b7ea7 100644 --- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs +++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs @@ -22,6 +22,7 @@ namespace MediaBrowser.Model.Dto public long? RunTimeTicks { get; set; } public bool ReadAtNativeFramerate { get; set; } + public bool SupportsTranscoding { get; set; } public VideoType? VideoType { get; set; } @@ -45,6 +46,7 @@ namespace MediaBrowser.Model.Dto MediaStreams = new List(); RequiredHttpHeaders = new Dictionary(); PlayableStreamFileNames = new List(); + SupportsTranscoding = true; } public int? DefaultAudioStreamIndex { get; set; } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 9fd632cbd0..27b5a53db0 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -125,6 +125,8 @@ + + diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index 7371ca5a9c..3551b71b7f 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -1,19 +1,18 @@ -using System.Collections.Generic; -using System.Linq; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; -using System; -using System.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Naming.Common; using MediaBrowser.Naming.IO; using MediaBrowser.Naming.TV; using MediaBrowser.Server.Implementations.Logging; -using EpisodeInfo = MediaBrowser.Controller.Providers.EpisodeInfo; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 7833058f44..a265ffdf1d 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -47,7 +47,7 @@ False - ..\packages\ImageMagickSharp.1.0.0.5\lib\net45\ImageMagickSharp.dll + ..\packages\ImageMagickSharp.1.0.0.6\lib\net45\ImageMagickSharp.dll False diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index b83bee17d6..8c530e0155 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.Server.Mono/Diagnostics/ProcessManager.cs b/MediaBrowser.Server.Mono/Diagnostics/ProcessManager.cs deleted file mode 100644 index 05d1a4151a..0000000000 --- a/MediaBrowser.Server.Mono/Diagnostics/ProcessManager.cs +++ /dev/null @@ -1,24 +0,0 @@ -using MediaBrowser.Controller.Diagnostics; -using System; -using System.Diagnostics; - -namespace MediaBrowser.Server.Mono.Diagnostics -{ - public class ProcessManager : IProcessManager - { - public void SuspendProcess(Process process) - { - throw new NotImplementedException(); - } - - public void ResumeProcess(Process process) - { - throw new NotImplementedException(); - } - - public bool SupportsSuspension - { - get { return false; } - } - } -} diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index 8b4783b5c0..8f552ee362 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -75,7 +75,6 @@ Properties\SharedVersion.cs - diff --git a/MediaBrowser.Server.Startup.Common/Diagnostics/ProcessManager.cs b/MediaBrowser.Server.Startup.Common/Diagnostics/ProcessManager.cs new file mode 100644 index 0000000000..d01756d0e2 --- /dev/null +++ b/MediaBrowser.Server.Startup.Common/Diagnostics/ProcessManager.cs @@ -0,0 +1,23 @@ +using MediaBrowser.Controller.Diagnostics; +using System.Diagnostics; + +namespace MediaBrowser.Server.Mono.Diagnostics +{ + public class ProcessManager : IProcessManager + { + public void SuspendProcess(Process process) + { + process.PriorityClass = ProcessPriorityClass.Idle; + } + + public void ResumeProcess(Process process) + { + process.PriorityClass = ProcessPriorityClass.Normal; + } + + public bool SupportsSuspension + { + get { return true; } + } + } +} diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index 38e07fde49..625b29d369 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -56,6 +56,7 @@ + diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 019f1e9776..58830360e3 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -62,7 +62,7 @@ False - ..\packages\ImageMagickSharp.1.0.0.5\lib\net45\ImageMagickSharp.dll + ..\packages\ImageMagickSharp.1.0.0.6\lib\net45\ImageMagickSharp.dll ..\packages\MediaBrowser.IsoMounting.3.0.69\lib\net45\MediaBrowser.IsoMounter.dll @@ -113,7 +113,6 @@ - diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 8d25b4f722..d518a82d4a 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Diagnostics; using MediaBrowser.IsoMounter; using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Mono.Diagnostics; using MediaBrowser.Server.Startup.Common; using MediaBrowser.ServerApplication.Networking; using System.Collections.Generic; @@ -113,7 +114,7 @@ namespace MediaBrowser.ServerApplication.Native public IProcessManager GetProcessManager() { - return new WindowsProcessManager(); + return new ProcessManager(); } } } diff --git a/MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs b/MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs deleted file mode 100644 index f3497aef55..0000000000 --- a/MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs +++ /dev/null @@ -1,78 +0,0 @@ -using MediaBrowser.Controller.Diagnostics; -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace MediaBrowser.ServerApplication.Native -{ - public class WindowsProcessManager : IProcessManager - { - public void SuspendProcess(Process process) - { - process.Suspend(); - } - - public void ResumeProcess(Process process) - { - process.Resume(); - } - - public bool SupportsSuspension - { - get { return true; } - } - } - - public static class ProcessExtension - { - [DllImport("kernel32.dll")] - static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId); - [DllImport("kernel32.dll")] - static extern uint SuspendThread(IntPtr hThread); - [DllImport("kernel32.dll")] - static extern int ResumeThread(IntPtr hThread); - - public static void Suspend(this Process process) - { - foreach (ProcessThread thread in process.Threads) - { - var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id); - if (pOpenThread == IntPtr.Zero) - { - break; - } - SuspendThread(pOpenThread); - } - } - public static void Resume(this Process process) - { - foreach (ProcessThread thread in process.Threads) - { - var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id); - if (pOpenThread == IntPtr.Zero) - { - break; - } - ResumeThread(pOpenThread); - } - } - public static void Print(this Process process) - { - Console.WriteLine("{0,8} {1}", process.Id, process.ProcessName); - } - } - - [Flags] - public enum ThreadAccess : int - { - TERMINATE = (0x0001), - SUSPEND_RESUME = (0x0002), - GET_CONTEXT = (0x0008), - SET_CONTEXT = (0x0010), - SET_INFORMATION = (0x0020), - QUERY_INFORMATION = (0x0040), - SET_THREAD_TOKEN = (0x0080), - IMPERSONATE = (0x0100), - DIRECT_IMPERSONATION = (0x0200) - } -} diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index cf01ed6666..3dd0c908d6 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file -- cgit v1.2.3 From 2fc0686c308e74654f4f7ef9ea6cf56fb61b5ff5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 3 Mar 2015 02:03:17 -0500 Subject: add date content added comparer --- MediaBrowser.Api/Playback/MediaInfoService.cs | 1 + MediaBrowser.Controller/Entities/Audio/Audio.cs | 2 +- MediaBrowser.Controller/Entities/Video.cs | 15 +++-- .../Library/IMediaSourceManager.cs | 18 ++++++ MediaBrowser.Model/Dlna/PlaybackErrorCode.cs | 3 +- .../Drawing/ImageHeader.cs | 3 +- .../Library/MediaSourceManager.cs | 55 +++++++++++++++++ .../MediaBrowser.Server.Implementations.csproj | 1 + .../Photos/BaseDynamicImageProvider.cs | 14 ++++- .../Photos/DynamicImageHelpers.cs | 15 ++++- .../Session/SessionManager.cs | 6 +- .../Sorting/DateLastMediaAddedComparer.cs | 70 ++++++++++++++++++++++ .../Sorting/DatePlayedComparer.cs | 1 - 13 files changed, 186 insertions(+), 18 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 77178c8cc1..330a8777c7 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; 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")] public class GetLiveMediaInfo : IReturn { [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 9024479999..d868227d95 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 = MediaSourceManager.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }).ToList(), + MediaStreams = MediaSourceManager.GetMediaStreams(i.Id).ToList(), Name = i.Name, Path = enablePathSubstituion ? GetMappedPath(i.Path, locationType) : i.Path, RunTimeTicks = i.RunTimeTicks, diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index d4507bc337..a0c3a6cf98 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -420,12 +420,17 @@ namespace MediaBrowser.Controller.Entities return base.GetDeletePaths(); } - public virtual IEnumerable GetMediaStreams() + public IEnumerable GetMediaStreams() { - return MediaSourceManager.GetMediaStreams(new MediaStreamQuery + var mediaSource = GetMediaSources(false) + .FirstOrDefault(); + + if (mediaSource == null) { - ItemId = Id - }); + return new List(); + } + + return mediaSource.MediaStreams; } public virtual MediaStream GetDefaultVideoStream() @@ -474,7 +479,7 @@ namespace MediaBrowser.Controller.Entities private static MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, Video i, MediaSourceType type) { - var mediaStreams = MediaSourceManager.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }) + var mediaStreams = MediaSourceManager.GetMediaStreams(i.Id) .ToList(); var locationType = i.LocationType; diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs index 4378bc85d9..5d79f613db 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -1,11 +1,29 @@ using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; +using System; using System.Collections.Generic; namespace MediaBrowser.Controller.Library { public interface IMediaSourceManager { + /// + /// Gets the media streams. + /// + /// The item identifier. + /// IEnumerable<MediaStream>. + IEnumerable GetMediaStreams(Guid itemId); + /// + /// Gets the media streams. + /// + /// The media source identifier. + /// IEnumerable<MediaStream>. + IEnumerable GetMediaStreams(string mediaSourceId); + /// + /// Gets the media streams. + /// + /// The query. + /// IEnumerable<MediaStream>. IEnumerable GetMediaStreams(MediaStreamQuery query); } } diff --git a/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs b/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs index d8d65e91aa..4ed4129854 100644 --- a/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs +++ b/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs @@ -4,6 +4,7 @@ namespace MediaBrowser.Model.Dlna public enum PlaybackErrorCode { NotAllowed = 0, - NoCompatibleStream = 1 + NoCompatibleStream = 1, + RateLimitExceeded = 2 } } diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs b/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs index 81d4a786aa..6287d0bb86 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs @@ -62,8 +62,9 @@ namespace MediaBrowser.Server.Implementations.Drawing logger.Info("Failed to read image header for {0}. Doing it the slow way.", path); } - using (var wand = new MagickWand(path)) + using (var wand = new MagickWand()) { + wand.PingImage(path); var img = wand.CurrentImage; return new ImageSize diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index a45757d135..6ce989b029 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; +using System; using System.Collections.Generic; using System.Linq; @@ -47,5 +48,59 @@ namespace MediaBrowser.Server.Implementations.Library { return true; } + + public IEnumerable GetMediaStreams(string mediaSourceId) + { + var list = GetMediaStreams(new MediaStreamQuery + { + ItemId = new Guid(mediaSourceId) + }); + + return GetMediaStreamsForItem(list); + } + + public IEnumerable GetMediaStreams(Guid itemId) + { + var list = GetMediaStreams(new MediaStreamQuery + { + ItemId = itemId + }); + + return GetMediaStreamsForItem(list); + } + + private IEnumerable GetMediaStreamsForItem(IEnumerable streams) + { + var list = streams.ToList(); + + var subtitleStreams = list + .Where(i => i.Type == MediaStreamType.Subtitle) + .ToList(); + + if (subtitleStreams.Count > 0) + { + var videoStream = list.FirstOrDefault(i => i.Type == MediaStreamType.Video); + + // This is abitrary but at some point it becomes too slow to extract subtitles on the fly + // We need to learn more about when this is the case vs. when it isn't + const int maxAllowedBitrateForExternalSubtitleStream = 10000000; + + var videoBitrate = videoStream == null ? maxAllowedBitrateForExternalSubtitleStream : videoStream.BitRate ?? maxAllowedBitrateForExternalSubtitleStream; + + foreach (var subStream in subtitleStreams) + { + var supportsExternalStream = StreamSupportsExternalStream(subStream); + + if (supportsExternalStream && videoBitrate >= maxAllowedBitrateForExternalSubtitleStream) + { + supportsExternalStream = false; + } + + subStream.SupportsExternalStream = supportsExternalStream; + } + } + + return list; + } } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index a265ffdf1d..54df9a86d5 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -278,6 +278,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs index e1f98c6592..40b85dad10 100644 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs @@ -108,7 +108,12 @@ namespace MediaBrowser.Server.Implementations.Photos protected Task GetThumbCollage(List items) { - return DynamicImageHelpers.GetThumbCollage(items.Select(i => i.GetImagePath(ImageType.Primary) ?? i.GetImagePath(ImageType.Thumb)).ToList(), + var files = items + .Select(i => i.GetImagePath(ImageType.Primary) ?? i.GetImagePath(ImageType.Thumb)) + .Where(i => !string.IsNullOrWhiteSpace(i)) + .ToList(); + + return DynamicImageHelpers.GetThumbCollage(files, FileSystem, 1600, 900, @@ -117,7 +122,12 @@ namespace MediaBrowser.Server.Implementations.Photos protected Task GetSquareCollage(List items) { - return DynamicImageHelpers.GetSquareCollage(items.Select(i => i.GetImagePath(ImageType.Primary) ?? i.GetImagePath(ImageType.Thumb)).ToList(), + var files = items + .Select(i => i.GetImagePath(ImageType.Primary) ?? i.GetImagePath(ImageType.Thumb)) + .Where(i => !string.IsNullOrWhiteSpace(i)) + .ToList(); + + return DynamicImageHelpers.GetSquareCollage(files, FileSystem, 800, ApplicationPaths); } diff --git a/MediaBrowser.Server.Implementations/Photos/DynamicImageHelpers.cs b/MediaBrowser.Server.Implementations/Photos/DynamicImageHelpers.cs index c2af9cdafc..e7cd2f4d26 100644 --- a/MediaBrowser.Server.Implementations/Photos/DynamicImageHelpers.cs +++ b/MediaBrowser.Server.Implementations/Photos/DynamicImageHelpers.cs @@ -4,6 +4,7 @@ using MediaBrowser.Common.IO; using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Photos @@ -15,6 +16,11 @@ namespace MediaBrowser.Server.Implementations.Photos int width, int height, IApplicationPaths appPaths) { + if (files.Any(string.IsNullOrWhiteSpace)) + { + throw new ArgumentException("Empty file found in files list"); + } + if (files.Count < 3) { return await GetSingleImage(files, fileSystem).ConfigureAwait(false); @@ -27,7 +33,7 @@ namespace MediaBrowser.Server.Implementations.Photos int cellHeight = height; var index = 0; - using (var wand = new MagickWand(width, height, "transparent")) + using (var wand = new MagickWand(width, height, new PixelWand(ColorName.None, 1))) { for (var row = 0; row < rows; row++) { @@ -57,6 +63,11 @@ namespace MediaBrowser.Server.Implementations.Photos IFileSystem fileSystem, int size, IApplicationPaths appPaths) { + if (files.Any(string.IsNullOrWhiteSpace)) + { + throw new ArgumentException("Empty file found in files list"); + } + if (files.Count < 4) { return await GetSingleImage(files, fileSystem).ConfigureAwait(false); @@ -68,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.Photos int singleSize = size / 2; var index = 0; - using (var wand = new MagickWand(size, size, "transparent")) + using (var wand = new MagickWand(size, size, new PixelWand(ColorName.None, 1))) { for (var row = 0; row < rows; row++) { diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 3ffbf5cb90..8eef8536ab 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1579,11 +1579,7 @@ namespace MediaBrowser.Server.Implementations.Session if (!string.IsNullOrWhiteSpace(mediaSourceId)) { - info.MediaStreams = _mediaSourceManager.GetMediaStreams(new MediaStreamQuery - { - ItemId = new Guid(mediaSourceId) - - }).ToList(); + info.MediaStreams = _mediaSourceManager.GetMediaStreams(mediaSourceId).ToList(); } return info; diff --git a/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs new file mode 100644 index 0000000000..68cd44ec94 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs @@ -0,0 +1,70 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +using System; +using System.Linq; + +namespace MediaBrowser.Server.Implementations.Sorting +{ + public class DateLastMediaAddedComparer : IUserBaseItemComparer + { + /// + /// Gets or sets the user. + /// + /// The user. + public User User { get; set; } + + /// + /// Gets or sets the user manager. + /// + /// The user manager. + public IUserManager UserManager { get; set; } + + /// + /// Gets or sets the user data repository. + /// + /// The user data repository. + public IUserDataManager UserDataRepository { get; set; } + + /// + /// Compares the specified x. + /// + /// The x. + /// The y. + /// System.Int32. + public int Compare(BaseItem x, BaseItem y) + { + return GetDate(x).CompareTo(GetDate(y)); + } + + /// + /// Gets the date. + /// + /// The x. + /// DateTime. + private DateTime GetDate(BaseItem x) + { + var folder = x as Folder; + + if (folder != null) + { + return folder.GetRecursiveChildren(User, i => !i.IsFolder) + .Select(i => i.DateCreated) + .OrderByDescending(i => i) + .FirstOrDefault(); + } + + return x.DateCreated; + } + + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get { return ItemSortBy.DateLastContentAdded; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs index 7605a7a50d..c881591beb 100644 --- a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs @@ -1,6 +1,5 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Querying; using System; -- cgit v1.2.3 From 75018055b212a92a4cae6e04fffc79eca54292f7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 7 Mar 2015 17:43:53 -0500 Subject: add methods to media source manager --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 64 +++------ MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 2 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 11 +- MediaBrowser.Api/Playback/Hls/MpegDashService.cs | 3 +- MediaBrowser.Api/Playback/Hls/VideoHlsService.cs | 3 +- MediaBrowser.Api/Playback/MediaInfoService.cs | 58 ++++---- .../Playback/Progressive/AudioService.cs | 2 +- .../Progressive/BaseProgressiveStreamingService.cs | 4 +- .../Playback/Progressive/VideoService.cs | 3 +- MediaBrowser.Api/Subtitles/SubtitleService.cs | 7 +- .../Entities/IHasMediaSources.cs | 54 +------- MediaBrowser.Controller/Entities/Video.cs | 3 +- .../Library/IMediaSourceManager.cs | 47 ++++++- .../Library/IMediaSourceProvider.cs | 19 +++ .../MediaBrowser.Controller.csproj | 1 + .../ContentDirectory/ControlHandler.cs | 5 +- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 8 +- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 11 +- MediaBrowser.Dlna/PlayTo/PlayToController.cs | 31 +++-- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 13 +- .../Encoder/EncodingJobFactory.cs | 50 ++----- .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + MediaBrowser.Model/Sync/SyncDialogOptions.cs | 21 ++- MediaBrowser.Model/Sync/SyncQualityOption.cs | 17 +++ .../Dto/DtoService.cs | 6 +- .../Library/MediaSourceManager.cs | 150 ++++++++++++++++++++- .../MediaBrowser.Server.Implementations.csproj | 1 + .../Sync/SyncConvertScheduledTask.cs | 6 +- .../Sync/SyncJobProcessor.cs | 8 +- .../Sync/SyncManager.cs | 10 +- .../Sync/SyncedMediaSourceProvider.cs | 17 +++ .../ApplicationHost.cs | 12 +- 34 files changed, 390 insertions(+), 264 deletions(-) create mode 100644 MediaBrowser.Controller/Library/IMediaSourceProvider.cs create mode 100644 MediaBrowser.Model/Sync/SyncQualityOption.cs create mode 100644 MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index a40e0f8c3f..2c4d1fd34f 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/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.Controller.Channels; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; @@ -15,6 +14,7 @@ using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.MediaInfo; using System; @@ -69,19 +69,19 @@ namespace MediaBrowser.Api.Playback protected ILiveTvManager LiveTvManager { get; private set; } protected IDlnaManager DlnaManager { get; private set; } protected IDeviceManager DeviceManager { get; private set; } - protected IChannelManager ChannelManager { get; private set; } protected ISubtitleEncoder SubtitleEncoder { get; private set; } protected IProcessManager ProcessManager { get; private set; } + protected IMediaSourceManager MediaSourceManager { get; private set; } /// /// Initializes a new instance of the class. /// - 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; DeviceManager = deviceManager; SubtitleEncoder = subtitleEncoder; - ChannelManager = channelManager; DlnaManager = dlnaManager; LiveTvManager = liveTvManager; FileSystem = fileSystem; @@ -1657,8 +1657,8 @@ namespace MediaBrowser.Api.Playback var source = string.IsNullOrEmpty(request.MediaSourceId) ? recording.GetMediaSources(false).First() - : recording.GetMediaSources(false).First(i => string.Equals(i.Id, request.MediaSourceId)); - + : MediaSourceManager.GetStaticMediaSource(recording, request.MediaSourceId, false); + mediaStreams = source.MediaStreams; // 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 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 { - var hasMediaSources = (IHasMediaSources)item; + var mediaSources = await MediaSourceManager.GetPlayackMediaSources(request.Id, cancellationToken).ConfigureAwait(false); + 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; @@ -1724,6 +1712,8 @@ namespace MediaBrowser.Api.Playback state.InputFileSize = mediaSource.Size; state.InputBitrate = mediaSource.Bitrate; state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate; + state.RunTimeTicks = mediaSource.RunTimeTicks; + state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders; var video = item as Video; @@ -1746,7 +1736,6 @@ namespace MediaBrowser.Api.Playback } } - state.RunTimeTicks = mediaSource.RunTimeTicks; } var videoRequest = request as VideoStreamRequest; @@ -1869,29 +1858,6 @@ namespace MediaBrowser.Api.Playback state.AllMediaStreams = mediaStreams; } - private async Task 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) { if (videoStream.IsInterlaced) diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index fdfa6e6d76..ecd91b4cb1 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Api.Playback.Hls /// 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) { } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 4f4f5f1cb7..13e2fa086b 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/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.Controller.Channels; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Diagnostics; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; @@ -12,6 +10,7 @@ using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using ServiceStack; using System; @@ -64,7 +63,7 @@ namespace MediaBrowser.Api.Playback.Hls 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; } diff --git a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs index 05909402c9..c8ccdf0715 100644 --- a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs +++ b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Diagnostics; @@ -52,7 +51,7 @@ namespace MediaBrowser.Api.Playback.Hls 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; } diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs index d27296bfdb..b987c8f859 100644 --- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Diagnostics; @@ -58,7 +57,7 @@ namespace MediaBrowser.Api.Playback.Hls /// 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) { } diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 330a8777c7..96958487b3 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/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.Model.Dto; using MediaBrowser.Model.MediaInfo; using ServiceStack; -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; 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")] public class GetLiveMediaInfo : IReturn { @@ -23,46 +18,39 @@ namespace MediaBrowser.Api.Playback public string UserId { get; set; } } + [Route("/Items/{Id}/PlaybackInfo", "GET", Summary = "Gets live playback media info for an item")] + public class GetPlaybackInfo : IReturn + { + [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] 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 Get(GetLiveMediaInfo request) + public async Task Get(GetPlaybackInfo request) { - var item = _libraryManager.GetItemById(request.Id); - IEnumerable 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 Get(GetLiveMediaInfo request) + { + var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.Id, request.UserId, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(new LiveMediaInfoResult { diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs index 08ec13f4ff..d9252ca402 100644 --- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs +++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Api.Playback.Progressive /// 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) { } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 0af4587b67..d7f7b423bc 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Diagnostics; @@ -16,7 +15,6 @@ using ServiceStack.Web; using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -30,7 +28,7 @@ namespace MediaBrowser.Api.Playback.Progressive protected readonly IImageProcessor ImageProcessor; protected readonly IHttpClient HttpClient; - protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, 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; HttpClient = httpClient; diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index 9b161085a9..0aed9d45c4 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Diagnostics; @@ -64,7 +63,7 @@ namespace MediaBrowser.Api.Playback.Progressive /// 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) { } diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index 32e6ba076d..c7997be5b2 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -124,20 +124,21 @@ namespace MediaBrowser.Api.Subtitles private readonly ILibraryManager _libraryManager; private readonly ISubtitleManager _subtitleManager; 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; _subtitleManager = subtitleManager; _subtitleEncoder = subtitleEncoder; + _mediaSourceManager = mediaSourceManager; } public object Get(GetSubtitlePlaylist request) { 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(); diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs index 98d2682989..17a1478068 100644 --- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs +++ b/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.Collections.Generic; -using System.Linq; namespace MediaBrowser.Controller.Entities { @@ -22,53 +19,4 @@ namespace MediaBrowser.Controller.Entities /// Task{IEnumerable{MediaSourceInfo}}. IEnumerable GetMediaSources(bool enablePathSubstitution); } - - public static class HasMediaSourceExtensions - { - public static IEnumerable 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 { } - : new List { 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; - } - } } diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index a0c3a6cf98..dd774c1edf 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -460,7 +460,7 @@ namespace MediaBrowser.Controller.Entities return result.OrderBy(i => { - if (item.VideoType == VideoType.VideoFile) + if (i.VideoType == VideoType.VideoFile) { return 0; } @@ -556,7 +556,6 @@ namespace MediaBrowser.Controller.Entities return info; } - private static string GetMediaSourceName(Video video, List mediaStreams) { var terms = new List(); diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs index 5d79f613db..58bcf6cff2 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs +++ b/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 System; using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Controller.Library { public interface IMediaSourceManager { + /// + /// Adds the parts. + /// + /// The providers. + void AddParts(IEnumerable providers); + /// /// Gets the media streams. /// @@ -25,5 +35,40 @@ namespace MediaBrowser.Controller.Library /// The query. /// IEnumerable<MediaStream>. IEnumerable GetMediaStreams(MediaStreamQuery query); + + /// + /// Gets the playack media sources. + /// + /// The identifier. + /// The user identifier. + /// The cancellation token. + /// IEnumerable<MediaSourceInfo>. + Task> GetPlayackMediaSources(string id, string userId, CancellationToken cancellationToken); + + /// + /// Gets the playack media sources. + /// + /// The identifier. + /// The cancellation token. + /// Task<IEnumerable<MediaSourceInfo>>. + Task> GetPlayackMediaSources(string id, CancellationToken cancellationToken); + + /// + /// Gets the static media sources. + /// + /// The item. + /// if set to true [enable path substitution]. + /// The user. + /// IEnumerable<MediaSourceInfo>. + IEnumerable GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user); + + /// + /// Gets the static media source. + /// + /// The item. + /// The media source identifier. + /// if set to true [enable path substitution]. + /// MediaSourceInfo. + MediaSourceInfo GetStaticMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution); } } diff --git a/MediaBrowser.Controller/Library/IMediaSourceProvider.cs b/MediaBrowser.Controller/Library/IMediaSourceProvider.cs new file mode 100644 index 0000000000..461285d6cc --- /dev/null +++ b/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 + { + /// + /// Gets the media sources. + /// + /// The item. + /// The cancellation token. + /// Task<IEnumerable<MediaSourceInfo>>. + Task> GetMediaSources(IHasMediaSources item, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 36809c5d38..72b9bfe9e6 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -172,6 +172,7 @@ + diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 25e4c882a4..17a9e7dc0a 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -32,7 +32,7 @@ namespace MediaBrowser.Dlna.ContentDirectory private readonly ILibraryManager _libraryManager; private readonly IChannelManager _channelManager; private readonly IUserDataManager _userDataManager; - private IServerConfigurationManager _config; + private readonly IServerConfigurationManager _config; private readonly User _user; 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 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) : base(config, logger) @@ -58,7 +59,7 @@ namespace MediaBrowser.Dlna.ContentDirectory _profile = profile; _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> GetResult(string methodName, Headers methodParams) diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs index b2eedad7c6..469b60a9c2 100644 --- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs +++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs @@ -37,14 +37,16 @@ namespace MediaBrowser.Dlna.Didl private readonly User _user; private readonly IUserDataManager _userDataManager; 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; _imageProcessor = imageProcessor; _serverAddress = serverAddress; _userDataManager = userDataManager; _localization = localization; + _mediaSourceManager = mediaSourceManager; _accessToken = accessToken; _user = user; } @@ -122,7 +124,7 @@ namespace MediaBrowser.Dlna.Didl { 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 { @@ -342,7 +344,7 @@ namespace MediaBrowser.Dlna.Didl 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 { diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index f3e8c108bc..4a8baf0feb 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -7,7 +7,6 @@ using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; using MediaBrowser.Dlna.Channels; @@ -30,13 +29,13 @@ namespace MediaBrowser.Dlna.Main private PlayToManager _manager; private readonly ISessionManager _sessionManager; private readonly IHttpClient _httpClient; - private readonly IItemRepository _itemRepo; private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; private readonly IDlnaManager _dlnaManager; private readonly IImageProcessor _imageProcessor; private readonly IUserDataManager _userDataManager; private readonly ILocalizationManager _localization; + private readonly IMediaSourceManager _mediaSourceManager; private SsdpHandler _ssdpHandler; private DeviceDiscovery _deviceDiscovery; @@ -44,20 +43,20 @@ namespace MediaBrowser.Dlna.Main private readonly List _registeredServerIds = new List(); 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; _appHost = appHost; _network = network; _sessionManager = sessionManager; _httpClient = httpClient; - _itemRepo = itemRepo; _libraryManager = libraryManager; _userManager = userManager; _dlnaManager = dlnaManager; _imageProcessor = imageProcessor; _userDataManager = userDataManager; _localization = localization; + _mediaSourceManager = mediaSourceManager; _logger = logManager.GetLogger("Dlna"); } @@ -217,7 +216,6 @@ namespace MediaBrowser.Dlna.Main { _manager = new PlayToManager(_logger, _sessionManager, - _itemRepo, _libraryManager, _userManager, _dlnaManager, @@ -227,7 +225,8 @@ namespace MediaBrowser.Dlna.Main _httpClient, _config, _userDataManager, - _localization); + _localization, + _mediaSourceManager); _manager.Start(); } diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index 5746231618..f53318069c 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Session; using MediaBrowser.Dlna.Didl; using MediaBrowser.Dlna.Ssdp; @@ -27,7 +26,6 @@ namespace MediaBrowser.Dlna.PlayTo private Device _device; private readonly SessionInfo _session; private readonly ISessionManager _sessionManager; - private readonly IItemRepository _itemRepository; private readonly ILibraryManager _libraryManager; private readonly ILogger _logger; private readonly IDlnaManager _dlnaManager; @@ -35,6 +33,7 @@ namespace MediaBrowser.Dlna.PlayTo private readonly IImageProcessor _imageProcessor; private readonly IUserDataManager _userDataManager; private readonly ILocalizationManager _localization; + private readonly IMediaSourceManager _mediaSourceManager; private readonly DeviceDiscovery _deviceDiscovery; private readonly string _serverAddress; @@ -55,10 +54,9 @@ namespace MediaBrowser.Dlna.PlayTo 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; - _itemRepository = itemRepository; _sessionManager = sessionManager; _libraryManager = libraryManager; _dlnaManager = dlnaManager; @@ -68,6 +66,7 @@ namespace MediaBrowser.Dlna.PlayTo _deviceDiscovery = deviceDiscovery; _userDataManager = userDataManager; _localization = localization; + _mediaSourceManager = mediaSourceManager; _accessToken = accessToken; _logger = logger; } @@ -140,7 +139,7 @@ namespace MediaBrowser.Dlna.PlayTo { try { - var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager); + var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager, _mediaSourceManager); if (streamInfo.Item != null) { var progress = GetProgressInfo(e.OldMediaInfo, streamInfo); @@ -150,7 +149,7 @@ namespace MediaBrowser.Dlna.PlayTo 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; var newItemProgress = GetProgressInfo(e.NewMediaInfo, streamInfo); @@ -167,7 +166,7 @@ namespace MediaBrowser.Dlna.PlayTo { try { - var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager); + var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager); if (streamInfo.Item == null) return; @@ -229,7 +228,7 @@ namespace MediaBrowser.Dlna.PlayTo { try { - var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager); + var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager); if (info.Item != null) { @@ -248,7 +247,7 @@ namespace MediaBrowser.Dlna.PlayTo { try { - var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager); + var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager); if (info.Item != null) { @@ -376,7 +375,7 @@ namespace MediaBrowser.Dlna.PlayTo if (media != null) { - var info = StreamParams.ParseFromUrl(media.Url, _libraryManager); + var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager); if (info.Item != null && !info.IsDirectStream) { @@ -472,7 +471,7 @@ namespace MediaBrowser.Dlna.PlayTo var hasMediaSources = item as IHasMediaSources; 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(); 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); - 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); playlistItem.Didl = itemXml; @@ -737,7 +736,7 @@ namespace MediaBrowser.Dlna.PlayTo if (media != null) { - var info = StreamParams.ParseFromUrl(media.Url, _libraryManager); + var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager); if (info.Item != null) { @@ -763,7 +762,7 @@ namespace MediaBrowser.Dlna.PlayTo if (media != null) { - var info = StreamParams.ParseFromUrl(media.Url, _libraryManager); + var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager); if (info.Item != null) { @@ -824,7 +823,7 @@ namespace MediaBrowser.Dlna.PlayTo return null; } - public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManager) + public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager) { var request = new StreamParams { @@ -892,7 +891,7 @@ namespace MediaBrowser.Dlna.PlayTo request.MediaSource = hasMediaSources == null ? null : - hasMediaSources.GetMediaSources(false).FirstOrDefault(i => string.Equals(i.Id, request.MediaSourceId, StringComparison.OrdinalIgnoreCase)); + mediaSourceManager.GetStaticMediaSource(hasMediaSources, request.MediaSourceId, false); diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index 9a9a976d35..ba6d656ddc 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -5,7 +5,6 @@ using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Session; using MediaBrowser.Dlna.Ssdp; using MediaBrowser.Model.Logging; @@ -22,7 +21,6 @@ namespace MediaBrowser.Dlna.PlayTo private readonly ILogger _logger; private readonly ISessionManager _sessionManager; - private readonly IItemRepository _itemRepository; private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; private readonly IDlnaManager _dlnaManager; @@ -34,12 +32,12 @@ namespace MediaBrowser.Dlna.PlayTo private readonly ILocalizationManager _localization; 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; _sessionManager = sessionManager; - _itemRepository = itemRepository; _libraryManager = libraryManager; _userManager = userManager; _dlnaManager = dlnaManager; @@ -50,6 +48,7 @@ namespace MediaBrowser.Dlna.PlayTo _config = config; _userDataManager = userDataManager; _localization = localization; + _mediaSourceManager = mediaSourceManager; } public void Start() @@ -102,7 +101,6 @@ namespace MediaBrowser.Dlna.PlayTo sessionInfo.SessionController = controller = new PlayToController(sessionInfo, _sessionManager, - _itemRepository, _libraryManager, _logger, _dlnaManager, @@ -112,7 +110,8 @@ namespace MediaBrowser.Dlna.PlayTo accessToken, _deviceDiscovery, _userDataManager, - _localization); + _localization, + _mediaSourceManager); controller.Init(device); diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index 925d17bc68..3488551dc3 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -23,6 +23,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly ILiveTvManager _liveTvManager; private readonly ILibraryManager _libraryManager; private readonly IChannelManager _channelManager; + private IMediaSourceManager _mediaSourceManager; protected static readonly CultureInfo UsCulture = new CultureInfo("en-US"); @@ -71,10 +72,10 @@ namespace MediaBrowser.MediaEncoding.Encoder var path = recording.RecordingInfo.Path; var mediaUrl = recording.RecordingInfo.Url; - + var source = string.IsNullOrEmpty(request.MediaSourceId) ? recording.GetMediaSources(false).First() - : recording.GetMediaSources(false).First(i => string.Equals(i.Id, request.MediaSourceId)); + : _mediaSourceManager.GetStaticMediaSource(recording, request.MediaSourceId, false); mediaStreams = source.MediaStreams; @@ -113,25 +114,13 @@ namespace MediaBrowser.MediaEncoding.Encoder // Just to prevent this from being null and causing other methods to fail 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 { - var hasMediaSources = (IHasMediaSources)item; + var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.ItemId, cancellationToken).ConfigureAwait(false); + 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; @@ -141,6 +130,8 @@ namespace MediaBrowser.MediaEncoding.Encoder state.InputFileSize = mediaSource.Size; state.InputBitrate = mediaSource.Bitrate; state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate; + state.RunTimeTicks = mediaSource.RunTimeTicks; + state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders; var video = item as Video; @@ -424,29 +415,6 @@ namespace MediaBrowser.MediaEncoding.Encoder return bitrate; } - private async Task 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) { var bitrate = state.OutputVideoBitrate; diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 2f5e8a5d79..0238cbf6e9 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -1124,6 +1124,9 @@ Sync\SyncQuality.cs + + Sync\SyncQualityOption.cs + Sync\SyncTarget.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index f15e752ffb..038ec14e3d 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -1083,6 +1083,9 @@ Sync\SyncQuality.cs + + Sync\SyncQualityOption.cs + Sync\SyncTarget.cs diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 0bfd0d3fdd..86b45e1238 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -395,6 +395,7 @@ + diff --git a/MediaBrowser.Model/Sync/SyncDialogOptions.cs b/MediaBrowser.Model/Sync/SyncDialogOptions.cs index 5c84fb81f8..751fbbb138 100644 --- a/MediaBrowser.Model/Sync/SyncDialogOptions.cs +++ b/MediaBrowser.Model/Sync/SyncDialogOptions.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using MediaBrowser.Model.Dto; namespace MediaBrowser.Model.Sync { @@ -19,33 +18,33 @@ namespace MediaBrowser.Model.Sync /// Gets or sets the quality options. /// /// The quality options. - public List QualityOptions { get; set; } + public List QualityOptions { get; set; } public SyncDialogOptions() { Targets = new List(); Options = new List(); - QualityOptions = new List + QualityOptions = new List { - new NameValuePair + new SyncQualityOption { Name = SyncQuality.Original.ToString(), - Value = SyncQuality.Original.ToString() + Id = SyncQuality.Original.ToString() }, - new NameValuePair + new SyncQualityOption { Name = SyncQuality.High.ToString(), - Value = SyncQuality.High.ToString() + Id = SyncQuality.High.ToString() }, - new NameValuePair + new SyncQualityOption { Name = SyncQuality.Medium.ToString(), - Value = SyncQuality.Medium.ToString() + Id = SyncQuality.Medium.ToString() }, - new NameValuePair + new SyncQualityOption { Name = SyncQuality.Low.ToString(), - Value = SyncQuality.Low.ToString() + Id = SyncQuality.Low.ToString() } }; } diff --git a/MediaBrowser.Model/Sync/SyncQualityOption.cs b/MediaBrowser.Model/Sync/SyncQualityOption.cs new file mode 100644 index 0000000000..6dc42fa481 --- /dev/null +++ b/MediaBrowser.Model/Sync/SyncQualityOption.cs @@ -0,0 +1,17 @@ + +namespace MediaBrowser.Model.Sync +{ + public class SyncQualityOption + { + /// + /// Gets or sets the name. + /// + /// The name. + public string Name { get; set; } + /// + /// Gets or sets the identifier. + /// + /// The identifier. + public string Id { get; set; } + } +} diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 48408b4ea2..f9b7470b2c 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -45,8 +45,9 @@ namespace MediaBrowser.Server.Implementations.Dto private readonly ISyncManager _syncManager; private readonly IApplicationHost _appHost; private readonly Func _deviceManager; + private readonly Func _mediaSourceManager; - public DtoService(ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func channelManagerFactory, ISyncManager syncManager, IApplicationHost appHost, Func deviceManager) + public DtoService(ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func channelManagerFactory, ISyncManager syncManager, IApplicationHost appHost, Func deviceManager, Func mediaSourceManager) { _logger = logger; _libraryManager = libraryManager; @@ -60,6 +61,7 @@ namespace MediaBrowser.Server.Implementations.Dto _syncManager = syncManager; _appHost = appHost; _deviceManager = deviceManager; + _mediaSourceManager = mediaSourceManager; } /// @@ -257,7 +259,7 @@ namespace MediaBrowser.Server.Implementations.Dto } else { - dto.MediaSources = hasMediaSources.GetMediaSources(true, user).ToList(); + dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true, user).ToList(); } } } diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 6ce989b029..97b50a48b3 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/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.Model.Dto; using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; using System.Linq; +using System.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Library { public class MediaSourceManager : IMediaSourceManager { 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; + _userManager = userManager; + _libraryManager = libraryManager; + _channelManager = channelManager; + } + + public void AddParts(IEnumerable providers) + { + _providers = providers.ToArray(); } public IEnumerable GetMediaStreams(MediaStreamQuery query) @@ -102,5 +121,132 @@ namespace MediaBrowser.Server.Implementations.Library return list; } + + public async Task> GetPlayackMediaSources(string id, string userId, CancellationToken cancellationToken) + { + var item = _libraryManager.GetItemById(id); + IEnumerable 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> GetPlayackMediaSources(string id, CancellationToken cancellationToken) + { + return GetPlayackMediaSources(id, null, cancellationToken); + } + + public IEnumerable 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 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 { } + : new List { 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 SortMediaSources(IEnumerable 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)); + } } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index dd68ef9da2..607ba3c41a 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -309,6 +309,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs index 70aabf345b..913d50e9d7 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs @@ -25,8 +25,9 @@ namespace MediaBrowser.Server.Implementations.Sync private readonly ISubtitleEncoder _subtitleEncoder; private readonly IConfigurationManager _config; 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; _syncRepo = syncRepo; @@ -38,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Sync _subtitleEncoder = subtitleEncoder; _config = config; _fileSystem = fileSystem; + _mediaSourceManager = mediaSourceManager; } public string Name @@ -60,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.Sync public Task Execute(CancellationToken cancellationToken, IProgress 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); } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 72dc1bdb64..b2b43ea982 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -38,8 +38,9 @@ namespace MediaBrowser.Server.Implementations.Sync private readonly ISubtitleEncoder _subtitleEncoder; private readonly IConfigurationManager _config; 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; _syncRepo = syncRepo; @@ -51,6 +52,7 @@ namespace MediaBrowser.Server.Implementations.Sync _subtitleEncoder = subtitleEncoder; _config = config; _fileSystem = fileSystem; + _mediaSourceManager = mediaSourceManager; } public async Task EnsureJobItems(SyncJob job) @@ -491,7 +493,7 @@ namespace MediaBrowser.Server.Implementations.Sync options.Context = EncodingContext.Static; options.Profile = profile; 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 mediaSource = streamInfo.MediaSource; @@ -682,7 +684,7 @@ namespace MediaBrowser.Server.Implementations.Sync options.Context = EncodingContext.Static; options.Profile = profile; 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 mediaSource = streamInfo.MediaSource; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 5644d561a2..d0d65d4379 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -47,7 +47,8 @@ namespace MediaBrowser.Server.Implementations.Sync private readonly IFileSystem _fileSystem; private readonly Func _subtitleEncoder; private readonly IConfigurationManager _config; - private IUserDataManager _userDataManager; + private readonly IUserDataManager _userDataManager; + private readonly Func _mediaSourceManager; private ISyncProvider[] _providers = { }; @@ -57,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Sync public event EventHandler> SyncJobItemUpdated; public event EventHandler> SyncJobItemCreated; - public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func mediaEncoder, IFileSystem fileSystem, Func subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager) + public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func mediaEncoder, IFileSystem fileSystem, Func subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func mediaSourceManager) { _libraryManager = libraryManager; _repo = repo; @@ -72,6 +73,7 @@ namespace MediaBrowser.Server.Implementations.Sync _subtitleEncoder = subtitleEncoder; _config = config; _userDataManager = userDataManager; + _mediaSourceManager = mediaSourceManager; } public void AddParts(IEnumerable providers) @@ -610,7 +612,7 @@ namespace MediaBrowser.Server.Implementations.Sync 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) @@ -677,7 +679,7 @@ namespace MediaBrowser.Server.Implementations.Sync dtoOptions.Fields.Remove(ItemFields.SyncInfo); syncedItem.Item = _dtoService().GetBaseItemDto(libraryItem, dtoOptions); - + var mediaSource = syncedItem.Item.MediaSources .FirstOrDefault(i => string.Equals(i.Id, jobItem.MediaSourceId)); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs new file mode 100644 index 0000000000..19383b3167 --- /dev/null +++ b/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> GetMediaSources(IHasMediaSources item, CancellationToken cancellationToken) + { + return new List(); + } + } +} diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 63d30a6069..9446a6eda6 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -447,10 +447,10 @@ namespace MediaBrowser.Server.Startup.Common TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager); 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); - 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); 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")); 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); RegisterSingleInstance(SessionManager); @@ -479,6 +476,9 @@ namespace MediaBrowser.Server.Startup.Common ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, Logger, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient); RegisterSingleInstance(ChannelManager); + MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, ChannelManager); + RegisterSingleInstance(MediaSourceManager); + var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger); RegisterSingleInstance(appThemeManager); @@ -754,6 +754,8 @@ namespace MediaBrowser.Server.Startup.Common ChannelManager.AddParts(GetExports(), GetExports()); + MediaSourceManager.AddParts(GetExports()); + NotificationManager.AddParts(GetExports(), GetExports()); SyncManager.AddParts(GetExports()); } -- cgit v1.2.3 From 43f0a1bbfe36e76cee773a6ba774b2b0dd7c3740 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 7 Mar 2015 18:39:24 -0500 Subject: get dynamic media sources --- MediaBrowser.Model/Sync/SyncJobItemQuery.cs | 5 +++ .../Library/MediaSourceManager.cs | 38 +++++++++++++++++++--- .../Sync/SyncRepository.cs | 5 +++ .../Sync/SyncedMediaSourceProvider.cs | 21 ++++++++++++ .../ApplicationHost.cs | 10 +++--- 5 files changed, 70 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Model/Sync/SyncJobItemQuery.cs b/MediaBrowser.Model/Sync/SyncJobItemQuery.cs index d211382049..97f26b3243 100644 --- a/MediaBrowser.Model/Sync/SyncJobItemQuery.cs +++ b/MediaBrowser.Model/Sync/SyncJobItemQuery.cs @@ -20,6 +20,11 @@ namespace MediaBrowser.Model.Sync /// The job identifier. public string JobId { get; set; } /// + /// Gets or sets the item identifier. + /// + /// The item identifier. + public string ItemId { get; set; } + /// /// Gets or sets the target identifier. /// /// The target identifier. diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 97b50a48b3..93fb101a9e 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Linq; @@ -21,13 +22,15 @@ namespace MediaBrowser.Server.Implementations.Library private readonly IChannelManager _channelManager; private IMediaSourceProvider[] _providers; + private readonly ILogger _logger; - public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, IChannelManager channelManager) + public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, IChannelManager channelManager, ILogger logger) { _itemRepo = itemRepo; _userManager = userManager; _libraryManager = libraryManager; _channelManager = channelManager; + _logger = logger; } public void AddParts(IEnumerable providers) @@ -127,6 +130,7 @@ namespace MediaBrowser.Server.Implementations.Library var item = _libraryManager.GetItemById(id); IEnumerable mediaSources; + var hasMediaSources = (IHasMediaSources)item; var channelItem = item as IChannelMediaItem; if (channelItem != null) @@ -136,8 +140,6 @@ namespace MediaBrowser.Server.Implementations.Library } else { - var hasMediaSources = (IHasMediaSources)item; - if (string.IsNullOrWhiteSpace(userId)) { mediaSources = hasMediaSources.GetMediaSources(true); @@ -149,7 +151,35 @@ namespace MediaBrowser.Server.Implementations.Library } } - return mediaSources; + var dynamicMediaSources = await GetDynamicMediaSources(hasMediaSources, cancellationToken).ConfigureAwait(false); + + var list = new List(); + + list.AddRange(mediaSources); + list.AddRange(dynamicMediaSources); + + return SortMediaSources(list); + } + + private async Task> GetDynamicMediaSources(IHasMediaSources item, CancellationToken cancellationToken) + { + var tasks = _providers.Select(i => GetDynamicMediaSources(item, i, cancellationToken)); + var results = await Task.WhenAll(tasks).ConfigureAwait(false); + + return results.SelectMany(i => i.ToList()); + } + + private async Task> GetDynamicMediaSources(IHasMediaSources item, IMediaSourceProvider provider, CancellationToken cancellationToken) + { + try + { + return await provider.GetMediaSources(item, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting media sources", ex); + return new List(); + } } public Task> GetPlayackMediaSources(string id, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 05d804cbb6..b0f48e7f54 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -539,6 +539,11 @@ namespace MediaBrowser.Server.Implementations.Sync whereClauses.Add("JobId=@JobId"); cmd.Parameters.Add(cmd, "@JobId", DbType.String).Value = query.JobId; } + if (!string.IsNullOrWhiteSpace(query.ItemId)) + { + whereClauses.Add("ItemId=@ItemId"); + cmd.Parameters.Add(cmd, "@ItemId", DbType.String).Value = query.ItemId; + } if (!string.IsNullOrWhiteSpace(query.TargetId)) { whereClauses.Add("TargetId=@TargetId"); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs index 19383b3167..9194ff1c95 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs @@ -1,7 +1,10 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Sync; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Sync; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -9,8 +12,26 @@ namespace MediaBrowser.Server.Implementations.Sync { public class SyncedMediaSourceProvider : IMediaSourceProvider { + private readonly ISyncManager _syncManager; + + public SyncedMediaSourceProvider(ISyncManager syncManager) + { + _syncManager = syncManager; + } + public async Task> GetMediaSources(IHasMediaSources item, CancellationToken cancellationToken) { + var jobItemResult = _syncManager.GetJobItems(new SyncJobItemQuery + { + AddMetadata = false, + Statuses = new List { SyncJobItemStatus.Synced }, + ItemId = item.Id.ToString("N") + }); + + var jobItems = jobItemResult + .Items + .Where(i => true); + return new List(); } } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 9446a6eda6..4eb510f189 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -450,7 +450,7 @@ namespace MediaBrowser.Server.Startup.Common SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager, () => MediaSourceManager); RegisterSingleInstance(SyncManager); - DtoService = new DtoService(Logger, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager); + DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager); RegisterSingleInstance(DtoService); var encryptionManager = new EncryptionManager(); @@ -459,10 +459,10 @@ namespace MediaBrowser.Server.Startup.Common ConnectManager = new ConnectManager(LogManager.GetLogger("Connect"), ApplicationPaths, JsonSerializer, encryptionManager, HttpClient, this, ServerConfigurationManager, UserManager, ProviderManager); RegisterSingleInstance(ConnectManager); - DeviceManager = new DeviceManager(new DeviceRepository(ApplicationPaths, JsonSerializer, Logger, FileSystemManager), UserManager, FileSystemManager, LibraryMonitor, ConfigurationManager, LogManager.GetLogger("DeviceManager")); + DeviceManager = new DeviceManager(new DeviceRepository(ApplicationPaths, JsonSerializer, LogManager.GetLogger("DeviceManager"), FileSystemManager), UserManager, FileSystemManager, LibraryMonitor, ConfigurationManager, LogManager.GetLogger("DeviceManager")); RegisterSingleInstance(DeviceManager); - SessionManager = new SessionManager(UserDataManager, Logger, UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager); + SessionManager = new SessionManager(UserDataManager, LogManager.GetLogger("SessionManager"), UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager); RegisterSingleInstance(SessionManager); var newsService = new Implementations.News.NewsService(ApplicationPaths, JsonSerializer); @@ -473,10 +473,10 @@ namespace MediaBrowser.Server.Startup.Common progress.Report(15); - ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, Logger, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient); + ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LogManager.GetLogger("ChannelManager"), ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient); RegisterSingleInstance(ChannelManager); - MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, ChannelManager); + MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, ChannelManager, LogManager.GetLogger("MediaSourceManager")); RegisterSingleInstance(MediaSourceManager); var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger); -- cgit v1.2.3 From af0d1cada0023872535e15227c192504f8692a6d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 8 Mar 2015 12:25:46 -0400 Subject: aadd sync services tab --- .../Library/MediaSourceManager.cs | 8 ++++++-- .../Localization/JavaScript/javascript.json | 10 ++++++++++ .../Localization/Server/server.json | 3 +++ MediaBrowser.WebDashboard/Api/PackageCreator.cs | 1 + MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 4 ++++ 5 files changed, 24 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 93fb101a9e..746f978ea0 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -156,7 +156,12 @@ namespace MediaBrowser.Server.Implementations.Library var list = new List(); list.AddRange(mediaSources); - list.AddRange(dynamicMediaSources); + + foreach (var source in dynamicMediaSources) + { + source.SupportsTranscoding = false; + list.Add(source); + } return SortMediaSources(list); } @@ -273,7 +278,6 @@ namespace MediaBrowser.Server.Implementations.Library .ToList(); } - public MediaSourceInfo GetStaticMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution) { return GetStaticMediaSources(item, enablePathSubstitution).FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)); diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 484578e31b..fd5ff94242 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -38,6 +38,16 @@ "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "ValueTimeLimitSingleHour": "Time limit: 1 hour", "ValueTimeLimitMultiHour": "Time limit: {0} hours", + "PluginCategoryGeneral": "General", + "PluginCategoryContentProvider": "Content Providers", + "PluginCategoryScreenSaver": "Screen Savers", + "PluginCategoryTheme": "Themes", + "PluginCategorySync": "Sync", + "PluginCategorySocialIntegration": "Social Networks", + "PluginCategoryNotifications": "Notifications", + "PluginCategoryMetadata": "Metadata", + "PluginCategoryLiveTV": "Live TV", + "PluginCategoryChannel": "Channels", "HeaderSearch": "Search", "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index b4ab8ef998..711c141b88 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -61,6 +61,9 @@ "HeaderEasyPinCode": "Easy Pin Code", "HeaderGrownupsOnly": "Grown-ups Only!", "DividerOr": "-- or --", + "HeaderInstalledServices": "Installed Services", + "HeaderAvailableServices": "Available Services", + "MessageNoServicesInstalled": "No services are currently installed.", "HeaderToAccessPleaseEnterEasyPinCode": "To access, please enter your easy pin code", "KidsModeAdultInstruction": "Click the lock icon in the bottom right to configure or leave kids mode. Your pin code will be required.", "ButtonConfigurePinCode": "Configure pin code", diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 8328cf8ab4..2807b631c1 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -366,6 +366,7 @@ namespace MediaBrowser.WebDashboard.Api "backdrops.js", "sync.js", "syncjob.js", + "syncservices.js", "playlistmanager.js", "mediaplayer.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index fa6413b8ba..cc62af5c69 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -144,6 +144,7 @@ PreserveNewest + PreserveNewest @@ -165,6 +166,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 639090ecf30581f3aedcc20ad32bb2707d721ca5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 8 Mar 2015 12:50:14 -0400 Subject: fixes #910: Feature Request: Support for additional Image Formats --- MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs index 02960ea7ea..d1cf7d6682 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -30,7 +30,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers return null; } - protected static string[] ImageExtensions = { ".tiff", ".jpeg", ".jpg", ".png", ".aiff" }; + // Some common file name extensions for RAW picture files include: .cr2, .crw, .dng, .nef, .orf, .rw2, .pef, .arw, .sr2, .srf, and .tif. + protected static string[] ImageExtensions = { ".tiff", ".jpeg", ".jpg", ".png", ".aiff", ".cr2", ".crw", "dng", ".nef", ".orf", ".pef", ".arw" }; private static readonly string[] IgnoreFiles = { -- cgit v1.2.3 From 5d9ab74e75a88b0d3310ba518675a767bc6730b6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 8 Mar 2015 13:34:02 -0400 Subject: set context with sync services --- MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs | 2 +- .../Localization/JavaScript/javascript.json | 2 ++ MediaBrowser.Server.Implementations/Localization/Server/server.json | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs index d1cf7d6682..b714e968b5 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -31,7 +31,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers } // Some common file name extensions for RAW picture files include: .cr2, .crw, .dng, .nef, .orf, .rw2, .pef, .arw, .sr2, .srf, and .tif. - protected static string[] ImageExtensions = { ".tiff", ".jpeg", ".jpg", ".png", ".aiff", ".cr2", ".crw", "dng", ".nef", ".orf", ".pef", ".arw" }; + protected static string[] ImageExtensions = { ".tiff", ".jpeg", ".jpg", ".png", ".aiff", ".cr2", ".crw", ".dng", ".nef", ".orf", ".pef", ".arw", ".webp" }; private static readonly string[] IgnoreFiles = { diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index fd5ff94242..ed25d75eba 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -87,6 +87,8 @@ "HeaderWelcomeToMediaBrowserWebClient": "Welcome to the Media Browser Web Client", "ButtonTakeTheTour": "Take the tour", "HeaderWelcomeBack": "Welcome back!", + "TitleSync": "Sync", + "TitlePlugins": "Plugins", "ButtonTakeTheTourToSeeWhatsNew": "Take the tour to see what's new", "MessageNoSyncJobsFound": "No sync jobs found. Create sync jobs using the Sync buttons found throughout the web interface.", "HeaderLibraryAccess": "Library Access", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 711c141b88..d6fe5bb974 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -226,7 +226,7 @@ "ScheduledTasksTitle": "Scheduled Tasks", "TabMyPlugins": "My Plugins", "TabCatalog": "Catalog", - "PluginsTitle": "Plugins", + "TitlePlugins": "Plugins", "HeaderAutomaticUpdates": "Automatic Updates", "HeaderNowPlaying": "Now Playing", "HeaderLatestAlbums": "Latest Albums", -- cgit v1.2.3 From d0df24d957d3e7d41281a839d190d5ec6e8c50a2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 10 Mar 2015 22:08:45 -0400 Subject: disable user lockout for now --- MediaBrowser.Server.Implementations/Library/UserManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 00c6744368..c50a71556a 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -286,10 +286,10 @@ namespace MediaBrowser.Server.Implementations.Library if (newValue >= maxCount) { - _logger.Debug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue.ToString(CultureInfo.InvariantCulture)); - user.Policy.IsDisabled = true; + //_logger.Debug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue.ToString(CultureInfo.InvariantCulture)); + //user.Policy.IsDisabled = true; - fireLockout = true; + //fireLockout = true; } await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); -- cgit v1.2.3 From fede730dc19b80c1a5915c4a39a86e40a9f27db7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 11 Mar 2015 23:37:25 -0400 Subject: don't apply path substitution when transcoding --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.Api/Playback/MediaInfoService.cs | 4 ++-- MediaBrowser.Controller/Library/IMediaSourceManager.cs | 6 ++++-- MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs | 2 +- .../Library/MediaSourceManager.cs | 10 +++++----- 5 files changed, 13 insertions(+), 11 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 7468b0b634..793066f32d 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1710,7 +1710,7 @@ namespace MediaBrowser.Api.Playback } else { - var mediaSources = await MediaSourceManager.GetPlayackMediaSources(request.Id, cancellationToken).ConfigureAwait(false); + var mediaSources = await MediaSourceManager.GetPlayackMediaSources(request.Id, false, cancellationToken).ConfigureAwait(false); var mediaSource = string.IsNullOrEmpty(request.MediaSourceId) ? mediaSources.First() diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 96958487b3..e2d3caf5e7 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -40,7 +40,7 @@ namespace MediaBrowser.Api.Playback public async Task Get(GetPlaybackInfo request) { - var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.Id, request.UserId, CancellationToken.None).ConfigureAwait(false); + var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.Id, request.UserId, true, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(new LiveMediaInfoResult { @@ -50,7 +50,7 @@ namespace MediaBrowser.Api.Playback public async Task Get(GetLiveMediaInfo request) { - var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.Id, request.UserId, CancellationToken.None).ConfigureAwait(false); + var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.Id, request.UserId, true, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(new LiveMediaInfoResult { diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs index 58bcf6cff2..c21fed6fc5 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -41,17 +41,19 @@ namespace MediaBrowser.Controller.Library /// /// The identifier. /// The user identifier. + /// if set to true [enable path substitution]. /// The cancellation token. /// IEnumerable<MediaSourceInfo>. - Task> GetPlayackMediaSources(string id, string userId, CancellationToken cancellationToken); + Task> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, CancellationToken cancellationToken); /// /// Gets the playack media sources. /// /// The identifier. + /// if set to true [enable path substitution]. /// The cancellation token. /// Task<IEnumerable<MediaSourceInfo>>. - Task> GetPlayackMediaSources(string id, CancellationToken cancellationToken); + Task> GetPlayackMediaSources(string id, bool enablePathSubstitution, CancellationToken cancellationToken); /// /// Gets the static media sources. diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index 916174c4bf..c5783e1882 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -116,7 +116,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } else { - var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.ItemId, cancellationToken).ConfigureAwait(false); + var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.ItemId, false, cancellationToken).ConfigureAwait(false); var mediaSource = string.IsNullOrEmpty(request.MediaSourceId) ? mediaSources.First() diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 746f978ea0..719c984bde 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -125,7 +125,7 @@ namespace MediaBrowser.Server.Implementations.Library return list; } - public async Task> GetPlayackMediaSources(string id, string userId, CancellationToken cancellationToken) + public async Task> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, CancellationToken cancellationToken) { var item = _libraryManager.GetItemById(id); IEnumerable mediaSources; @@ -142,12 +142,12 @@ namespace MediaBrowser.Server.Implementations.Library { if (string.IsNullOrWhiteSpace(userId)) { - mediaSources = hasMediaSources.GetMediaSources(true); + mediaSources = hasMediaSources.GetMediaSources(enablePathSubstitution); } else { var user = _userManager.GetUserById(userId); - mediaSources = GetStaticMediaSources(hasMediaSources, true, user); + mediaSources = GetStaticMediaSources(hasMediaSources, enablePathSubstitution, user); } } @@ -187,9 +187,9 @@ namespace MediaBrowser.Server.Implementations.Library } } - public Task> GetPlayackMediaSources(string id, CancellationToken cancellationToken) + public Task> GetPlayackMediaSources(string id, bool enablePathSubstitution, CancellationToken cancellationToken) { - return GetPlayackMediaSources(id, null, cancellationToken); + return GetPlayackMediaSources(id, null, enablePathSubstitution, cancellationToken); } public IEnumerable GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution) -- cgit v1.2.3 From 8f90e54faf0b71a17ee2ae54d05418c29256a84e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 11 Mar 2015 23:38:59 -0400 Subject: don't resolve audio playlists --- MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index e6e6b8c74b..070b111ee8 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1846,6 +1846,10 @@ namespace MediaBrowser.Server.Implementations.Library { var options = new ExtendedNamingOptions(); + // These cause apps to have problems + options.AudioFileExtensions.Remove(".m3u"); + options.AudioFileExtensions.Remove(".wpl"); + if (!ConfigurationManager.Configuration.EnableAudioArchiveFiles) { options.AudioFileExtensions.Remove(".rar"); -- cgit v1.2.3 From 96ec4cef77d98b0cad42a7b105e025df3543784d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 13 Mar 2015 13:25:28 -0400 Subject: add ArtistItems to api output --- MediaBrowser.Api/ItemRefreshService.cs | 2 +- MediaBrowser.Api/ItemUpdateService.cs | 26 +++++++++---- MediaBrowser.Api/Music/AlbumsService.cs | 10 ++--- MediaBrowser.Api/SearchService.cs | 2 +- MediaBrowser.Api/UserLibrary/ItemsService.cs | 45 +++++++++++++++------- MediaBrowser.Controller/Entities/Audio/Audio.cs | 10 ----- .../Entities/Audio/IHasAlbumArtist.cs | 20 ++++++++-- .../Entities/Audio/MusicAlbum.cs | 10 ----- .../Entities/Audio/MusicArtist.cs | 2 +- MediaBrowser.Controller/Entities/MusicVideo.cs | 10 ----- MediaBrowser.Controller/Playlists/Playlist.cs | 2 +- .../MediaBrowser.Model.Portable.csproj | 3 -- .../MediaBrowser.Model.net35.csproj | 3 -- MediaBrowser.Model/ApiClient/IApiClient.cs | 4 +- MediaBrowser.Model/Dto/BaseItemDto.cs | 6 +++ MediaBrowser.Model/MediaBrowser.Model.csproj | 1 - MediaBrowser.Model/Querying/ItemQuery.cs | 10 ++--- .../Querying/SimilarItemsByNameQuery.cs | 29 -------------- .../MediaInfo/FFProbeAudioInfo.cs | 2 +- .../Dto/DtoService.cs | 39 +++++++++++++------ .../Library/MusicManager.cs | 2 +- 21 files changed, 117 insertions(+), 121 deletions(-) delete mode 100644 MediaBrowser.Model/Querying/SimilarItemsByNameQuery.cs (limited to 'MediaBrowser.Server.Implementations/Library') diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs index 78bc14ab09..6a7b4826c4 100644 --- a/MediaBrowser.Api/ItemRefreshService.cs +++ b/MediaBrowser.Api/ItemRefreshService.cs @@ -53,7 +53,7 @@ namespace MediaBrowser.Api var albums = _libraryManager.RootFolder .GetRecursiveChildren() .OfType() - .Where(i => i.HasArtist(item.Name)) + .Where(i => i.HasAnyArtist(item.Name)) .ToList(); var musicArtists = albums diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index bdcad73b0d..86689f5cf3 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -389,23 +389,33 @@ namespace MediaBrowser.Api game.PlayersSupported = request.Players; } - var song = item as Audio; - - if (song != null) + var hasAlbumArtists = item as IHasAlbumArtist; + if (hasAlbumArtists != null) { - song.Album = request.Album; - song.AlbumArtists = request + hasAlbumArtists.AlbumArtists = request .AlbumArtists .Select(i => i.Name) .ToList(); - song.Artists = request.Artists.ToList(); } - var musicVideo = item as MusicVideo; + var hasArtists = item as IHasArtist; + if (hasArtists != null) + { + hasArtists.Artists = request + .ArtistItems + .Select(i => i.Name) + .ToList(); + } + + var song = item as Audio; + if (song != null) + { + song.Album = request.Album; + } + var musicVideo = item as MusicVideo; if (musicVideo != null) { - musicVideo.Artists = request.Artists.ToList(); musicVideo.Album = request.Album; } diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index 76c6c57764..a1c98addbe 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -77,15 +77,13 @@ namespace MediaBrowser.Api.Music var album1 = (MusicAlbum)item1; var album2 = (MusicAlbum)item2; - var artists1 = album1.GetRecursiveChildren(i => i is IHasArtist) - .Cast() - .SelectMany(i => i.AllArtists) + var artists1 = album1 + .AllArtists .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); - var artists2 = album2.GetRecursiveChildren(i => i is IHasArtist) - .Cast() - .SelectMany(i => i.AllArtists) + var artists2 = album2 + .AllArtists .Distinct(StringComparer.OrdinalIgnoreCase) .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index ee48946d5d..2cca72593b 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -211,7 +211,7 @@ namespace MediaBrowser.Api result.SongCount = album.Tracks.Count(); result.Artists = album.Artists.ToArray(); - result.AlbumArtist = album.AlbumArtists.FirstOrDefault(); + result.AlbumArtist = album.AlbumArtist; } var song = item as Audio; diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 0b636e93b4..256ae3625c 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -60,6 +60,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "Artists", Description = "Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Artists { get; set; } + [ApiMember(Name = "ArtistIds", Description = "Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + public string ArtistIds { get; set; } + [ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Albums { get; set; } @@ -600,6 +603,8 @@ namespace MediaBrowser.Api.UserLibrary private bool ApplyAdditionalFilters(GetItems request, BaseItem i, User user, bool isPreFiltered, ILibraryManager libraryManager) { + var video = i as Video; + if (!isPreFiltered) { var mediaTypes = request.GetMediaTypes(); @@ -647,7 +652,6 @@ namespace MediaBrowser.Api.UserLibrary if (request.Is3D.HasValue) { var val = request.Is3D.Value; - var video = i as Video; if (video == null || val != video.Video3DFormat.HasValue) { @@ -658,7 +662,6 @@ namespace MediaBrowser.Api.UserLibrary if (request.IsHD.HasValue) { var val = request.IsHD.Value; - var video = i as Video; if (video == null || val != video.IsHD) { @@ -800,8 +803,6 @@ namespace MediaBrowser.Api.UserLibrary { var val = request.HasSubtitles.Value; - var video = i as Video; - if (video == null || val != video.HasSubtitles) { return false; @@ -922,15 +923,10 @@ namespace MediaBrowser.Api.UserLibrary } // Filter by VideoType - if (!string.IsNullOrEmpty(request.VideoTypes)) + var videoTypes = request.GetVideoTypes(); + if (video == null || !videoTypes.Contains(video.VideoType)) { - var types = request.VideoTypes.Split(','); - - var video = i as Video; - if (video == null || !types.Contains(video.VideoType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } + return false; } var imageTypes = request.GetImageTypes().ToList(); @@ -1014,6 +1010,29 @@ namespace MediaBrowser.Api.UserLibrary } } + // Artists + if (!string.IsNullOrEmpty(request.ArtistIds)) + { + var artistIds = request.ArtistIds.Split('|'); + + var audio = i as IHasArtist; + + if (!(audio != null && artistIds.Any(id => + { + try + { + return audio.HasAnyArtist(libraryManager.GetItemById(id).Name); + } + catch (Exception ex) + { + return false; + } + }))) + { + return false; + } + } + // Artists if (!string.IsNullOrEmpty(request.Artists)) { @@ -1021,7 +1040,7 @@ namespace MediaBrowser.Api.UserLibrary var audio = i as IHasArtist; - if (!(audio != null && artists.Any(audio.HasArtist))) + if (!(audio != null && artists.Any(audio.HasAnyArtist))) { return false; } diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index d868227d95..c033b144af 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -171,16 +171,6 @@ namespace MediaBrowser.Controller.Entities.Audio + (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name; } - /// - /// Determines whether the specified name has artist. - /// - /// The name. - /// true if the specified name has artist; otherwise, false. - public bool HasArtist(string name) - { - return AllArtists.Contains(name, StringComparer.OrdinalIgnoreCase); - } - /// /// Gets the user data key. /// diff --git a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs b/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs index a20f053232..56921409ae 100644 --- a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; namespace MediaBrowser.Controller.Entities.Audio { @@ -9,10 +11,20 @@ namespace MediaBrowser.Controller.Entities.Audio public interface IHasArtist { - bool HasArtist(string name); - List AllArtists { get; } - List Artists { get; } + List Artists { get; set; } + } + + public static class HasArtistExtensions + { + public static bool HasArtist(this IHasArtist hasArtist, string artist) + { + return hasArtist.Artists.Contains(artist, StringComparer.OrdinalIgnoreCase); + } + public static bool HasAnyArtist(this IHasArtist hasArtist, string artist) + { + return hasArtist.AllArtists.Contains(artist, StringComparer.OrdinalIgnoreCase); + } } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index e3f523b5a7..dc3f13b01d 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -120,16 +120,6 @@ namespace MediaBrowser.Controller.Entities.Audio get { return Parent as MusicArtist ?? UnknwonArtist; } } - /// - /// Determines whether the specified artist has artist. - /// - /// The artist. - /// true if the specified artist has artist; otherwise, false. - public bool HasArtist(string artist) - { - return AllArtists.Contains(artist, StringComparer.OrdinalIgnoreCase); - } - public List Artists { get; set; } /// diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index fed9689b36..4185590ab3 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -213,7 +213,7 @@ namespace MediaBrowser.Controller.Entities.Audio return i => { var hasArtist = i as IHasArtist; - return hasArtist != null && hasArtist.HasArtist(Name); + return hasArtist != null && hasArtist.HasAnyArtist(Name); }; } } diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs index 771c62fd6d..b2cad02de8 100644 --- a/MediaBrowser.Controller/Entities/MusicVideo.cs +++ b/MediaBrowser.Controller/Entities/MusicVideo.cs @@ -47,16 +47,6 @@ namespace MediaBrowser.Controller.Entities } } - /// - /// Determines whether the specified name has artist. - /// - /// The name. - /// true if the specified name has artist; otherwise, false. - public bool HasArtist(string name) - { - return AllArtists.Contains(name, StringComparer.OrdinalIgnoreCase); - } - /// /// Gets the user data key. /// diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 3479902cbd..fdc36db354 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -106,7 +106,7 @@ namespace MediaBrowser.Controller.Playlists Func filter = i => { var audio = i as Audio; - return audio != null && audio.HasArtist(musicArtist.Name); + return audio != null && audio.HasAnyArtist(musicArtist.Name); }; var items = user == null diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index b72a895ca2..74f927c7e2 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -980,9 +980,6 @@ Querying\SessionQuery.cs - - Querying\SimilarItemsByNameQuery.cs - Querying\SimilarItemsQuery.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 7a28f6de83..7f6f7bc132 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -942,9 +942,6 @@ Querying\SessionQuery.cs - - Querying\SimilarItemsByNameQuery.cs - Querying\SimilarItemsQuery.cs diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 190f2100eb..0b55d0b45c 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -344,14 +344,14 @@ namespace MediaBrowser.Model.ApiClient /// /// The query. /// Task{ItemsResult}. - Task GetInstantMixFromArtistAsync(SimilarItemsByNameQuery query); + Task GetInstantMixFromArtistAsync(SimilarItemsQuery query); /// /// Gets the instant mix from music genre async. /// /// The query. /// Task{ItemsResult}. - Task GetInstantMixFromMusicGenreAsync(SimilarItemsByNameQuery query); + Task GetInstantMixFromMusicGenreAsync(SimilarItemsQuery query); /// /// Gets the similar movies async. diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 66066e392d..7a1c78112f 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -466,6 +466,12 @@ namespace MediaBrowser.Model.Dto /// The artists. public List Artists { get; set; } + /// + /// Gets or sets the artist items. + /// + /// The artist items. + public List ArtistItems { get; set; } + /// /// Gets or sets the album. /// diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index fd50e598a9..601ba6dc17 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -322,7 +322,6 @@ - diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs index a40eca5b5a..1fde6d62da 100644 --- a/MediaBrowser.Model/Querying/ItemQuery.cs +++ b/MediaBrowser.Model/Querying/ItemQuery.cs @@ -39,11 +39,11 @@ namespace MediaBrowser.Model.Querying public string[] SortBy { get; set; } /// - /// Filter by artists + /// Gets or sets the artist ids. /// - /// The artists. - public string[] Artists { get; set; } - + /// The artist ids. + public string[] ArtistIds { get; set; } + /// /// The sort order to return results with /// @@ -306,7 +306,7 @@ namespace MediaBrowser.Model.Querying Years = new int[] { }; PersonTypes = new string[] { }; Ids = new string[] { }; - Artists = new string[] { }; + ArtistIds = new string[] { }; ImageTypes = new ImageType[] { }; AirDays = new DayOfWeek[] { }; diff --git a/MediaBrowser.Model/Querying/SimilarItemsByNameQuery.cs b/MediaBrowser.Model/Querying/SimilarItemsByNameQuery.cs deleted file mode 100644 index 7d0d4da317..0000000000 --- a/MediaBrowser.Model/Querying/SimilarItemsByNameQuery.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace MediaBrowser.Model.Querying -{ - public class SimilarItemsByNameQuery - { - /// - /// The user to localize search results for - /// - /// The user id. - public string UserId { get; set; } - - /// - /// Gets or sets the name. - /// - /// The name. - public string Name { get; set; } - - /// - /// The maximum number of items to return - /// - /// The limit. - public int? Limit { get; set; } - - /// - /// Fields to return within the items, in addition to basic information - /// - /// The fields. - public ItemFields[] Fields { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs index 26d00d5444..ea191dd08f 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs @@ -387,7 +387,7 @@ namespace MediaBrowser.Providers.MediaInfo if (!string.IsNullOrEmpty(val)) { // Sometimes the artist name is listed here, account for that - var studios = Split(val, true).Where(i => !audio.HasArtist(i)); + var studios = Split(val, true).Where(i => !audio.HasAnyArtist(i)); foreach (var studio in studios) { diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 8086033ebb..3280cf264b 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -504,7 +504,6 @@ namespace MediaBrowser.Server.Implementations.Dto } dto.Album = item.Album; - dto.Artists = item.Artists; } private void SetGameProperties(BaseItemDto dto, Game item) @@ -1142,7 +1141,6 @@ namespace MediaBrowser.Server.Implementations.Dto if (audio != null) { dto.Album = audio.Album; - dto.Artists = audio.Artists; var albumParent = audio.FindParent(); @@ -1163,15 +1161,40 @@ namespace MediaBrowser.Server.Implementations.Dto if (album != null) { - dto.Artists = album.Artists; - dto.SoundtrackIds = album.SoundtrackIds .Select(i => i.ToString("N")) .ToArray(); } - var hasAlbumArtist = item as IHasAlbumArtist; + var hasArtist = item as IHasArtist; + if (hasArtist != null) + { + dto.Artists = hasArtist.Artists; + + dto.ArtistItems = hasArtist + .Artists + .Select(i => + { + try + { + var artist = _libraryManager.GetArtist(i); + return new NameIdPair + { + Name = artist.Name, + Id = artist.Id.ToString("N") + }; + } + catch (Exception ex) + { + _logger.ErrorException("Error getting artist", ex); + return null; + } + }) + .Where(i => i != null) + .ToList(); + } + var hasAlbumArtist = item as IHasAlbumArtist; if (hasAlbumArtist != null) { dto.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); @@ -1253,7 +1276,6 @@ namespace MediaBrowser.Server.Implementations.Dto // Add MovieInfo var movie = item as Movie; - if (movie != null) { if (fields.Contains(ItemFields.TmdbCollectionName)) @@ -1263,7 +1285,6 @@ namespace MediaBrowser.Server.Implementations.Dto } var hasSpecialFeatures = item as IHasSpecialFeatures; - if (hasSpecialFeatures != null) { var specialFeatureCount = hasSpecialFeatures.SpecialFeatureIds.Count; @@ -1276,7 +1297,6 @@ namespace MediaBrowser.Server.Implementations.Dto // Add EpisodeInfo var episode = item as Episode; - if (episode != null) { dto.IndexNumberEnd = episode.IndexNumberEnd; @@ -1318,7 +1338,6 @@ namespace MediaBrowser.Server.Implementations.Dto // Add SeriesInfo var series = item as Series; - if (series != null) { dto.AirDays = series.AirDays; @@ -1368,7 +1387,6 @@ namespace MediaBrowser.Server.Implementations.Dto // Add SeasonInfo var season = item as Season; - if (season != null) { series = season.Series; @@ -1402,7 +1420,6 @@ namespace MediaBrowser.Server.Implementations.Dto } var musicVideo = item as MusicVideo; - if (musicVideo != null) { SetMusicVideoProperties(dto, musicVideo); diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index 7733e7d379..3a854f2fe0 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Library var genres = user.RootFolder .GetRecursiveChildren(user, i => i is Audio) .Cast