From 78165d78a23c4f8f05706619c5021754e99097f6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 2 Sep 2017 22:42:13 -0400 Subject: update SocketHttpListener --- Emby.Server.Implementations/Emby.Server.Implementations.csproj | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations/Emby.Server.Implementations.csproj') diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 84ec214c9..75a9d8588 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -440,7 +440,6 @@ - -- cgit v1.2.3 From eb63e0d264d563b100a353c12859f226e9303910 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 7 Sep 2017 14:17:18 -0400 Subject: update image processor --- Emby.Drawing/ImageProcessor.cs | 94 +++++++---- Emby.Server.Implementations/ApplicationHost.cs | 4 +- .../Data/SqliteItemRepository.cs | 2 +- .../Data/SqliteUserDataRepository.cs | 2 +- Emby.Server.Implementations/Dto/DtoService.cs | 3 +- .../Emby.Server.Implementations.csproj | 1 + .../Services/SwaggerService.cs | 183 +++++++++++++++++++++ MediaBrowser.Api/Images/ImageService.cs | 47 +----- MediaBrowser.Api/UserLibrary/ItemsService.cs | 14 ++ MediaBrowser.Controller/Drawing/IImageProcessor.cs | 2 + .../Drawing/ImageProcessingOptions.cs | 8 +- MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 28 ++++ .../Providers/IImageEnhancer.cs | 7 + MediaBrowser.Model/Dlna/StreamBuilder.cs | 122 ++++++++++++-- 14 files changed, 428 insertions(+), 89 deletions(-) create mode 100644 Emby.Server.Implementations/Services/SwaggerService.cs (limited to 'Emby.Server.Implementations/Emby.Server.Implementations.csproj') diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 1d3f4a8e3..9e941b38c 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -203,10 +203,9 @@ namespace Emby.Drawing } private static readonly string[] TransparentImageTypes = new string[] { ".png", ".webp" }; - private bool SupportsTransparency(string path) + public bool SupportsTransparency(string path) { return TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty); - ; } public async Task> ProcessImage(ImageProcessingOptions options) @@ -239,6 +238,7 @@ namespace Emby.Drawing var supportedImageInfo = await GetSupportedImage(originalImagePath, dateModified).ConfigureAwait(false); originalImagePath = supportedImageInfo.Item1; dateModified = supportedImageInfo.Item2; + var requiresTransparency = TransparentImageTypes.Contains(Path.GetExtension(originalImagePath) ?? string.Empty); if (options.Enhancers.Count > 0) { @@ -253,10 +253,11 @@ namespace Emby.Drawing Type = originalImage.Type, Path = originalImagePath - }, item, options.ImageIndex, options.Enhancers).ConfigureAwait(false); + }, requiresTransparency, item, options.ImageIndex, options.Enhancers).ConfigureAwait(false); originalImagePath = tuple.Item1; dateModified = tuple.Item2; + requiresTransparency = tuple.Item3; } var photo = item as Photo; @@ -268,7 +269,7 @@ namespace Emby.Drawing orientation = photo.Orientation; } - if (options.HasDefaultOptions(originalImagePath) && !autoOrient) + if (options.HasDefaultOptions(originalImagePath) && (!autoOrient || !options.RequiresAutoOrientation)) { // Just spit out the original file if all the options are default return new Tuple(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); @@ -285,7 +286,7 @@ namespace Emby.Drawing var newSize = ImageHelper.GetNewImageSize(options, originalImageSize); var quality = options.Quality; - var outputFormat = GetOutputFormat(options.SupportedOutputFormats[0]); + var outputFormat = GetOutputFormat(options.SupportedOutputFormats, requiresTransparency); var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.Blur, options.BackgroundColor, options.ForegroundLayer); try @@ -336,6 +337,34 @@ namespace Emby.Drawing } } + private ImageFormat GetOutputFormat(ImageFormat[] clientSupportedFormats, bool requiresTransparency) + { + var serverFormats = GetSupportedImageOutputFormats(); + + // Client doesn't care about format, so start with webp if supported + if (serverFormats.Contains(ImageFormat.Webp) && clientSupportedFormats.Contains(ImageFormat.Webp)) + { + return ImageFormat.Webp; + } + + // If transparency is needed and webp isn't supported, than png is the only option + if (requiresTransparency) + { + return ImageFormat.Png; + } + + foreach (var format in clientSupportedFormats) + { + if (serverFormats.Contains(format)) + { + return format; + } + } + + // We should never actually get here + return ImageFormat.Jpg; + } + private void CopyFile(string src, string destination) { try @@ -389,21 +418,6 @@ namespace Emby.Drawing return MimeTypes.GetMimeType(path); } - private ImageFormat GetOutputFormat(ImageFormat requestedFormat) - { - if (requestedFormat == ImageFormat.Webp && !_imageEncoder.SupportedOutputFormats.Contains(ImageFormat.Webp)) - { - return ImageFormat.Png; - } - - return requestedFormat; - } - - private Tuple GetResult(string path) - { - return new Tuple(path, _fileSystem.GetLastWriteTimeUtc(path)); - } - /// /// Increment this when there's a change requiring caches to be invalidated /// @@ -753,12 +767,15 @@ namespace Emby.Drawing var imageInfo = item.GetImageInfo(imageType, imageIndex); - var result = await GetEnhancedImage(imageInfo, item, imageIndex, enhancers); + var inputImageSupportsTransparency = SupportsTransparency(imageInfo.Path); + + var result = await GetEnhancedImage(imageInfo, inputImageSupportsTransparency, item, imageIndex, enhancers); return result.Item1; } - private async Task> GetEnhancedImage(ItemImageInfo image, + private async Task> GetEnhancedImage(ItemImageInfo image, + bool inputImageSupportsTransparency, IHasMetadata item, int imageIndex, List enhancers) @@ -772,12 +789,16 @@ namespace Emby.Drawing var cacheGuid = GetImageCacheTag(item, image, enhancers); // Enhance if we have enhancers - var ehnancedImagePath = await GetEnhancedImageInternal(originalImagePath, item, imageType, imageIndex, enhancers, cacheGuid).ConfigureAwait(false); + var ehnancedImageInfo = await GetEnhancedImageInternal(originalImagePath, item, imageType, imageIndex, enhancers, cacheGuid).ConfigureAwait(false); + + var ehnancedImagePath = ehnancedImageInfo.Item1; // If the path changed update dateModified if (!string.Equals(ehnancedImagePath, originalImagePath, StringComparison.OrdinalIgnoreCase)) { - return GetResult(ehnancedImagePath); + var treatmentRequiresTransparency = ehnancedImageInfo.Item2; + + return new Tuple(ehnancedImagePath, _fileSystem.GetLastWriteTimeUtc(ehnancedImagePath), treatmentRequiresTransparency); } } catch (Exception ex) @@ -785,7 +806,7 @@ namespace Emby.Drawing _logger.Error("Error enhancing image", ex); } - return new Tuple(originalImagePath, dateModified); + return new Tuple(originalImagePath, dateModified, inputImageSupportsTransparency); } /// @@ -803,11 +824,11 @@ namespace Emby.Drawing /// or /// item /// - private async Task GetEnhancedImageInternal(string originalImagePath, + private async Task> GetEnhancedImageInternal(string originalImagePath, IHasMetadata item, ImageType imageType, int imageIndex, - IEnumerable supportedEnhancers, + List supportedEnhancers, string cacheGuid) { if (string.IsNullOrEmpty(originalImagePath)) @@ -820,13 +841,26 @@ namespace Emby.Drawing throw new ArgumentNullException("item"); } + var treatmentRequiresTransparency = false; + foreach (var enhancer in supportedEnhancers) + { + if (!treatmentRequiresTransparency) + { + treatmentRequiresTransparency = enhancer.GetEnhancedImageInfo(item, originalImagePath, imageType, imageIndex).RequiresTransparency; + } + } + // All enhanced images are saved as png to allow transparency - var enhancedImagePath = GetCachePath(EnhancedImageCachePath, cacheGuid + ".png"); + var cacheExtension = _imageEncoder.SupportedOutputFormats.Contains(ImageFormat.Webp) ? + ".webp" : + (treatmentRequiresTransparency ? ".png" : ".jpg"); + + var enhancedImagePath = GetCachePath(EnhancedImageCachePath, cacheGuid + cacheExtension); // Check again in case of contention if (_fileSystem.FileExists(enhancedImagePath)) { - return enhancedImagePath; + return new Tuple(enhancedImagePath, treatmentRequiresTransparency); } _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(enhancedImagePath)); @@ -845,7 +879,7 @@ namespace Emby.Drawing } - return tmpPath; + return new Tuple(tmpPath, treatmentRequiresTransparency); } /// diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index b3268b156..673798294 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1861,7 +1861,9 @@ namespace Emby.Server.Implementations { "mbplus.dll", "mbintros.dll", - "embytv.dll" + "embytv.dll", + "Messenger.dll", + "MediaBrowser.Plugins.TvMazeProvider.dll" }; return !exclude.Contains(filename ?? string.Empty, StringComparer.OrdinalIgnoreCase); diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 165d17a57..a07b79e10 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -114,7 +114,7 @@ namespace Emby.Server.Implementations.Data { get { - return true; + return false; } } diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs index ef1d7ba44..d078a31c9 100644 --- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs @@ -94,7 +94,7 @@ namespace Emby.Server.Implementations.Data { get { - return true; + return false; } } diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index a0bbd171f..b57662e31 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -275,8 +275,7 @@ namespace Emby.Server.Implementations.Dto { var hasFullSyncInfo = options.Fields.Contains(ItemFields.SyncInfo); - if (!options.Fields.Contains(ItemFields.BasicSyncInfo) && - !hasFullSyncInfo) + if (!hasFullSyncInfo && !options.Fields.Contains(ItemFields.BasicSyncInfo)) { return; } diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 75a9d8588..719510fc3 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -496,6 +496,7 @@ + diff --git a/Emby.Server.Implementations/Services/SwaggerService.cs b/Emby.Server.Implementations/Services/SwaggerService.cs new file mode 100644 index 000000000..4590369fa --- /dev/null +++ b/Emby.Server.Implementations/Services/SwaggerService.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MediaBrowser.Model.Services; + +namespace Emby.Server.Implementations.Services +{ + [Route("/swagger", "GET", Summary = "Gets the swagger specifications")] + [Route("/swagger.json", "GET", Summary = "Gets the swagger specifications")] + public class GetSwaggerSpec : IReturn + { + } + + public class SwaggerSpec + { + public string swagger { get; set; } + public string[] schemes { get; set; } + public SwaggerInfo info { get; set; } + public string host { get; set; } + public string basePath { get; set; } + public SwaggerTag[] tags { get; set; } + public Dictionary> paths { get; set; } + public Dictionary definitions { get; set; } + } + + public class SwaggerInfo + { + public string description { get; set; } + public string version { get; set; } + public string title { get; set; } + + public SwaggerConcactInfo contact { get; set; } + } + + public class SwaggerConcactInfo + { + public string email { get; set; } + } + + public class SwaggerTag + { + public string description { get; set; } + public string name { get; set; } + } + + public class SwaggerMethod + { + public string summary { get; set; } + public string description { get; set; } + public string[] tags { get; set; } + public string operationId { get; set; } + public string[] consumes { get; set; } + public string[] produces { get; set; } + public SwaggerParam[] parameters { get; set; } + public Dictionary responses { get; set; } + } + + public class SwaggerParam + { + public string @in { get; set; } + public string name { get; set; } + public string description { get; set; } + public bool required { get; set; } + public string type { get; set; } + public string collectionFormat { get; set; } + } + + public class SwaggerResponse + { + public string description { get; set; } + + // ex. "$ref":"#/definitions/Pet" + public Dictionary schema { get; set; } + } + + public class SwaggerDefinition + { + public string type { get; set; } + public Dictionary properties { get; set; } + } + + public class SwaggerProperty + { + public string type { get; set; } + public string format { get; set; } + public string description { get; set; } + public string[] @enum { get; set; } + public string @default { get; set; } + } + + public class SwaggerService : IService + { + private SwaggerSpec _spec; + + public object Get(GetSwaggerSpec request) + { + return _spec ?? (_spec = GetSpec()); + } + + private SwaggerSpec GetSpec() + { + var spec = new SwaggerSpec + { + schemes = new[] { "http" }, + tags = GetTags(), + swagger = "2.0", + info = new SwaggerInfo + { + title = "Emby Server API", + version = "1", + description = "Explore the Emby Server API", + contact = new SwaggerConcactInfo + { + email = "api@emby.media" + } + }, + paths = GetPaths(), + definitions = GetDefinitions() + }; + + return spec; + } + + + private SwaggerTag[] GetTags() + { + return new SwaggerTag[] { }; + } + + private Dictionary GetDefinitions() + { + return new Dictionary(); + } + + private Dictionary> GetPaths() + { + var paths = new Dictionary>(); + + var all = ServiceController.Instance.RestPathMap.ToList(); + + foreach (var current in all) + { + foreach (var info in current.Value) + { + paths[info.Path] = GetPathInfo(info); + } + } + + return paths; + } + + private Dictionary GetPathInfo(RestPath info) + { + var result = new Dictionary(); + + foreach (var verb in info.Verbs) + { + result[verb] = new SwaggerMethod + { + summary = info.Summary, + produces = new[] + { + "application/json", + "application/xml" + }, + consumes = new[] + { + "application/json", + "application/xml" + }, + operationId = info.RequestType.Name, + tags = new string[] { }, + + parameters = new SwaggerParam[] { } + }; + } + + return result; + } + } +} diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 69d4a4ab4..f8481517d 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -567,7 +567,7 @@ namespace MediaBrowser.Api.Images cropwhitespace = request.CropWhitespace.Value; } - var outputFormats = GetOutputFormats(request, imageInfo, cropwhitespace, supportedImageEnhancers); + var outputFormats = GetOutputFormats(request); TimeSpan? cacheDuration = null; @@ -597,7 +597,7 @@ namespace MediaBrowser.Api.Images ImageRequest request, ItemImageInfo image, bool cropwhitespace, - List supportedFormats, + ImageFormat[] supportedFormats, List enhancers, TimeSpan? cacheDuration, IDictionary headers, @@ -644,55 +644,18 @@ namespace MediaBrowser.Api.Images }).ConfigureAwait(false); } - private List GetOutputFormats(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List enhancers) + private ImageFormat[] GetOutputFormats(ImageRequest request) { if (!string.IsNullOrWhiteSpace(request.Format)) { ImageFormat format; if (Enum.TryParse(request.Format, true, out format)) { - return new List { format }; + return new ImageFormat[] { format }; } } - var extension = Path.GetExtension(image.Path); - ImageFormat? inputFormat = null; - - if (string.Equals(extension, ".jpg", StringComparison.OrdinalIgnoreCase) || - string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase)) - { - inputFormat = ImageFormat.Jpg; - } - else if (string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase)) - { - inputFormat = ImageFormat.Png; - } - - var clientSupportedFormats = GetClientSupportedFormats(); - - var serverFormats = _imageProcessor.GetSupportedImageOutputFormats(); - var outputFormats = new List(); - - // Client doesn't care about format, so start with webp if supported - if (serverFormats.Contains(ImageFormat.Webp) && clientSupportedFormats.Contains(ImageFormat.Webp)) - { - outputFormats.Add(ImageFormat.Webp); - } - - if (enhancers.Count > 0) - { - outputFormats.Add(ImageFormat.Png); - } - - if (inputFormat.HasValue && inputFormat.Value == ImageFormat.Jpg) - { - outputFormats.Add(ImageFormat.Jpg); - } - - // We can't predict if there will be transparency or not, so play it safe - outputFormats.Add(ImageFormat.Png); - - return outputFormats; + return GetClientSupportedFormats(); } private ImageFormat[] GetClientSupportedFormats() diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index fb48f65e4..5919c50d4 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -408,6 +408,20 @@ namespace MediaBrowser.Api.UserLibrary }).Where(i => i != null).Select(i => i.Id.ToString("N")).ToArray(); } + // Apply default sorting if none requested + if (query.OrderBy.Length == 0) + { + // Albums by artist + if (query.ArtistIds.Length > 0 && query.IncludeItemTypes.Length == 1 && string.Equals(query.IncludeItemTypes[0], "MusicAlbum", StringComparison.OrdinalIgnoreCase)) + { + query.OrderBy = new Tuple[] + { + new Tuple(ItemSortBy.ProductionYear, SortOrder.Descending), + new Tuple(ItemSortBy.SortName, SortOrder.Ascending) + }; + } + } + return query; } } diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index 113f823f5..d7b68d1e7 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -118,5 +118,7 @@ namespace MediaBrowser.Controller.Drawing IImageEncoder ImageEncoder { get; set; } void SaveImageSize(string path, DateTime imageDateModified, ImageSize size); + + bool SupportsTransparency(string path); } } diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs index fac21c744..26283b5ea 100644 --- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs +++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs @@ -10,6 +10,11 @@ namespace MediaBrowser.Controller.Drawing { public class ImageProcessingOptions { + public ImageProcessingOptions() + { + RequiresAutoOrientation = true; + } + public string ItemId { get; set; } public string ItemType { get; set; } public IHasMetadata Item { get; set; } @@ -32,7 +37,7 @@ namespace MediaBrowser.Controller.Drawing public List Enhancers { get; set; } - public List SupportedOutputFormats { get; set; } + public ImageFormat[] SupportedOutputFormats { get; set; } public bool AddPlayedIndicator { get; set; } @@ -43,6 +48,7 @@ namespace MediaBrowser.Controller.Drawing public string BackgroundColor { get; set; } public string ForegroundLayer { get; set; } + public bool RequiresAutoOrientation { get; set; } public bool HasDefaultOptions(string originalImagePath) { diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 900e8a664..bd8d9024d 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -80,15 +80,43 @@ namespace MediaBrowser.Controller.Entities.Movies protected override IEnumerable GetNonCachedChildren(IDirectoryService directoryService) { + if (IsLegacyBoxSet) + { + return base.GetNonCachedChildren(directoryService); + } return new List(); } protected override List LoadChildren() { + if (IsLegacyBoxSet) + { + return base.LoadChildren(); + } + // Save a trip to the database return new List(); } + [IgnoreDataMember] + private bool IsLegacyBoxSet + { + get + { + if (string.IsNullOrWhiteSpace(Path)) + { + return false; + } + + if (LinkedChildren.Length > 0) + { + return false; + } + + return !FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.DataPath, Path); + } + } + [IgnoreDataMember] public override bool IsPreSorted { diff --git a/MediaBrowser.Controller/Providers/IImageEnhancer.cs b/MediaBrowser.Controller/Providers/IImageEnhancer.cs index a993f536d..90f7296c6 100644 --- a/MediaBrowser.Controller/Providers/IImageEnhancer.cs +++ b/MediaBrowser.Controller/Providers/IImageEnhancer.cs @@ -39,6 +39,8 @@ namespace MediaBrowser.Controller.Providers /// ImageSize. ImageSize GetEnhancedImageSize(IHasMetadata item, ImageType imageType, int imageIndex, ImageSize originalImageSize); + EnhancedImageInfo GetEnhancedImageInfo(IHasMetadata item, string inputFile, ImageType imageType, int imageIndex); + /// /// Enhances the image async. /// @@ -51,4 +53,9 @@ namespace MediaBrowser.Controller.Providers /// Task EnhanceImageAsync(IHasMetadata item, string inputFile, string outputFile, ImageType imageType, int imageIndex); } + + public class EnhancedImageInfo + { + public bool RequiresTransparency { get; set; } + } } \ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 10c6a05c0..a5ec0f26c 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -849,8 +849,6 @@ namespace MediaBrowser.Model.Dlna } } } - ApplyTranscodingConditions(playlistItem, audioTranscodingConditions); - // Honor requested max channels if (options.MaxAudioChannels.HasValue) { @@ -878,6 +876,9 @@ namespace MediaBrowser.Model.Dlna var longBitrate = Math.Max(Math.Min(videoBitrate, currentValue), 64000); playlistItem.VideoBitrate = longBitrate > int.MaxValue ? int.MaxValue : Convert.ToInt32(longBitrate); } + + // Do this after initial values are set to account for greater than/less than conditions + ApplyTranscodingConditions(playlistItem, audioTranscodingConditions); } playlistItem.TranscodeReasons = transcodeReasons; @@ -1430,7 +1431,18 @@ namespace MediaBrowser.Model.Dlna int num; if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { - item.AudioBitrate = num; + if (condition.Condition == ProfileConditionType.Equals) + { + item.AudioBitrate = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.AudioBitrate = Math.Min(num, item.AudioBitrate ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.AudioBitrate = Math.Max(num, item.AudioBitrate ?? num); + } } break; } @@ -1439,7 +1451,18 @@ namespace MediaBrowser.Model.Dlna int num; if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { - item.MaxAudioChannels = num; + if (condition.Condition == ProfileConditionType.Equals) + { + item.MaxAudioChannels = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.MaxAudioChannels = Math.Min(num, item.MaxAudioChannels ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.MaxAudioChannels = Math.Max(num, item.MaxAudioChannels ?? num); + } } break; } @@ -1507,7 +1530,18 @@ namespace MediaBrowser.Model.Dlna int num; if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { - item.MaxRefFrames = num; + if (condition.Condition == ProfileConditionType.Equals) + { + item.MaxRefFrames = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.MaxRefFrames = Math.Min(num, item.MaxRefFrames ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.MaxRefFrames = Math.Max(num, item.MaxRefFrames ?? num); + } } break; } @@ -1516,7 +1550,18 @@ namespace MediaBrowser.Model.Dlna int num; if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { - item.MaxVideoBitDepth = num; + if (condition.Condition == ProfileConditionType.Equals) + { + item.MaxVideoBitDepth = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.MaxVideoBitDepth = Math.Min(num, item.MaxVideoBitDepth ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.MaxVideoBitDepth = Math.Max(num, item.MaxVideoBitDepth ?? num); + } } break; } @@ -1530,7 +1575,18 @@ namespace MediaBrowser.Model.Dlna int num; if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { - item.MaxHeight = num; + if (condition.Condition == ProfileConditionType.Equals) + { + item.MaxHeight = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.MaxHeight = Math.Min(num, item.MaxHeight ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.MaxHeight = Math.Max(num, item.MaxHeight ?? num); + } } break; } @@ -1539,7 +1595,18 @@ namespace MediaBrowser.Model.Dlna int num; if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { - item.VideoBitrate = num; + if (condition.Condition == ProfileConditionType.Equals) + { + item.VideoBitrate = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.VideoBitrate = Math.Min(num, item.VideoBitrate ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.VideoBitrate = Math.Max(num, item.VideoBitrate ?? num); + } } break; } @@ -1548,7 +1615,18 @@ namespace MediaBrowser.Model.Dlna float num; if (float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { - item.MaxFramerate = num; + if (condition.Condition == ProfileConditionType.Equals) + { + item.MaxFramerate = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.MaxFramerate = Math.Min(num, item.MaxFramerate ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.MaxFramerate = Math.Max(num, item.MaxFramerate ?? num); + } } break; } @@ -1557,7 +1635,18 @@ namespace MediaBrowser.Model.Dlna int num; if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { - item.VideoLevel = num; + if (condition.Condition == ProfileConditionType.Equals) + { + item.VideoLevel = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.VideoLevel = Math.Min(num, item.VideoLevel ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.VideoLevel = Math.Max(num, item.VideoLevel ?? num); + } } break; } @@ -1566,7 +1655,18 @@ namespace MediaBrowser.Model.Dlna int num; if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { - item.MaxWidth = num; + if (condition.Condition == ProfileConditionType.Equals) + { + item.MaxWidth = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.MaxWidth = Math.Min(num, item.MaxWidth ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.MaxWidth = Math.Max(num, item.MaxWidth ?? num); + } } break; } -- cgit v1.2.3 From 9a5a6f569deee21931f26c03a72b0ea0340639f5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 9 Sep 2017 14:21:21 -0400 Subject: removed dead code --- .../Emby.Server.Implementations.csproj | 1 - .../IO/AsyncStreamCopier.cs | 459 --------------------- .../TunerHosts/HdHomerun/HdHomerunHttpStream.cs | 51 --- .../TunerHosts/HdHomerun/HdHomerunUdpStream.cs | 27 +- 4 files changed, 2 insertions(+), 536 deletions(-) delete mode 100644 Emby.Server.Implementations/IO/AsyncStreamCopier.cs (limited to 'Emby.Server.Implementations/Emby.Server.Implementations.csproj') diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 719510fc3..bcda149d6 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -129,7 +129,6 @@ - diff --git a/Emby.Server.Implementations/IO/AsyncStreamCopier.cs b/Emby.Server.Implementations/IO/AsyncStreamCopier.cs deleted file mode 100644 index 9e5ce0604..000000000 --- a/Emby.Server.Implementations/IO/AsyncStreamCopier.cs +++ /dev/null @@ -1,459 +0,0 @@ -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Emby.Server.Implementations.IO -{ - public class AsyncStreamCopier : IDisposable - { - // size in bytes of the buffers in the buffer pool - private const int DefaultBufferSize = 81920; - private readonly int _bufferSize; - // number of buffers in the pool - private const int DefaultBufferCount = 4; - private readonly int _bufferCount; - - // indexes of the next buffer to read into/write from - private int _nextReadBuffer = -1; - private int _nextWriteBuffer = -1; - - // the buffer pool, implemented as an array, and used in a cyclic way - private readonly byte[][] _buffers; - // sizes in bytes of the available (read) data in the buffers - private readonly int[] _sizes; - // the streams... - private Stream _source; - private Stream _target; - private readonly bool _closeStreamsOnEnd; - - // number of buffers that are ready to be written - private int _buffersToWrite; - // flag indicating that there is still a read operation to be scheduled - // (source end of stream not reached) - private volatile bool _moreDataToRead; - // the result of the whole operation, returned by BeginCopy() - private AsyncResult _asyncResult; - // any exception that occurs during an async operation - // stored here for rethrow - private Exception _exception; - - public TaskCompletionSource TaskCompletionSource; - private long _bytesToRead; - private long _totalBytesWritten; - private CancellationToken _cancellationToken; - public int IndividualReadOffset = 0; - - public AsyncStreamCopier(Stream source, - Stream target, - long bytesToRead, - CancellationToken cancellationToken, - bool closeStreamsOnEnd = false, - int bufferSize = DefaultBufferSize, - int bufferCount = DefaultBufferCount) - { - if (source == null) - throw new ArgumentNullException("source"); - if (target == null) - throw new ArgumentNullException("target"); - if (!source.CanRead) - throw new ArgumentException("Cannot copy from a non-readable stream."); - if (!target.CanWrite) - throw new ArgumentException("Cannot copy to a non-writable stream."); - _source = source; - _target = target; - _moreDataToRead = true; - _closeStreamsOnEnd = closeStreamsOnEnd; - _bufferSize = bufferSize; - _bufferCount = bufferCount; - _buffers = new byte[_bufferCount][]; - _sizes = new int[_bufferCount]; - _bytesToRead = bytesToRead; - _cancellationToken = cancellationToken; - } - - ~AsyncStreamCopier() - { - // ensure any exception cannot be ignored - ThrowExceptionIfNeeded(); - } - - public static Task CopyStream(Stream source, Stream target, int bufferSize, int bufferCount, CancellationToken cancellationToken) - { - return CopyStream(source, target, 0, bufferSize, bufferCount, cancellationToken); - } - - public static Task CopyStream(Stream source, Stream target, long size, int bufferSize, int bufferCount, CancellationToken cancellationToken) - { - var copier = new AsyncStreamCopier(source, target, size, cancellationToken, false, bufferSize, bufferCount); - var taskCompletion = new TaskCompletionSource(); - - copier.TaskCompletionSource = taskCompletion; - - var result = copier.BeginCopy(StreamCopyCallback, copier); - - if (result.CompletedSynchronously) - { - StreamCopyCallback(result); - } - - cancellationToken.Register(() => taskCompletion.TrySetCanceled()); - - return taskCompletion.Task; - } - - private static void StreamCopyCallback(IAsyncResult result) - { - var copier = (AsyncStreamCopier)result.AsyncState; - var taskCompletion = copier.TaskCompletionSource; - - try - { - copier.EndCopy(result); - taskCompletion.TrySetResult(copier._totalBytesWritten); - } - catch (Exception ex) - { - taskCompletion.TrySetException(ex); - } - } - - public void Dispose() - { - if (_asyncResult != null) - _asyncResult.Dispose(); - if (_closeStreamsOnEnd) - { - if (_source != null) - { - _source.Dispose(); - _source = null; - } - if (_target != null) - { - _target.Dispose(); - _target = null; - } - } - GC.SuppressFinalize(this); - ThrowExceptionIfNeeded(); - } - - public IAsyncResult BeginCopy(AsyncCallback callback, object state) - { - // avoid concurrent start of the copy on separate threads - if (Interlocked.CompareExchange(ref _asyncResult, new AsyncResult(callback, state), null) != null) - throw new InvalidOperationException("A copy operation has already been started on this object."); - // allocate buffers - for (int i = 0; i < _bufferCount; i++) - _buffers[i] = new byte[_bufferSize]; - - // we pass false to BeginRead() to avoid completing the async result - // immediately which would result in invoking the callback - // when the method fails synchronously - BeginRead(false); - // throw exception synchronously if there is one - ThrowExceptionIfNeeded(); - return _asyncResult; - } - - public void EndCopy(IAsyncResult ar) - { - if (ar != _asyncResult) - throw new InvalidOperationException("Invalid IAsyncResult object."); - - if (!_asyncResult.IsCompleted) - _asyncResult.AsyncWaitHandle.WaitOne(); - - if (_closeStreamsOnEnd) - { - _source.Close(); - _source = null; - _target.Close(); - _target = null; - } - - //_logger.Info("AsyncStreamCopier {0} bytes requested. {1} bytes transferred", _bytesToRead, _totalBytesWritten); - ThrowExceptionIfNeeded(); - } - - /// - /// Here we'll throw a pending exception if there is one, - /// and remove it from our instance, so we know it has been consumed. - /// - private void ThrowExceptionIfNeeded() - { - if (_exception != null) - { - var exception = _exception; - _exception = null; - throw exception; - } - } - - private void BeginRead(bool completeOnError = true) - { - if (!_moreDataToRead) - { - return; - } - if (_asyncResult.IsCompleted) - return; - int bufferIndex = Interlocked.Increment(ref _nextReadBuffer) % _bufferCount; - - try - { - _source.BeginRead(_buffers[bufferIndex], 0, _bufferSize, EndRead, bufferIndex); - } - catch (Exception exception) - { - _exception = exception; - if (completeOnError) - _asyncResult.Complete(false); - } - } - - private void BeginWrite() - { - if (_asyncResult.IsCompleted) - return; - // this method can actually be called concurrently!! - // indeed, let's say we call a BeginWrite, and the thread gets interrupted - // just after making the IO request. - // At that moment, the thread is still in the method. And then the IO request - // ends (extremely fast io, or caching...), EndWrite gets called - // on another thread, and calls BeginWrite again! There we have it! - // That is the reason why an Interlocked is needed here. - int bufferIndex = Interlocked.Increment(ref _nextWriteBuffer) % _bufferCount; - - try - { - int bytesToWrite; - if (_bytesToRead > 0) - { - var bytesLeftToWrite = _bytesToRead - _totalBytesWritten; - bytesToWrite = Convert.ToInt32(Math.Min(_sizes[bufferIndex], bytesLeftToWrite)); - } - else - { - bytesToWrite = _sizes[bufferIndex]; - } - - _target.BeginWrite(_buffers[bufferIndex], IndividualReadOffset, bytesToWrite - IndividualReadOffset, EndWrite, null); - - _totalBytesWritten += bytesToWrite; - } - catch (Exception exception) - { - _exception = exception; - _asyncResult.Complete(false); - } - } - - private void EndRead(IAsyncResult ar) - { - try - { - int read = _source.EndRead(ar); - _moreDataToRead = read > 0; - var bufferIndex = (int)ar.AsyncState; - _sizes[bufferIndex] = read; - } - catch (Exception exception) - { - _exception = exception; - _asyncResult.Complete(false); - return; - } - - if (_moreDataToRead && !_cancellationToken.IsCancellationRequested) - { - int usedBuffers = Interlocked.Increment(ref _buffersToWrite); - // if we incremented from zero to one, then it means we just - // added the single buffer to write, so a writer could not - // be busy, and we have to schedule one. - if (usedBuffers == 1) - BeginWrite(); - // test if there is at least a free buffer, and schedule - // a read, as we have read some data - if (usedBuffers < _bufferCount) - BeginRead(); - } - else - { - // we did not add a buffer, because no data was read, and - // there is no buffer left to write so this is the end... - if (Thread.VolatileRead(ref _buffersToWrite) == 0) - { - _asyncResult.Complete(false); - } - } - } - - private void EndWrite(IAsyncResult ar) - { - try - { - _target.EndWrite(ar); - } - catch (Exception exception) - { - _exception = exception; - _asyncResult.Complete(false); - return; - } - - int buffersLeftToWrite = Interlocked.Decrement(ref _buffersToWrite); - // no reader could be active if all buffers were full of data waiting to be written - bool noReaderIsBusy = buffersLeftToWrite == _bufferCount - 1; - // note that it is possible that both a reader and - // a writer see the end of the copy and call Complete - // on the _asyncResult object. That race condition is handled by - // Complete that ensures it is only executed fully once. - - long bytesLeftToWrite; - if (_bytesToRead > 0) - { - bytesLeftToWrite = _bytesToRead - _totalBytesWritten; - } - else - { - bytesLeftToWrite = 1; - } - - if (!_moreDataToRead || bytesLeftToWrite <= 0 || _cancellationToken.IsCancellationRequested) - { - // at this point we know no reader can schedule a read or write - if (Thread.VolatileRead(ref _buffersToWrite) == 0) - { - // nothing left to write, so it is the end - _asyncResult.Complete(false); - return; - } - } - else - // here, we know we have something left to read, - // so schedule a read if no read is busy - if (noReaderIsBusy) - BeginRead(); - - // also schedule a write if we are sure we did not write the last buffer - // note that if buffersLeftToWrite is zero and a reader has put another - // buffer to write between the time we decremented _buffersToWrite - // and now, that reader will also schedule another write, - // as it will increment _buffersToWrite from zero to one - if (buffersLeftToWrite > 0) - BeginWrite(); - } - } - - internal class AsyncResult : IAsyncResult, IDisposable - { - // Fields set at construction which never change while - // operation is pending - private readonly AsyncCallback _asyncCallback; - private readonly object _asyncState; - - // Fields set at construction which do change after - // operation completes - private const int StatePending = 0; - private const int StateCompletedSynchronously = 1; - private const int StateCompletedAsynchronously = 2; - private int _completedState = StatePending; - - // Field that may or may not get set depending on usage - private ManualResetEvent _waitHandle; - - internal AsyncResult( - AsyncCallback asyncCallback, - object state) - { - _asyncCallback = asyncCallback; - _asyncState = state; - } - - internal bool Complete(bool completedSynchronously) - { - bool result = false; - - // The _completedState field MUST be set prior calling the callback - int prevState = Interlocked.CompareExchange(ref _completedState, - completedSynchronously ? StateCompletedSynchronously : - StateCompletedAsynchronously, StatePending); - if (prevState == StatePending) - { - // If the event exists, set it - if (_waitHandle != null) - _waitHandle.Set(); - - if (_asyncCallback != null) - _asyncCallback(this); - - result = true; - } - - return result; - } - - #region Implementation of IAsyncResult - - public Object AsyncState { get { return _asyncState; } } - - public bool CompletedSynchronously - { - get - { - return Thread.VolatileRead(ref _completedState) == - StateCompletedSynchronously; - } - } - - public WaitHandle AsyncWaitHandle - { - get - { - if (_waitHandle == null) - { - bool done = IsCompleted; - var mre = new ManualResetEvent(done); - if (Interlocked.CompareExchange(ref _waitHandle, - mre, null) != null) - { - // Another thread created this object's event; dispose - // the event we just created - mre.Close(); - } - else - { - if (!done && IsCompleted) - { - // If the operation wasn't done when we created - // the event but now it is done, set the event - _waitHandle.Set(); - } - } - } - return _waitHandle; - } - } - - public bool IsCompleted - { - get - { - return Thread.VolatileRead(ref _completedState) != - StatePending; - } - } - #endregion - - public void Dispose() - { - if (_waitHandle != null) - { - _waitHandle.Dispose(); - _waitHandle = null; - } - } - } -} diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs index d2e9c8bf0..84adf0cfc 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs @@ -158,58 +158,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun public Task CopyToAsync(Stream stream, CancellationToken cancellationToken) { - if (_enableFileBuffer) - { - return CopyFileTo(_tempFilePath, stream, cancellationToken); - } return _multicastStream.CopyToAsync(stream, cancellationToken); - //return CopyFileTo(_tempFilePath, stream, cancellationToken); - } - - protected async Task CopyFileTo(string path, Stream outputStream, CancellationToken cancellationToken) - { - long startPosition = -20000; - if (startPosition < 0) - { - var length = FileSystem.GetFileInfo(path).Length; - startPosition = Math.Max(length - startPosition, 0); - } - - _logger.Info("Live stream starting position is {0} bytes", startPosition.ToString(CultureInfo.InvariantCulture)); - - var allowAsync = Environment.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows; - // use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039 - - using (var inputStream = GetInputStream(path, startPosition, allowAsync)) - { - if (startPosition > 0) - { - inputStream.Position = startPosition; - } - - while (!cancellationToken.IsCancellationRequested) - { - long bytesRead; - - if (allowAsync) - { - bytesRead = await AsyncStreamCopier.CopyStream(inputStream, outputStream, 81920, 2, cancellationToken).ConfigureAwait(false); - } - else - { - StreamHelper.CopyTo(inputStream, outputStream, 81920, cancellationToken); - bytesRead = 1; - } - - //var position = fs.Position; - //_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path); - - if (bytesRead == 0) - { - await Task.Delay(100, cancellationToken).ConfigureAwait(false); - } - } - } } } } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index 5ad6e2e16..69fe59b4a 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -211,15 +211,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { long bytesRead; - if (allowAsync) - { - bytesRead = await AsyncStreamCopier.CopyStream(inputStream, outputStream, 81920, 2, cancellationToken).ConfigureAwait(false); - } - else - { - StreamHelper.CopyTo(inputStream, outputStream, 81920, cancellationToken); - bytesRead = 1; - } + StreamHelper.CopyTo(inputStream, outputStream, 81920, cancellationToken); + bytesRead = 1; //var position = fs.Position; //_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path); @@ -285,22 +278,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun //return taskCompletion.Task; } - private void StreamCopyCallback(IAsyncResult result) - { - var copier = (AsyncStreamCopier)result.AsyncState; - var taskCompletion = copier.TaskCompletionSource; - - try - { - copier.EndCopy(result); - taskCompletion.TrySetResult(0); - } - catch (Exception ex) - { - taskCompletion.TrySetException(ex); - } - } - public class UdpClientStream : Stream { private static int RtpHeaderBytes = 12; -- cgit v1.2.3 From b8834be83c4aaad7a47953f2d33be371d24095e8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 10 Sep 2017 16:40:31 -0400 Subject: update naming project to target .net standard --- Emby.Drawing/ImageProcessor.cs | 6 +++++ .../Emby.Server.Implementations.csproj | 7 +++--- .../Library/LibraryManager.cs | 27 +++++++++++----------- .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 4 ++-- .../Library/Resolvers/BaseVideoResolver.cs | 6 ++--- .../Library/Resolvers/Movies/MovieResolver.cs | 6 ++--- .../Library/Resolvers/TV/SeasonResolver.cs | 4 ++-- .../Library/Resolvers/TV/SeriesResolver.cs | 6 ++--- Emby.Server.Implementations/packages.config | 1 - 9 files changed, 35 insertions(+), 32 deletions(-) (limited to 'Emby.Server.Implementations/Emby.Server.Implementations.csproj') diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 9e941b38c..c519d4e21 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -724,6 +724,12 @@ namespace Emby.Drawing .TrimStart('.') .Replace("jpeg", "jpg", StringComparison.OrdinalIgnoreCase); + // These are just jpg files renamed as tbn + if (string.Equals(inputFormat, "tbn", StringComparison.OrdinalIgnoreCase)) + { + return new Tuple(originalImagePath, dateModified); + } + if (!_imageEncoder.SupportedInputFormats.Contains(inputFormat, StringComparer.OrdinalIgnoreCase)) { try diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index bcda149d6..ccff29eef 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -654,16 +654,15 @@ {1d74413b-e7cf-455b-b021-f52bdf881542} SocketHttpListener + + ..\ThirdParty\emby\Emby.Naming.dll + ..\ThirdParty\emby\Emby.Server.MediaEncoding.dll ..\packages\Emby.XmlTv.1.0.10\lib\portable-net45+netstandard2.0+win8\Emby.XmlTv.dll - - ..\packages\MediaBrowser.Naming.1.0.7\lib\portable-net45+netstandard2.0+win8\MediaBrowser.Naming.dll - True - ..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll True diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 510ecee76..139435faa 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -14,10 +14,10 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; -using MediaBrowser.Naming.Audio; -using MediaBrowser.Naming.Common; -using MediaBrowser.Naming.TV; -using MediaBrowser.Naming.Video; +using Emby.Naming.Audio; +using Emby.Naming.Common; +using Emby.Naming.TV; +using Emby.Naming.Video; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -38,7 +38,7 @@ using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Library; using MediaBrowser.Model.Net; using SortOrder = MediaBrowser.Model.Entities.SortOrder; -using VideoResolver = MediaBrowser.Naming.Video.VideoResolver; +using VideoResolver = Emby.Naming.Video.VideoResolver; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Dto; @@ -2346,7 +2346,7 @@ namespace Emby.Server.Implementations.Library public bool IsVideoFile(string path, LibraryOptions libraryOptions) { - var resolver = new VideoResolver(GetNamingOptions(), new NullLogger()); + var resolver = new VideoResolver(GetNamingOptions()); return resolver.IsVideoFile(path); } @@ -2373,8 +2373,7 @@ namespace Emby.Server.Implementations.Library public bool FillMissingEpisodeNumbersFromPath(Episode episode) { - var resolver = new EpisodeResolver(GetNamingOptions(), - new NullLogger()); + var resolver = new EpisodeResolver(GetNamingOptions()); var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd; @@ -2382,11 +2381,11 @@ namespace Emby.Server.Implementations.Library var episodeInfo = locationType == LocationType.FileSystem || locationType == LocationType.Offline ? resolver.Resolve(episode.Path, isFolder) : - new MediaBrowser.Naming.TV.EpisodeInfo(); + new Emby.Naming.TV.EpisodeInfo(); if (episodeInfo == null) { - episodeInfo = new MediaBrowser.Naming.TV.EpisodeInfo(); + episodeInfo = new Emby.Naming.TV.EpisodeInfo(); } var changed = false; @@ -2557,7 +2556,7 @@ namespace Emby.Server.Implementations.Library public ItemLookupInfo ParseName(string name) { - var resolver = new VideoResolver(GetNamingOptions(), new NullLogger()); + var resolver = new VideoResolver(GetNamingOptions()); var result = resolver.CleanDateTime(name); var cleanName = resolver.CleanString(result.Name); @@ -2578,7 +2577,7 @@ namespace Emby.Server.Implementations.Library .SelectMany(i => _fileSystem.GetFiles(i.FullName, _videoFileExtensions, false, false)) .ToList(); - var videoListResolver = new VideoListResolver(namingOptions, new NullLogger()); + var videoListResolver = new VideoListResolver(namingOptions); var videos = videoListResolver.Resolve(fileSystemChildren); @@ -2626,7 +2625,7 @@ namespace Emby.Server.Implementations.Library .SelectMany(i => _fileSystem.GetFiles(i.FullName, _videoFileExtensions, false, false)) .ToList(); - var videoListResolver = new VideoListResolver(namingOptions, new NullLogger()); + var videoListResolver = new VideoListResolver(namingOptions); var videos = videoListResolver.Resolve(fileSystemChildren); @@ -2752,7 +2751,7 @@ namespace Emby.Server.Implementations.Library private void SetExtraTypeFromFilename(Video item) { - var resolver = new ExtraResolver(GetNamingOptions(), new NullLogger(), new RegexProvider()); + var resolver = new ExtraResolver(GetNamingOptions(), new RegexProvider()); var result = resolver.GetExtraInfo(item.Path); diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 70fe8d9ef..b8ec41805 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -4,7 +4,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; -using MediaBrowser.Naming.Audio; +using Emby.Naming.Audio; using System; using System.Collections.Generic; using System.IO; @@ -165,7 +165,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio { var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); - var parser = new AlbumParser(namingOptions, new NullLogger()); + var parser = new AlbumParser(namingOptions); var result = parser.ParseMultiPart(path); return result.IsMultiPart; diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index fa4f026f4..e3200a099 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -1,7 +1,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; -using MediaBrowser.Naming.Video; +using Emby.Naming.Video; using System; using System.IO; using System.Linq; @@ -50,7 +50,7 @@ namespace Emby.Server.Implementations.Library.Resolvers var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions(); // If the path is a file check for a matching extensions - var parser = new MediaBrowser.Naming.Video.VideoResolver(namingOptions, new NullLogger()); + var parser = new Emby.Naming.Video.VideoResolver(namingOptions); if (args.IsDirectory) { @@ -258,7 +258,7 @@ namespace Emby.Server.Implementations.Library.Resolvers { var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions(); - var resolver = new Format3DParser(namingOptions, new NullLogger()); + var resolver = new Format3DParser(namingOptions); var result = resolver.Parse(video.Path); Set3DFormat(video, result.Is3D, result.Format3D); diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 1e5c0beed..cd1264754 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -6,7 +6,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; -using MediaBrowser.Naming.Video; +using Emby.Naming.Video; using System; using System.Collections.Generic; using System.IO; @@ -138,7 +138,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions(); - var resolver = new VideoListResolver(namingOptions, new NullLogger()); + var resolver = new VideoListResolver(namingOptions); var resolverResult = resolver.Resolve(files, suppportMultiEditions).ToList(); var result = new MultiItemResolverResult @@ -490,7 +490,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies } var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions(); - var resolver = new StackResolver(namingOptions, new NullLogger()); + var resolver = new StackResolver(namingOptions); var result = resolver.ResolveDirectories(folderPaths); diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs index 830bd9d85..bbe1bba85 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -3,8 +3,8 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Globalization; -using MediaBrowser.Naming.Common; -using MediaBrowser.Naming.TV; +using Emby.Naming.Common; +using Emby.Naming.TV; namespace Emby.Server.Implementations.Library.Resolvers.TV { diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index e1c18c913..9f982f9ce 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -4,8 +4,8 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; -using MediaBrowser.Naming.Common; -using MediaBrowser.Naming.TV; +using Emby.Naming.Common; +using Emby.Naming.TV; using System; using System.Collections.Generic; using System.IO; @@ -163,7 +163,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV var allowOptimisticEpisodeDetection = isTvContentType; var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions(allowOptimisticEpisodeDetection); - var episodeResolver = new MediaBrowser.Naming.TV.EpisodeResolver(namingOptions, new NullLogger()); + var episodeResolver = new Emby.Naming.TV.EpisodeResolver(namingOptions); var episodeInfo = episodeResolver.Resolve(fullName, false, false); if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue) { diff --git a/Emby.Server.Implementations/packages.config b/Emby.Server.Implementations/packages.config index 5b869221a..c27b8ac26 100644 --- a/Emby.Server.Implementations/packages.config +++ b/Emby.Server.Implementations/packages.config @@ -1,7 +1,6 @@  - -- cgit v1.2.3