From b9f3944b7f2cbfba1dadffd0ac0594ad3cd81f38 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 1 Apr 2015 17:56:32 -0400 Subject: rework media source methods --- MediaBrowser.Controller/Library/IMediaSourceManager.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'MediaBrowser.Controller/Library') diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs index 9cbbabc8db..5bcc5f3136 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -63,15 +63,7 @@ namespace MediaBrowser.Controller.Library /// if set to true [enable path substitution]. /// The user. /// IEnumerable<MediaSourceInfo>. - IEnumerable GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user); - - /// - /// Gets the static media sources. - /// - /// The item. - /// if set to true [enable path substitution]. - /// IEnumerable<MediaSourceInfo>. - IEnumerable GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution); + IEnumerable GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null); /// /// Gets the static media source. -- cgit v1.2.3 From b9c656e859fe28ed6a66580d1eb5577bd50264e6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 9 Apr 2015 01:20:23 -0400 Subject: added out of network bitrate limit --- Emby.Drawing/GDI/GDIImageEncoder.cs | 9 ++++-- Emby.Drawing/IImageEncoder.cs | 5 +++ Emby.Drawing/ImageMagick/ImageMagickEncoder.cs | 5 +++ MediaBrowser.Api/LiveTv/LiveTvService.cs | 6 ++-- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.Api/Playback/MediaInfoService.cs | 37 +++++++++++++++------- MediaBrowser.Api/Subtitles/SubtitleService.cs | 4 +-- .../BaseApplicationHost.cs | 13 +++----- .../Networking/BaseNetworkManager.cs | 12 ++++--- .../Library/IMediaSourceManager.cs | 16 +++------- .../Providers/IImageEnhancer.cs | 3 +- MediaBrowser.Dlna/PlayTo/PlayToController.cs | 2 +- .../Encoder/EncodingJobFactory.cs | 2 +- .../Subtitles/SubtitleEncoder.cs | 2 +- .../Configuration/ServerConfiguration.cs | 1 + MediaBrowser.Model/Session/ClientCapabilities.cs | 2 ++ MediaBrowser.Model/Users/UserPolicy.cs | 10 +++--- .../Library/MediaSourceManager.cs | 28 ++++++++++------ .../Localization/JavaScript/javascript.json | 2 +- .../Localization/Server/server.json | 8 +++-- .../Session/SessionManager.cs | 7 ++-- .../Sync/CloudSyncProfile.cs | 26 +++++++++++++-- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 1 + .../MediaBrowser.WebDashboard.csproj | 6 ++++ 24 files changed, 136 insertions(+), 73 deletions(-) (limited to 'MediaBrowser.Controller/Library') diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing/GDI/GDIImageEncoder.cs index 33502c5e11..d968b8b5fe 100644 --- a/Emby.Drawing/GDI/GDIImageEncoder.cs +++ b/Emby.Drawing/GDI/GDIImageEncoder.cs @@ -1,5 +1,4 @@ -using System.Linq; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Logging; @@ -8,6 +7,7 @@ using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; +using System.Linq; using ImageFormat = MediaBrowser.Model.Drawing.ImageFormat; namespace Emby.Drawing.GDI @@ -245,5 +245,10 @@ namespace Emby.Drawing.GDI public void Dispose() { } + + public string Name + { + get { return "GDI"; } + } } } diff --git a/Emby.Drawing/IImageEncoder.cs b/Emby.Drawing/IImageEncoder.cs index 83a59a0026..29261dbdb3 100644 --- a/Emby.Drawing/IImageEncoder.cs +++ b/Emby.Drawing/IImageEncoder.cs @@ -44,5 +44,10 @@ namespace Emby.Drawing /// /// The options. void CreateImageCollage(ImageCollageOptions options); + /// + /// Gets the name. + /// + /// The name. + string Name { get; } } } diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index b4a00f027a..3d6cdd03dd 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -206,6 +206,11 @@ namespace Emby.Drawing.ImageMagick } } + public string Name + { + get { return "ImageMagick"; } + } + private bool _disposed; public void Dispose() { diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index bb6f74f364..8cb814b971 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -433,7 +433,7 @@ namespace MediaBrowser.Api.LiveTv var result = await _liveTvManager.GetPrograms(query, CancellationToken.None).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public async Task Get(GetRecommendedPrograms request) @@ -450,7 +450,7 @@ namespace MediaBrowser.Api.LiveTv var result = await _liveTvManager.GetRecommendedPrograms(query, CancellationToken.None).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public object Post(GetPrograms request) @@ -473,7 +473,7 @@ namespace MediaBrowser.Api.LiveTv }, CancellationToken.None).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public async Task Get(GetRecording request) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 302ad7f29a..62bee1f9b7 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1627,7 +1627,7 @@ namespace MediaBrowser.Api.Playback MediaSourceInfo mediaSource; if (string.IsNullOrWhiteSpace(request.LiveStreamId)) { - var mediaSources = (await MediaSourceManager.GetPlayackMediaSources(request.Id, false, cancellationToken).ConfigureAwait(false)).ToList(); + var mediaSources = (await MediaSourceManager.GetPlayackMediaSources(request.Id, null, false, new[] { MediaType.Audio, MediaType.Video }, cancellationToken).ConfigureAwait(false)).ToList(); mediaSource = string.IsNullOrEmpty(request.MediaSourceId) ? mediaSources.First() diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index abd0278c26..6e5af261c8 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Controller.Devices; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; @@ -59,23 +61,27 @@ namespace MediaBrowser.Api.Playback private readonly IMediaSourceManager _mediaSourceManager; private readonly IDeviceManager _deviceManager; private readonly ILibraryManager _libraryManager; + private readonly IServerConfigurationManager _config; + private readonly INetworkManager _networkManager; - public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager) + public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager) { _mediaSourceManager = mediaSourceManager; _deviceManager = deviceManager; _libraryManager = libraryManager; + _config = config; + _networkManager = networkManager; } public async Task Get(GetPlaybackInfo request) { - var result = await GetPlaybackInfo(request.Id, request.UserId).ConfigureAwait(false); + var result = await GetPlaybackInfo(request.Id, request.UserId, new[] { MediaType.Audio, MediaType.Video }).ConfigureAwait(false); return ToOptimizedResult(result); } public async Task Get(GetLiveMediaInfo request) { - var result = await GetPlaybackInfo(request.Id, request.UserId).ConfigureAwait(false); + var result = await GetPlaybackInfo(request.Id, request.UserId, new[] { MediaType.Audio, MediaType.Video }).ConfigureAwait(false); return ToOptimizedResult(result); } @@ -122,29 +128,38 @@ namespace MediaBrowser.Api.Playback public async Task Post(GetPostedPlaybackInfo request) { - var info = await GetPlaybackInfo(request.Id, request.UserId, request.MediaSourceId, request.LiveStreamId).ConfigureAwait(false); var authInfo = AuthorizationContext.GetAuthorizationInfo(Request); var profile = request.DeviceProfile; - if (profile == null) + + var caps = _deviceManager.GetCapabilities(authInfo.DeviceId); + if (caps != null) { - var caps = _deviceManager.GetCapabilities(authInfo.DeviceId); - if (caps != null) + if (profile == null) { profile = caps.DeviceProfile; } } + var maxBitrate = request.MaxStreamingBitrate; + + if (_config.Configuration.RemoteClientBitrateLimit > 0 && !_networkManager.IsInLocalNetwork(Request.RemoteIp)) + { + maxBitrate = Math.Min(maxBitrate ?? _config.Configuration.RemoteClientBitrateLimit, _config.Configuration.RemoteClientBitrateLimit); + } + + var info = await GetPlaybackInfo(request.Id, request.UserId, new[] { MediaType.Audio, MediaType.Video }, request.MediaSourceId, request.LiveStreamId).ConfigureAwait(false); + if (profile != null) { var mediaSourceId = request.MediaSourceId; - SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex); + SetDeviceSpecificData(request.Id, info, profile, authInfo, maxBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex); } return ToOptimizedResult(info); } - private async Task GetPlaybackInfo(string id, string userId, string mediaSourceId = null, string liveStreamId = null) + private async Task GetPlaybackInfo(string id, string userId, string[] supportedLiveMediaTypes, string mediaSourceId = null, string liveStreamId = null) { var result = new PlaybackInfoResponse(); @@ -153,7 +168,7 @@ namespace MediaBrowser.Api.Playback IEnumerable mediaSources; try { - mediaSources = await _mediaSourceManager.GetPlayackMediaSources(id, userId, true, CancellationToken.None).ConfigureAwait(false); + mediaSources = await _mediaSourceManager.GetPlayackMediaSources(id, userId, true, supportedLiveMediaTypes, CancellationToken.None).ConfigureAwait(false); } catch (PlaybackException ex) { diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index 73589d6777..a70118d3ce 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -136,11 +136,11 @@ namespace MediaBrowser.Api.Subtitles _providerManager = providerManager; } - public object Get(GetSubtitlePlaylist request) + public async Task Get(GetSubtitlePlaylist request) { var item = (Video)_libraryManager.GetItemById(new Guid(request.Id)); - var mediaSource = _mediaSourceManager.GetStaticMediaSource(item, request.MediaSourceId, false); + var mediaSource = await _mediaSourceManager.GetMediaSource(item, request.MediaSourceId, false).ConfigureAwait(false); var builder = new StringBuilder(); diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index bc1b0e7855..70ed5c3191 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -101,12 +101,6 @@ namespace MediaBrowser.Common.Implementations /// The failed assemblies. public List FailedAssemblies { get; protected set; } - /// - /// Gets all types within all running assemblies - /// - /// All types. - public Type[] AllTypes { get; protected set; } - /// /// Gets all concrete types. /// @@ -438,9 +432,10 @@ namespace MediaBrowser.Common.Implementations Logger.Info("Loading {0}", assembly.FullName); } - AllTypes = assemblies.SelectMany(GetTypes).ToArray(); - - AllConcreteTypes = AllTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray(); + AllConcreteTypes = assemblies + .SelectMany(GetTypes) + .Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType) + .ToArray(); } /// diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index 1762ed5754..0fd4e27874 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -172,11 +172,11 @@ namespace MediaBrowser.Common.Implementations.Networking Uri uri; if (Uri.TryCreate(endpoint, UriKind.RelativeOrAbsolute, out uri)) { - var host = uri.DnsSafeHost; - Logger.Debug("Resolving host {0}", host); - try { + var host = uri.DnsSafeHost; + Logger.Debug("Resolving host {0}", host); + address = GetIpAddresses(host).FirstOrDefault(); if (address != null) @@ -186,9 +186,13 @@ namespace MediaBrowser.Common.Implementations.Networking return IsInLocalNetworkInternal(address.ToString(), false); } } + catch (InvalidOperationException) + { + // Can happen with reverse proxy or IIS url rewriting + } catch (Exception ex) { - Logger.ErrorException("Error resovling hostname {0}", ex, host); + Logger.ErrorException("Error resovling hostname", ex); } } } diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs index 5bcc5f3136..a77d88049b 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -43,18 +43,10 @@ namespace MediaBrowser.Controller.Library /// The identifier. /// The user identifier. /// if set to true [enable path substitution]. + /// The supported live media types. /// The cancellation token. /// IEnumerable<MediaSourceInfo>. - 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, bool enablePathSubstitution, CancellationToken cancellationToken); + Task> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, string[] supportedLiveMediaTypes, CancellationToken cancellationToken); /// /// Gets the static media sources. @@ -64,7 +56,7 @@ namespace MediaBrowser.Controller.Library /// The user. /// IEnumerable<MediaSourceInfo>. IEnumerable GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null); - + /// /// Gets the static media source. /// @@ -72,7 +64,7 @@ namespace MediaBrowser.Controller.Library /// The media source identifier. /// if set to true [enable path substitution]. /// MediaSourceInfo. - MediaSourceInfo GetStaticMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution); + Task GetMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution); /// /// Opens the media source. diff --git a/MediaBrowser.Controller/Providers/IImageEnhancer.cs b/MediaBrowser.Controller/Providers/IImageEnhancer.cs index e5a51a56e0..a43941607e 100644 --- a/MediaBrowser.Controller/Providers/IImageEnhancer.cs +++ b/MediaBrowser.Controller/Providers/IImageEnhancer.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; using System.Threading.Tasks; diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index d88adc8c62..9df69b1157 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -892,7 +892,7 @@ namespace MediaBrowser.Dlna.PlayTo request.MediaSource = hasMediaSources == null ? null : - mediaSourceManager.GetStaticMediaSource(hasMediaSources, request.MediaSourceId, false); + mediaSourceManager.GetMediaSource(hasMediaSources, request.MediaSourceId, false).Result; diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index 8d82010749..a0f5d928dd 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -59,7 +59,7 @@ namespace MediaBrowser.MediaEncoding.Encoder state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase); - var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.ItemId, false, cancellationToken).ConfigureAwait(false); + var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.ItemId, null, false, new[] { MediaType.Audio, MediaType.Video }, cancellationToken).ConfigureAwait(false); var mediaSource = string.IsNullOrEmpty(request.MediaSourceId) ? mediaSources.First() diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 14d3e72840..60b70ad083 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -132,7 +132,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles int subtitleStreamIndex, CancellationToken cancellationToken) { - var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(itemId, false, cancellationToken).ConfigureAwait(false); + var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(itemId, null, false, new[] { MediaType.Audio, MediaType.Video }, cancellationToken).ConfigureAwait(false); var mediaSource = mediaSources .First(i => string.Equals(i.Id, mediaSourceId)); diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index bc167333ae..ac9bd6b08f 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -208,6 +208,7 @@ namespace MediaBrowser.Model.Configuration public bool EnableAudioArchiveFiles { get; set; } public bool EnableVideoArchiveFiles { get; set; } + public int RemoteClientBitrateLimit { get; set; } /// /// Initializes a new instance of the class. diff --git a/MediaBrowser.Model/Session/ClientCapabilities.cs b/MediaBrowser.Model/Session/ClientCapabilities.cs index 9361a60ea4..25438a811c 100644 --- a/MediaBrowser.Model/Session/ClientCapabilities.cs +++ b/MediaBrowser.Model/Session/ClientCapabilities.cs @@ -19,12 +19,14 @@ namespace MediaBrowser.Model.Session public bool SupportsOfflineAccess { get; set; } public DeviceProfile DeviceProfile { get; set; } + public List SupportedLiveMediaTypes { get; set; } public ClientCapabilities() { PlayableMediaTypes = new List(); SupportedCommands = new List(); SupportsPersistentIdentifier = true; + SupportedLiveMediaTypes = new List(); } } } \ No newline at end of file diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index b3c5994966..d7c894587d 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -39,8 +39,9 @@ namespace MediaBrowser.Model.Users public bool EnableLiveTvAccess { get; set; } public bool EnableMediaPlayback { get; set; } - public bool EnableMediaPlaybackTranscoding { get; set; } - + public bool EnableAudioPlaybackTranscoding { get; set; } + public bool EnableVideoPlaybackTranscoding { get; set; } + public bool EnableContentDeletion { get; set; } public bool EnableContentDownloading { get; set; } @@ -68,8 +69,9 @@ namespace MediaBrowser.Model.Users EnableSyncTranscoding = true; EnableMediaPlayback = true; - EnableMediaPlaybackTranscoding = true; - + EnableAudioPlaybackTranscoding = true; + EnableVideoPlaybackTranscoding = true; + EnableLiveTvManagement = true; EnableLiveTvAccess = true; diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 01efe0ab10..71fd4127b5 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -129,12 +129,7 @@ namespace MediaBrowser.Server.Implementations.Library return list; } - public Task> GetPlayackMediaSources(string id, bool enablePathSubstitution, CancellationToken cancellationToken) - { - return GetPlayackMediaSources(id, null, enablePathSubstitution, cancellationToken); - } - - public async Task> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, CancellationToken cancellationToken) + public async Task> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, string[] supportedLiveMediaTypes, CancellationToken cancellationToken) { var item = _libraryManager.GetItemById(id); @@ -184,9 +179,19 @@ namespace MediaBrowser.Server.Implementations.Library { if (user != null) { - if (!user.Policy.EnableMediaPlaybackTranscoding) + if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)) { - source.SupportsTranscoding = false; + if (!user.Policy.EnableAudioPlaybackTranscoding) + { + source.SupportsTranscoding = false; + } + } + else if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) + { + if (!user.Policy.EnableVideoPlaybackTranscoding) + { + source.SupportsTranscoding = false; + } } } } @@ -238,9 +243,12 @@ namespace MediaBrowser.Server.Implementations.Library } } - public MediaSourceInfo GetStaticMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution) + public async Task GetMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution) { - return GetStaticMediaSources(item, enablePathSubstitution).FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)); + var sources = await GetPlayackMediaSources(item.Id.ToString("N"), null, enablePathSubstitution, new[] { MediaType.Audio, MediaType.Video }, + CancellationToken.None).ConfigureAwait(false); + + return sources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)); } public IEnumerable GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index f782a1f680..4c6689bc63 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -122,7 +122,7 @@ "LabelFree": "Free", "HeaderPlaybackError": "Playback Error", "MessagePlaybackErrorNotAllowed": "You're currently not authorized to play this content. Please contact your system administrator for details.", - "MessagePlaybackErrorNoCompatibleStream": "No compatible streams are currently available. Please try again later.", + "MessagePlaybackErrorNoCompatibleStream": "No compatible streams are currently available. Please try again later or contact your system administrator for details.", "MessagePlaybackErrorRateLimitExceeded": "Your playback rate limit has been exceeded. Please contact your system administrator for details.", "MessagePlaybackErrorPlaceHolder": "The content chosen is not playable from this device.", "HeaderSelectAudio": "Select Audio", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index bf03498dbb..b651b72dae 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1410,6 +1410,10 @@ "LabelUploadSpeedLimit": "Upload speed limit (mbps):", "OptionAllowSyncTranscoding": "Allow syncing that requires transcoding", "HeaderPlayback": "Media Playback", - "OptionAllowMediaPlaybackTranscoding": "Allow media playback that requires transcoding", - "OptionAllowMediaPlaybackTranscodingHelp": "Users will receive friendly messages when content is unplayable based on policy." + "OptionAllowAudioPlaybackTranscoding": "Allow audio playback that requires transcoding", + "OptionAllowVideoPlaybackTranscoding": "Allow video playback that requires transcoding", + "OptionAllowMediaPlaybackTranscodingHelp": "Users will receive friendly messages when content is unplayable based on policy.", + "TabStreaming": "Streaming", + "LabelRemoteClientBitrateLimit": "Remote client bitrate limit (mbps):", + "LabelRemoteClientBitrateLimitHelp": "An optional streaming bitrate limit for all remote clients. This is useful to prevent clients from requesting a higher bitrate than your connection can handle." } diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 7f5033b98f..112778ec8a 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -305,12 +305,9 @@ namespace MediaBrowser.Server.Implementations.Session } } - private async Task GetMediaSource(IHasMediaSources item, string mediaSourceId) + private Task GetMediaSource(IHasMediaSources item, string mediaSourceId) { - var sources = await _mediaSourceManager.GetPlayackMediaSources(item.Id.ToString("N"), false, CancellationToken.None) - .ConfigureAwait(false); - - return sources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)); + return _mediaSourceManager.GetMediaSource(item, mediaSourceId, false); } /// diff --git a/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs b/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs index 73400f8345..f881a2055c 100644 --- a/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs +++ b/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs @@ -195,17 +195,39 @@ namespace MediaBrowser.Server.Implementations.Sync } }; - var maxAudioChannels = supportsAc3 || supportsDca ? "5" : "2"; codecProfiles.Add(new CodecProfile { Type = CodecType.VideoAudio, + Codec = "ac3", Conditions = new[] { new ProfileCondition { Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.AudioChannels, - Value = maxAudioChannels, + Value = "5", + IsRequired = true + }, + new ProfileCondition + { + Condition = ProfileConditionType.Equals, + Property = ProfileConditionValue.IsSecondaryAudio, + Value = "false", + IsRequired = false + } + } + }); + codecProfiles.Add(new CodecProfile + { + Type = CodecType.VideoAudio, + Codec = "ac3", + Conditions = new[] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "2", IsRequired = true }, new ProfileCondition diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 5138b157f1..90af13b579 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -482,6 +482,7 @@ namespace MediaBrowser.WebDashboard.Api "selectserver.js", "serversecurity.js", "songs.js", + "streamingsettings.js", "supporterkeypage.js", "supporterpage.js", "syncactivity.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 4ad2ab685d..7abe2ded98 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -150,6 +150,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -174,6 +177,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 1b600aee37fbcbe27ba48e669b5ada790aa4c5da Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 9 Apr 2015 17:11:57 -0400 Subject: improve name matching --- MediaBrowser.Api/BaseApiService.cs | 10 +++--- MediaBrowser.Api/FilterService.cs | 2 +- MediaBrowser.Api/Movies/MoviesService.cs | 4 +-- MediaBrowser.Api/Music/AlbumsService.cs | 4 +-- MediaBrowser.Api/SimilarItemsHelper.cs | 2 +- MediaBrowser.Api/UserLibrary/ArtistsService.cs | 4 +-- MediaBrowser.Api/UserLibrary/GameGenresService.cs | 2 +- MediaBrowser.Api/UserLibrary/GenresService.cs | 2 +- MediaBrowser.Api/UserLibrary/MusicGenresService.cs | 2 +- MediaBrowser.Api/UserLibrary/PersonsService.cs | 2 +- MediaBrowser.Api/UserLibrary/StudiosService.cs | 2 +- .../Entities/Audio/IHasAlbumArtist.cs | 7 ++-- .../Entities/Audio/MusicArtist.cs | 1 - .../Entities/UserViewBuilder.cs | 16 ++++----- MediaBrowser.Controller/Library/NameExtensions.cs | 41 ++++++++++++++++++++++ .../MediaBrowser.Controller.csproj | 1 + .../Music/ArtistMetadataService.cs | 2 +- .../Library/LibraryManager.cs | 4 +-- .../Library/SearchEngine.cs | 2 +- .../Library/Validators/ArtistsValidator.cs | 2 +- .../Library/Validators/GameGenresValidator.cs | 2 +- .../Library/Validators/GenresValidator.cs | 2 +- .../Library/Validators/MusicGenresValidator.cs | 2 +- .../Library/Validators/StudiosValidator.cs | 2 +- .../LiveTv/LiveTvManager.cs | 2 +- .../Localization/Server/server.json | 2 +- 26 files changed, 81 insertions(+), 43 deletions(-) create mode 100644 MediaBrowser.Controller/Library/NameExtensions.cs (limited to 'MediaBrowser.Controller/Library') diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 4465be97a2..66b2a314e4 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -259,7 +259,7 @@ namespace MediaBrowser.Api .GetRecursiveChildren(i => i is IHasArtist) .Cast() .SelectMany(i => i.AllArtists) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .FirstOrDefault(i => { i = _dashReplaceChars.Aggregate(i, (current, c) => current.Replace(c, SlugChar)); @@ -281,7 +281,7 @@ namespace MediaBrowser.Api return libraryManager.RootFolder.GetRecursiveChildren() .SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .FirstOrDefault(i => { i = _dashReplaceChars.Aggregate(i, (current, c) => current.Replace(c, SlugChar)); @@ -301,7 +301,7 @@ namespace MediaBrowser.Api return libraryManager.RootFolder .GetRecursiveChildren(i => i is Game) .SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .FirstOrDefault(i => { i = _dashReplaceChars.Aggregate(i, (current, c) => current.Replace(c, SlugChar)); @@ -324,7 +324,7 @@ namespace MediaBrowser.Api return libraryManager.RootFolder .GetRecursiveChildren() .SelectMany(i => i.Studios) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .FirstOrDefault(i => { i = _dashReplaceChars.Aggregate(i, (current, c) => current.Replace(c, SlugChar)); @@ -348,7 +348,7 @@ namespace MediaBrowser.Api .GetRecursiveChildren() .SelectMany(i => i.People) .Select(i => i.Name) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .FirstOrDefault(i => { i = _dashReplaceChars.Aggregate(i, (current, c) => current.Replace(c, SlugChar)); diff --git a/MediaBrowser.Api/FilterService.cs b/MediaBrowser.Api/FilterService.cs index fb51b2bdd4..6d1c5d868d 100644 --- a/MediaBrowser.Api/FilterService.cs +++ b/MediaBrowser.Api/FilterService.cs @@ -76,7 +76,7 @@ namespace MediaBrowser.Api .ToArray(); result.Genres = items.SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .OrderBy(i => i) .ToArray(); diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 07f5942c62..1a7f6d8f49 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -410,7 +410,7 @@ namespace MediaBrowser.Api.Movies return items .SelectMany(i => i.People.Where(p => !string.Equals(PersonType.Director, p.Type, StringComparison.OrdinalIgnoreCase)).Take(2)) .Select(i => i.Name) - .Distinct(StringComparer.OrdinalIgnoreCase); + .DistinctNames(); } private IEnumerable GetDirectors(IEnumerable items) @@ -419,7 +419,7 @@ namespace MediaBrowser.Api.Movies .Select(i => i.People.FirstOrDefault(p => string.Equals(PersonType.Director, p.Type, StringComparison.OrdinalIgnoreCase))) .Where(i => i != null) .Select(i => i.Name) - .Distinct(StringComparer.OrdinalIgnoreCase); + .DistinctNames(); } } } diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index a1c98addbe..37f79bf208 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -79,12 +79,12 @@ namespace MediaBrowser.Api.Music var artists1 = album1 .AllArtists - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .ToList(); var artists2 = album2 .AllArtists - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); return points + artists1.Where(artists2.ContainsKey).Sum(i => 5); diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs index e061c391a2..fb04dd0301 100644 --- a/MediaBrowser.Api/SimilarItemsHelper.cs +++ b/MediaBrowser.Api/SimilarItemsHelper.cs @@ -170,7 +170,7 @@ namespace MediaBrowser.Api points += item1.Studios.Where(i => item2.Studios.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 3); var item2PeopleNames = item2.People.Select(i => i.Name) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); points += item1.People.Where(i => item2PeopleNames.ContainsKey(i.Name)).Sum(i => diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs index dd9825debd..9f3f174657 100644 --- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs +++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs @@ -132,7 +132,7 @@ namespace MediaBrowser.Api.UserLibrary .Where(i => !i.IsFolder) .OfType() .SelectMany(i => i.AlbumArtists) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(name => { try @@ -152,7 +152,7 @@ namespace MediaBrowser.Api.UserLibrary .Where(i => !i.IsFolder) .OfType() .SelectMany(i => i.AllArtists) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(name => { try diff --git a/MediaBrowser.Api/UserLibrary/GameGenresService.cs b/MediaBrowser.Api/UserLibrary/GameGenresService.cs index 3063e19c72..2f7430d333 100644 --- a/MediaBrowser.Api/UserLibrary/GameGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GameGenresService.cs @@ -105,7 +105,7 @@ namespace MediaBrowser.Api.UserLibrary return itemsList .SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(name => LibraryManager.GetGameGenre(name)); } } diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs index c659852de8..63c0575bff 100644 --- a/MediaBrowser.Api/UserLibrary/GenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GenresService.cs @@ -108,7 +108,7 @@ namespace MediaBrowser.Api.UserLibrary { return items .SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(name => { try diff --git a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs index 3733128f04..1fe9dfaaa3 100644 --- a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs @@ -105,7 +105,7 @@ namespace MediaBrowser.Api.UserLibrary return itemsList .SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(name => LibraryManager.GetMusicGenre(name)); } } diff --git a/MediaBrowser.Api/UserLibrary/PersonsService.cs b/MediaBrowser.Api/UserLibrary/PersonsService.cs index e9b3fa402f..08ee6e462e 100644 --- a/MediaBrowser.Api/UserLibrary/PersonsService.cs +++ b/MediaBrowser.Api/UserLibrary/PersonsService.cs @@ -127,7 +127,7 @@ namespace MediaBrowser.Api.UserLibrary return allPeople .Select(i => i.Name) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(name => { diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs index a4ebef6846..ae1da03468 100644 --- a/MediaBrowser.Api/UserLibrary/StudiosService.cs +++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs @@ -109,7 +109,7 @@ namespace MediaBrowser.Api.UserLibrary return itemsList .SelectMany(i => i.Studios) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(name => LibraryManager.GetStudio(name)); } } diff --git a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs b/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs index 56921409ae..254f90376d 100644 --- a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs @@ -1,6 +1,5 @@ -using System; +using MediaBrowser.Controller.Library; using System.Collections.Generic; -using System.Linq; namespace MediaBrowser.Controller.Entities.Audio { @@ -20,11 +19,11 @@ namespace MediaBrowser.Controller.Entities.Audio { public static bool HasArtist(this IHasArtist hasArtist, string artist) { - return hasArtist.Artists.Contains(artist, StringComparer.OrdinalIgnoreCase); + return NameExtensions.EqualsAny(hasArtist.Artists, artist); } public static bool HasAnyArtist(this IHasArtist hasArtist, string artist) { - return hasArtist.AllArtists.Contains(artist, StringComparer.OrdinalIgnoreCase); + return NameExtensions.EqualsAny(hasArtist.AllArtists, artist); } } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index e0c14821e9..4185590ab3 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Querying; using MediaBrowser.Model.Users; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index c01814bce2..5e5735d34c 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -283,7 +283,7 @@ namespace MediaBrowser.Controller.Entities var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) .Where(i => !i.IsFolder) .SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(i => { try @@ -313,7 +313,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase)) .OfType() .SelectMany(i => i.AlbumArtists) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(i => { try @@ -337,7 +337,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => !i.IsFolder) .OfType() .SelectMany(i => i.AlbumArtists) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(i => { try @@ -361,7 +361,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => !i.IsFolder) .OfType() .SelectMany(i => i.Artists) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(i => { try @@ -385,7 +385,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => !i.IsFolder) .OfType() .SelectMany(i => i.AlbumArtists) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(i => { try @@ -552,7 +552,7 @@ namespace MediaBrowser.Controller.Entities var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }) .Where(i => i is Movie) .SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(i => { try @@ -724,7 +724,7 @@ namespace MediaBrowser.Controller.Entities var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }) .OfType() .SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(i => { try @@ -776,7 +776,7 @@ namespace MediaBrowser.Controller.Entities var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }) .OfType() .SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .Select(i => { try diff --git a/MediaBrowser.Controller/Library/NameExtensions.cs b/MediaBrowser.Controller/Library/NameExtensions.cs new file mode 100644 index 0000000000..b2acdc7ea5 --- /dev/null +++ b/MediaBrowser.Controller/Library/NameExtensions.cs @@ -0,0 +1,41 @@ +using MediaBrowser.Common.Extensions; +using MoreLinq; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Controller.Library +{ + public static class NameExtensions + { + public static bool AreEqual(string name1, string name2) + { + name1 = NormalizeForComparison(name1); + name2 = NormalizeForComparison(name2); + + return string.Equals(name1, name2, StringComparison.OrdinalIgnoreCase); + } + + public static bool EqualsAny(IEnumerable names, string name) + { + name = NormalizeForComparison(name); + + return names.Any(i => string.Equals(NormalizeForComparison(i), name, StringComparison.OrdinalIgnoreCase)); + } + + private static string NormalizeForComparison(string name) + { + if (string.IsNullOrWhiteSpace(name)) + { + return string.Empty; + } + + return name.RemoveDiacritics(); + } + + public static IEnumerable DistinctNames(this IEnumerable names) + { + return names.DistinctBy(NormalizeForComparison, StringComparer.OrdinalIgnoreCase); + } + } +} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 37b108b446..ba0c266b23 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -186,6 +186,7 @@ + diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs index 2497cc1ec7..7905293717 100644 --- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs +++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs @@ -54,7 +54,7 @@ namespace MediaBrowser.Providers.Music var currentList = item.Genres.ToList(); item.Genres = taggedItems.SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .ToList(); if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index da3c0aa9c8..2e28f1a94e 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -926,10 +926,8 @@ namespace MediaBrowser.Server.Implementations.Library if (isArtist) { - var validFilename = _fileSystem.GetValidFilename(name).Trim(); - var existing = RootFolder - .GetRecursiveChildren(i => i is T && string.Equals(_fileSystem.GetValidFilename(i.Name).Trim(), validFilename, StringComparison.OrdinalIgnoreCase)) + .GetRecursiveChildren(i => i is T && NameExtensions.AreEqual(i.Name, name)) .Cast() .FirstOrDefault(); diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index 51cad7a35d..72bbefae45 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -122,7 +122,7 @@ namespace MediaBrowser.Server.Implementations.Library var artists = items.OfType