From 6c9274730bd2c024e96abfa32b97e0bd5ccda8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BCnktchen?= Date: Fri, 28 Jul 2017 18:15:31 +0200 Subject: [PATCH 1/3] Improve playback of RTSP streams Without those little changes, rtsp live tv streams get corrupted even when stream copying, but also with transcoding. It's already really bad for sd streams, but hd streams are just unwatchable. The whole picture consists of green blocks. Btw. this problem isn't new. It was already discussed in many posts at the time the Argus TV plugin was still alive. These changes have the potential to fix it there also. --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 42f0dda160..bd7bbb6fe2 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1551,6 +1551,11 @@ namespace MediaBrowser.Controller.MediaEncoding inputModifier += " " + GetFastSeekCommandLineParameter(state.BaseRequest); inputModifier = inputModifier.Trim(); + + if (state.InputProtocol == MediaProtocol.Rtsp) + { + inputModifier += " -rtsp_transport tcp"; + } if (!string.IsNullOrEmpty(state.InputAudioSync)) { @@ -1562,7 +1567,7 @@ namespace MediaBrowser.Controller.MediaEncoding inputModifier += " -vsync " + state.InputVideoSync; } - if (state.ReadInputAtNativeFramerate) + if (state.ReadInputAtNativeFramerate && state.InputProtocol != MediaProtocol.Rtsp) { inputModifier += " -re"; } From eb63e0d264d563b100a353c12859f226e9303910 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 7 Sep 2017 14:17:18 -0400 Subject: [PATCH 2/3] update image processor --- Emby.Drawing/ImageProcessor.cs | 94 ++++++--- .../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 ++ .../Drawing/IImageProcessor.cs | 2 + .../Drawing/ImageProcessingOptions.cs | 8 +- .../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 diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 1d3f4a8e39..9e941b38c7 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 b3268b156b..673798294c 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 165d17a570..a07b79e109 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 ef1d7ba445..d078a31c9b 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 a0bbd171f8..b57662e311 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 75a9d85886..719510fc39 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 0000000000..4590369fab --- /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 69d4a4ab45..f8481517db 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 fb48f65e4b..5919c50d48 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 113f823f5f..d7b68d1e7e 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 fac21c7445..26283b5eae 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 900e8a6646..bd8d9024d4 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 a993f536d9..90f7296c65 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 10c6a05c0f..a5ec0f26c9 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; } From 6392f5e141b9971f7d69cc74e08118889d6d5580 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 7 Sep 2017 14:17:43 -0400 Subject: [PATCH 3/3] 3.2.30.9 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 85588a9af8..07784a3f04 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.30.8")] +[assembly: AssemblyVersion("3.2.30.9")]