From c9b88ab741baac47d21b00f1a877f788d81ac213 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 9 Jan 2019 23:33:17 +0100 Subject: [PATCH 01/19] Clean up streambuilder --- MediaBrowser.Model/Dlna/StreamBuilder.cs | 154 +++++++++-------------- 1 file changed, 61 insertions(+), 93 deletions(-) diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index ec05e2eb72..7a500d28ef 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -317,14 +317,14 @@ namespace MediaBrowser.Model.Dlna var conditionProcessor = new ConditionProcessor(); - int? inputAudioChannels = audioStream == null ? null : audioStream.Channels; - int? inputAudioBitrate = audioStream == null ? null : audioStream.BitDepth; - int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate; - int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth; + int? inputAudioChannels = audioStream?.Channels; + int? inputAudioBitrate = audioStream?.BitDepth; + int? inputAudioSampleRate = audioStream?.SampleRate; + int? inputAudioBitDepth = audioStream.BitDepth; - if (directPlayMethods.Count > 0) + if (directPlayMethods.Count() > 0) { - string audioCodec = audioStream == null ? null : audioStream.Codec; + string audioCodec = audioStream?.Codec; // Make sure audio codec profiles are satisfied var conditions = new List(); @@ -345,10 +345,7 @@ namespace MediaBrowser.Model.Dlna if (applyConditions) { - foreach (ProfileCondition c in i.Conditions) - { - conditions.Add(c); - } + conditions.AddRange(i.Conditions); } } } @@ -473,66 +470,57 @@ namespace MediaBrowser.Model.Dlna return options.GetMaxBitrate(isAudio); } - private Tuple, List> GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options) + private (IEnumerable, IEnumerable) GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options) { - var transcodeReasons = new List(); + DirectPlayProfile directPlayProfile = options.Profile.DirectPlayProfiles + .FirstOrDefault(x => x.Type == DlnaProfileType.Audio && IsAudioDirectPlaySupported(x, item, audioStream)); - DirectPlayProfile directPlayProfile = null; - foreach (var i in options.Profile.DirectPlayProfiles) + if (directPlayProfile == null) { - if (i.Type == DlnaProfileType.Audio && IsAudioDirectPlaySupported(i, item, audioStream)) - { - directPlayProfile = i; - break; - } - } - - var playMethods = new List(); - - if (directPlayProfile != null) - { - // While options takes the network and other factors into account. Only applies to direct stream - if (item.SupportsDirectStream) - { - if (IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true) ?? 0, PlayMethod.DirectStream)) - { - if (options.EnableDirectStream) - { - playMethods.Add(PlayMethod.DirectStream); - } - } - else - { - transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit); - } - } - - // The profile describes what the device supports - // If device requirements are satisfied then allow both direct stream and direct play - if (item.SupportsDirectPlay) - { - if (IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true) ?? 0, PlayMethod.DirectPlay)) - { - if (options.EnableDirectPlay) - { - playMethods.Add(PlayMethod.DirectPlay); - } - } - else - { - transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit); - } - } - } - else - { - transcodeReasons.InsertRange(0, GetTranscodeReasonsFromDirectPlayProfile(item, null, audioStream, options.Profile.DirectPlayProfiles)); - _logger.LogInformation("Profile: {0}, No direct play profiles found for Path: {1}", options.Profile.Name ?? "Unknown Profile", item.Path ?? "Unknown path"); + + return (Enumerable.Empty(), GetTranscodeReasonsFromDirectPlayProfile(item, null, audioStream, options.Profile.DirectPlayProfiles)); } + var playMethods = new List(); + var transcodeReasons = new List(); + + // While options takes the network and other factors into account. Only applies to direct stream + if (item.SupportsDirectStream) + { + if (IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true) ?? 0, PlayMethod.DirectStream)) + { + if (options.EnableDirectStream) + { + playMethods.Add(PlayMethod.DirectStream); + } + } + else + { + transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit); + } + } + + // The profile describes what the device supports + // If device requirements are satisfied then allow both direct stream and direct play + if (item.SupportsDirectPlay) + { + if (IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true) ?? 0, PlayMethod.DirectPlay)) + { + if (options.EnableDirectPlay) + { + playMethods.Add(PlayMethod.DirectPlay); + } + } + else + { + transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit); + } + } + + if (playMethods.Count > 0) { transcodeReasons.Clear(); @@ -542,41 +530,25 @@ namespace MediaBrowser.Model.Dlna transcodeReasons = transcodeReasons.Distinct().ToList(); } - return new Tuple, List>(playMethods, transcodeReasons); + return (playMethods, transcodeReasons); } private List GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable directPlayProfiles) { - var list = new List(); var containerSupported = false; var audioSupported = false; var videoSupported = false; foreach (var profile in directPlayProfiles) { - audioSupported = false; - videoSupported = false; - // Check container type if (profile.SupportsContainer(item.Container)) { containerSupported = true; - if (videoStream != null) - { - if (profile.SupportsVideoCodec(videoStream.Codec)) - { - videoSupported = true; - } - } + videoSupported = videoStream != null && profile.SupportsVideoCodec(videoStream.Codec); - if (audioStream != null) - { - if (profile.SupportsAudioCodec(audioStream.Codec)) - { - audioSupported = true; - } - } + audioSupported = audioStream != null && profile.SupportsAudioCodec(audioStream.Codec); if (videoSupported && audioSupported) { @@ -585,6 +557,7 @@ namespace MediaBrowser.Model.Dlna } } + var list = new List(); if (!containerSupported) { list.Add(TranscodeReason.ContainerNotSupported); @@ -1197,7 +1170,7 @@ namespace MediaBrowser.Model.Dlna mediaSource.Path ?? "Unknown path"); } - private ValueTuple IsEligibleForDirectPlay(MediaSourceInfo item, + private (bool directPlay, TranscodeReason? reason) IsEligibleForDirectPlay(MediaSourceInfo item, long maxBitrate, MediaStream subtitleStream, VideoOptions options, @@ -1210,18 +1183,13 @@ namespace MediaBrowser.Model.Dlna if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed) { _logger.LogInformation("Not eligible for {0} due to unsupported subtitles", playMethod); - return new ValueTuple(false, TranscodeReason.SubtitleCodecNotSupported); + return (false, TranscodeReason.SubtitleCodecNotSupported); } } - var result = IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod); + bool result = IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod); - if (result) - { - return new ValueTuple(result, null); - } - - return new ValueTuple(result, TranscodeReason.ContainerBitrateExceedsLimit); + return (result, result ? (TranscodeReason?)null : TranscodeReason.ContainerBitrateExceedsLimit); } public static SubtitleProfile GetSubtitleProfile(MediaSourceInfo mediaSource, MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, ITranscoderSupport transcoderSupport, string outputContainer, string transcodingSubProtocol) @@ -1391,12 +1359,12 @@ namespace MediaBrowser.Model.Dlna var requestedMaxBitrate = maxBitrate > 0 ? maxBitrate : 1000000; // If we don't know the bitrate, then force a transcode if requested max bitrate is under 40 mbps - var itemBitrate = item.Bitrate ?? - 40000000; + var itemBitrate = item.Bitrate ?? 40000000; if (itemBitrate > requestedMaxBitrate) { - _logger.LogInformation("Bitrate exceeds " + playMethod + " limit: media bitrate: {0}, max bitrate: {1}", itemBitrate.ToString(CultureInfo.InvariantCulture), requestedMaxBitrate.ToString(CultureInfo.InvariantCulture)); + _logger.LogInformation("Bitrate exceeds {PlayBackMethod} limit: media bitrate: {MediaBitrate}, max bitrate: {MaxBitrate}", + playMethod, itemBitrate, requestedMaxBitrate); return false; } From 37be6c87eb5b28eccc554be84e0cada303d2e50b Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 20 Jan 2019 11:34:33 +0100 Subject: [PATCH 02/19] Make ConditionProcessor static --- MediaBrowser.Model/Dlna/AudioOptions.cs | 24 +-- MediaBrowser.Model/Dlna/ConditionProcessor.cs | 24 +-- MediaBrowser.Model/Dlna/DeviceProfile.cs | 12 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 156 ++++++++---------- 4 files changed, 93 insertions(+), 123 deletions(-) diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs index 33e2982e93..6dfe8093e5 100644 --- a/MediaBrowser.Model/Dlna/AudioOptions.cs +++ b/MediaBrowser.Model/Dlna/AudioOptions.cs @@ -66,21 +66,21 @@ namespace MediaBrowser.Model.Dlna return MaxBitrate; } - if (Profile != null) + if (Profile == null) { - if (Context == EncodingContext.Static) - { - if (isAudio && Profile.MaxStaticMusicBitrate.HasValue) - { - return Profile.MaxStaticMusicBitrate; - } - return Profile.MaxStaticBitrate; - } - - return Profile.MaxStreamingBitrate; + return null; } - return null; + if (Context == EncodingContext.Static) + { + if (isAudio && Profile.MaxStaticMusicBitrate.HasValue) + { + return Profile.MaxStaticMusicBitrate; + } + return Profile.MaxStaticBitrate; + } + + return Profile.MaxStreamingBitrate; } } } diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs index dc0c5f1397..3629d15470 100644 --- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs +++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs @@ -5,9 +5,10 @@ using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Model.Dlna { - public class ConditionProcessor + public static class ConditionProcessor { - public bool IsVideoConditionSatisfied(ProfileCondition condition, + public static bool IsVideoConditionSatisfied( + ProfileCondition condition, int? width, int? height, int? videoBitDepth, @@ -64,7 +65,7 @@ namespace MediaBrowser.Model.Dlna } } - public bool IsImageConditionSatisfied(ProfileCondition condition, int? width, int? height) + public static bool IsImageConditionSatisfied(ProfileCondition condition, int? width, int? height) { switch (condition.Property) { @@ -77,7 +78,7 @@ namespace MediaBrowser.Model.Dlna } } - public bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth) + public static bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth) { switch (condition.Property) { @@ -94,7 +95,8 @@ namespace MediaBrowser.Model.Dlna } } - public bool IsVideoAudioConditionSatisfied(ProfileCondition condition, + public static bool IsVideoAudioConditionSatisfied( + ProfileCondition condition, int? audioChannels, int? audioBitrate, int? audioSampleRate, @@ -121,7 +123,7 @@ namespace MediaBrowser.Model.Dlna } } - private bool IsConditionSatisfied(ProfileCondition condition, int? currentValue) + private static bool IsConditionSatisfied(ProfileCondition condition, int? currentValue) { if (!currentValue.HasValue) { @@ -150,7 +152,7 @@ namespace MediaBrowser.Model.Dlna return false; } - private bool IsConditionSatisfied(ProfileCondition condition, string currentValue) + private static bool IsConditionSatisfied(ProfileCondition condition, string currentValue) { if (string.IsNullOrEmpty(currentValue)) { @@ -175,7 +177,7 @@ namespace MediaBrowser.Model.Dlna } } - private bool IsConditionSatisfied(ProfileCondition condition, bool? currentValue) + private static bool IsConditionSatisfied(ProfileCondition condition, bool? currentValue) { if (!currentValue.HasValue) { @@ -199,7 +201,7 @@ namespace MediaBrowser.Model.Dlna return false; } - private bool IsConditionSatisfied(ProfileCondition condition, float currentValue) + private static bool IsConditionSatisfied(ProfileCondition condition, float currentValue) { if (currentValue <= 0) { @@ -227,7 +229,7 @@ namespace MediaBrowser.Model.Dlna return false; } - private bool IsConditionSatisfied(ProfileCondition condition, double? currentValue) + private static bool IsConditionSatisfied(ProfileCondition condition, double? currentValue) { if (!currentValue.HasValue) { @@ -255,7 +257,7 @@ namespace MediaBrowser.Model.Dlna return false; } - private bool IsConditionSatisfied(ProfileCondition condition, TransportStreamTimestamp? timestamp) + private static bool IsConditionSatisfied(ProfileCondition condition, TransportStreamTimestamp? timestamp) { if (!timestamp.HasValue) { diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 6894f45edc..8d8fe9eb5b 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -188,12 +188,10 @@ namespace MediaBrowser.Model.Dlna continue; } - var conditionProcessor = new ConditionProcessor(); - var anyOff = false; foreach (ProfileCondition c in i.Conditions) { - if (!conditionProcessor.IsAudioConditionSatisfied(GetModelProfileCondition(c), audioChannels, audioBitrate, audioSampleRate, audioBitDepth)) + if (!ConditionProcessor.IsAudioConditionSatisfied(GetModelProfileCondition(c), audioChannels, audioBitrate, audioSampleRate, audioBitDepth)) { anyOff = true; break; @@ -235,12 +233,10 @@ namespace MediaBrowser.Model.Dlna continue; } - var conditionProcessor = new ConditionProcessor(); - var anyOff = false; foreach (var c in i.Conditions) { - if (!conditionProcessor.IsImageConditionSatisfied(GetModelProfileCondition(c), width, height)) + if (!ConditionProcessor.IsImageConditionSatisfied(GetModelProfileCondition(c), width, height)) { anyOff = true; break; @@ -301,12 +297,10 @@ namespace MediaBrowser.Model.Dlna continue; } - var conditionProcessor = new ConditionProcessor(); - var anyOff = false; foreach (ProfileCondition c in i.Conditions) { - if (!conditionProcessor.IsVideoConditionSatisfied(GetModelProfileCondition(c), width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) + if (!ConditionProcessor.IsVideoConditionSatisfied(GetModelProfileCondition(c), width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) { anyOff = true; break; diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 7a500d28ef..e61e600c22 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -93,19 +93,10 @@ namespace MediaBrowser.Model.Dlna return GetOptimalStream(streams, options.GetMaxBitrate(false) ?? 0); } - private StreamInfo GetOptimalStream(List streams, long maxBitrate) - { - var sorted = SortMediaSources(streams, maxBitrate); + private static StreamInfo GetOptimalStream(List streams, long maxBitrate) + => SortMediaSources(streams, maxBitrate).FirstOrDefault(); - foreach (StreamInfo stream in sorted) - { - return stream; - } - - return null; - } - - private StreamInfo[] SortMediaSources(List streams, long maxBitrate) + private static IOrderedEnumerable SortMediaSources(List streams, long maxBitrate) { return streams.OrderBy(i => { @@ -151,25 +142,21 @@ namespace MediaBrowser.Model.Dlna return 0; - }).ThenBy(streams.IndexOf).ToArray(); + }).ThenBy(streams.IndexOf); } - private TranscodeReason? GetTranscodeReasonForFailedCondition(ProfileCondition condition) + private static TranscodeReason? GetTranscodeReasonForFailedCondition(ProfileCondition condition) { switch (condition.Property) { - case ProfileConditionValue.AudioBitrate: - if (condition.Condition == ProfileConditionType.LessThanEqual) - { + case ProfileConditionValue.AudioBitrate when condition.Condition == ProfileConditionType.LessThanEqual: return TranscodeReason.AudioBitrateNotSupported; - } + case ProfileConditionValue.AudioBitrate: return TranscodeReason.AudioBitrateNotSupported; + case ProfileConditionValue.AudioChannels when condition.Condition == ProfileConditionType.LessThanEqual: + return TranscodeReason.AudioChannelsNotSupported; case ProfileConditionValue.AudioChannels: - if (condition.Condition == ProfileConditionType.LessThanEqual) - { - return TranscodeReason.AudioChannelsNotSupported; - } return TranscodeReason.AudioChannelsNotSupported; case ProfileConditionValue.AudioProfile: @@ -246,7 +233,7 @@ namespace MediaBrowser.Model.Dlna } } - public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, string unused1, DeviceProfile profile, DlnaProfileType type) + public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, string _, DeviceProfile profile, DlnaProfileType type) { if (string.IsNullOrEmpty(inputContainer)) { @@ -266,12 +253,10 @@ namespace MediaBrowser.Model.Dlna { foreach (var directPlayProfile in profile.DirectPlayProfiles) { - if (directPlayProfile.Type == type) + if (directPlayProfile.Type == type + && directPlayProfile.SupportsContainer(format)) { - if (directPlayProfile.SupportsContainer(format)) - { - return format; - } + return format; } } } @@ -282,9 +267,7 @@ namespace MediaBrowser.Model.Dlna private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options) { - var transcodeReasons = new List(); - - var playlistItem = new StreamInfo + StreamInfo playlistItem = new StreamInfo { ItemId = options.ItemId, MediaType = DlnaProfileType.Audio, @@ -313,9 +296,7 @@ namespace MediaBrowser.Model.Dlna var directPlayInfo = GetAudioDirectPlayMethods(item, audioStream, options); var directPlayMethods = directPlayInfo.Item1; - transcodeReasons.AddRange(directPlayInfo.Item2); - - var conditionProcessor = new ConditionProcessor(); + var transcodeReasons = directPlayInfo.Item2.ToList(); int? inputAudioChannels = audioStream?.Channels; int? inputAudioBitrate = audioStream?.BitDepth; @@ -335,7 +316,7 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) { - if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth)) + if (!ConditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth)) { LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item); applyConditions = false; @@ -353,7 +334,7 @@ namespace MediaBrowser.Model.Dlna bool all = true; foreach (ProfileCondition c in conditions) { - if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth)) + if (!ConditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth)) { LogConditionFailure(options.Profile, "AudioCodecProfile", c, item); var transcodeReason = GetTranscodeReasonForFailedCondition(c); @@ -382,13 +363,12 @@ namespace MediaBrowser.Model.Dlna TranscodingProfile transcodingProfile = null; foreach (var i in options.Profile.TranscodingProfiles) { - if (i.Type == playlistItem.MediaType && i.Context == options.Context) + if (i.Type == playlistItem.MediaType + && i.Context == options.Context + && _transcoderSupport.CanEncodeToAudioCodec(i.AudioCodec ?? i.Container)) { - if (_transcoderSupport.CanEncodeToAudioCodec(i.AudioCodec ?? i.Container)) - { - transcodingProfile = i; - break; - } + transcodingProfile = i; + break; } } @@ -418,7 +398,7 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (var applyCondition in i.ApplyConditions) { - if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth)) + if (!ConditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth)) { LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item); applyConditions = false; @@ -460,7 +440,7 @@ namespace MediaBrowser.Model.Dlna return playlistItem; } - private long? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options, bool isAudio) + private static long? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options, bool isAudio) { if (item.Protocol == MediaProtocol.File) { @@ -533,7 +513,7 @@ namespace MediaBrowser.Model.Dlna return (playMethods, transcodeReasons); } - private List GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable directPlayProfiles) + private static List GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable directPlayProfiles) { var containerSupported = false; var audioSupported = false; @@ -576,18 +556,17 @@ namespace MediaBrowser.Model.Dlna return list; } - private int? GetDefaultSubtitleStreamIndex(MediaSourceInfo item, SubtitleProfile[] subtitleProfiles) + private static int? GetDefaultSubtitleStreamIndex(MediaSourceInfo item, SubtitleProfile[] subtitleProfiles) { int highestScore = -1; foreach (var stream in item.MediaStreams) { - if (stream.Type == MediaStreamType.Subtitle && stream.Score.HasValue) + if (stream.Type == MediaStreamType.Subtitle + && stream.Score.HasValue + && stream.Score.Value > highestScore) { - if (stream.Score.Value > highestScore) - { - highestScore = stream.Score.Value; - } + highestScore = stream.Score.Value; } } @@ -619,7 +598,7 @@ namespace MediaBrowser.Model.Dlna return item.DefaultSubtitleStreamIndex; } - private void SetStreamInfoOptionsFromTranscodingProfile(StreamInfo playlistItem, TranscodingProfile transcodingProfile) + private static void SetStreamInfoOptionsFromTranscodingProfile(StreamInfo playlistItem, TranscodingProfile transcodingProfile) { if (string.IsNullOrEmpty(transcodingProfile.AudioCodec)) { @@ -659,12 +638,10 @@ namespace MediaBrowser.Model.Dlna } playlistItem.SubProtocol = transcodingProfile.Protocol; - if (!string.IsNullOrEmpty(transcodingProfile.MaxAudioChannels)) + if (!string.IsNullOrEmpty(transcodingProfile.MaxAudioChannels) + && int.TryParse(transcodingProfile.MaxAudioChannels, NumberStyles.Any, CultureInfo.InvariantCulture, out int transcodingMaxAudioChannels)) { - if (int.TryParse(transcodingProfile.MaxAudioChannels, NumberStyles.Any, CultureInfo.InvariantCulture, out var transcodingMaxAudioChannels)) - { - playlistItem.TranscodingMaxAudioChannels = transcodingMaxAudioChannels; - } + playlistItem.TranscodingMaxAudioChannels = transcodingMaxAudioChannels; } } @@ -675,9 +652,7 @@ namespace MediaBrowser.Model.Dlna throw new ArgumentNullException(nameof(item)); } - var transcodeReasons = new List(); - - var playlistItem = new StreamInfo + StreamInfo playlistItem = new StreamInfo { ItemId = options.ItemId, MediaType = DlnaProfileType.Video, @@ -710,6 +685,8 @@ namespace MediaBrowser.Model.Dlna isEligibleForDirectPlay, isEligibleForDirectStream); + var transcodeReasons = new List(); + if (isEligibleForDirectPlay || isEligibleForDirectStream) { // See if it can be direct played @@ -776,8 +753,6 @@ namespace MediaBrowser.Model.Dlna SetStreamInfoOptionsFromTranscodingProfile(playlistItem, transcodingProfile); - var conditionProcessor = new ConditionProcessor(); - var isFirstAppliedCodecProfile = true; foreach (var i in options.Profile.CodecProfiles) { @@ -805,7 +780,7 @@ namespace MediaBrowser.Model.Dlna int? numAudioStreams = item.GetStreamCount(MediaStreamType.Audio); int? numVideoStreams = item.GetStreamCount(MediaStreamType.Video); - if (!conditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) + if (!ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) { //LogConditionFailure(options.Profile, "VideoCodecProfile.ApplyConditions", applyCondition, item); applyConditions = false; @@ -849,7 +824,7 @@ namespace MediaBrowser.Model.Dlna int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate; int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth; - if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio)) + if (!ConditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio)) { //LogConditionFailure(options.Profile, "VideoCodecProfile.ApplyConditions", applyCondition, item); applyConditions = false; @@ -1016,29 +991,27 @@ namespace MediaBrowser.Model.Dlna } } - var conditionProcessor = new ConditionProcessor(); - - int? width = videoStream == null ? null : videoStream.Width; - int? height = videoStream == null ? null : videoStream.Height; - int? bitDepth = videoStream == null ? null : videoStream.BitDepth; - int? videoBitrate = videoStream == null ? null : videoStream.BitRate; - double? videoLevel = videoStream == null ? null : videoStream.Level; - string videoProfile = videoStream == null ? null : videoStream.Profile; + int? width = videoStream?.Width; + int? height = videoStream?.Height; + int? bitDepth = videoStream?.BitDepth; + int? videoBitrate = videoStream?.BitRate; + double? videoLevel = videoStream?.Level; + string videoProfile = videoStream?.Profile; float videoFramerate = videoStream == null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0; - bool? isAnamorphic = videoStream == null ? null : videoStream.IsAnamorphic; - bool? isInterlaced = videoStream == null ? (bool?)null : videoStream.IsInterlaced; - string videoCodecTag = videoStream == null ? null : videoStream.CodecTag; - bool? isAvc = videoStream == null ? null : videoStream.IsAVC; + bool? isAnamorphic = videoStream?.IsAnamorphic; + bool? isInterlaced = videoStream?.IsInterlaced; + string videoCodecTag = videoStream?.CodecTag; + bool? isAvc = videoStream?.IsAVC; - int? audioBitrate = audioStream == null ? null : audioStream.BitRate; - int? audioChannels = audioStream == null ? null : audioStream.Channels; - string audioProfile = audioStream == null ? null : audioStream.Profile; - int? audioSampleRate = audioStream == null ? null : audioStream.SampleRate; - int? audioBitDepth = audioStream == null ? null : audioStream.BitDepth; + int? audioBitrate = audioStream?.BitRate; + int? audioChannels = audioStream?.Channels; + string audioProfile = audioStream?.Profile; + int? audioSampleRate = audioStream?.SampleRate; + int? audioBitDepth = audioStream?.BitDepth; TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp; - int? packetLength = videoStream == null ? null : videoStream.PacketLength; - int? refFrames = videoStream == null ? null : videoStream.RefFrames; + int? packetLength = videoStream?.PacketLength; + int? refFrames = videoStream?.RefFrames; int? numAudioStreams = mediaSource.GetStreamCount(MediaStreamType.Audio); int? numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video); @@ -1046,7 +1019,7 @@ namespace MediaBrowser.Model.Dlna // Check container conditions foreach (ProfileCondition i in conditions) { - if (!conditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) + if (!ConditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) { LogConditionFailure(profile, "VideoContainerProfile", i, mediaSource); @@ -1069,7 +1042,7 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) { - if (!conditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) + if (!ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) { //LogConditionFailure(profile, "VideoCodecProfile.ApplyConditions", applyCondition, mediaSource); applyConditions = false; @@ -1089,14 +1062,14 @@ namespace MediaBrowser.Model.Dlna foreach (ProfileCondition i in conditions) { - if (!conditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) + if (!ConditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) { LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource); var transcodeReason = GetTranscodeReasonForFailedCondition(i); var transcodeReasons = transcodeReason.HasValue ? new List { transcodeReason.Value } - : new List { }; + : new List(); return new Tuple>(null, transcodeReasons); } @@ -1116,7 +1089,7 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) { - if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio)) + if (!ConditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio)) { //LogConditionFailure(profile, "VideoAudioCodecProfile.ApplyConditions", applyCondition, mediaSource); applyConditions = false; @@ -1136,14 +1109,14 @@ namespace MediaBrowser.Model.Dlna foreach (ProfileCondition i in conditions) { - if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio)) + if (!ConditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio)) { LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource); var transcodeReason = GetTranscodeReasonForFailedCondition(i); var transcodeReasons = transcodeReason.HasValue ? new List { transcodeReason.Value } - : new List { }; + : new List(); return new Tuple>(null, transcodeReasons); } @@ -1170,7 +1143,8 @@ namespace MediaBrowser.Model.Dlna mediaSource.Path ?? "Unknown path"); } - private (bool directPlay, TranscodeReason? reason) IsEligibleForDirectPlay(MediaSourceInfo item, + private (bool directPlay, TranscodeReason? reason) IsEligibleForDirectPlay( + MediaSourceInfo item, long maxBitrate, MediaStream subtitleStream, VideoOptions options, From 06d9423f00d7577c74ac6d0e0a14da02394b5885 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 20 Jan 2019 12:03:05 +0100 Subject: [PATCH 03/19] Clean up last bits --- MediaBrowser.Model/Dlna/StreamBuilder.cs | 169 ++++++++++------------- 1 file changed, 74 insertions(+), 95 deletions(-) diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index e61e600c22..8f0120a0d7 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -761,21 +761,21 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) { - int? width = videoStream == null ? null : videoStream.Width; - int? height = videoStream == null ? null : videoStream.Height; - int? bitDepth = videoStream == null ? null : videoStream.BitDepth; - int? videoBitrate = videoStream == null ? null : videoStream.BitRate; - double? videoLevel = videoStream == null ? null : videoStream.Level; - string videoProfile = videoStream == null ? null : videoStream.Profile; + int? width = videoStream?.Width; + int? height = videoStream?.Height; + int? bitDepth = videoStream?.BitDepth; + int? videoBitrate = videoStream?.BitRate; + double? videoLevel = videoStream?.Level; + string videoProfile = videoStream?.Profile; float videoFramerate = videoStream == null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0; - bool? isAnamorphic = videoStream == null ? null : videoStream.IsAnamorphic; - bool? isInterlaced = videoStream == null ? (bool?)null : videoStream.IsInterlaced; - string videoCodecTag = videoStream == null ? null : videoStream.CodecTag; - bool? isAvc = videoStream == null ? null : videoStream.IsAVC; + bool? isAnamorphic = videoStream?.IsAnamorphic; + bool? isInterlaced = videoStream?.IsInterlaced; + string videoCodecTag = videoStream?.CodecTag; + bool? isAvc = videoStream?.IsAVC; TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : item.Timestamp; - int? packetLength = videoStream == null ? null : videoStream.PacketLength; - int? refFrames = videoStream == null ? null : videoStream.RefFrames; + int? packetLength = videoStream?.PacketLength; + int? refFrames = videoStream?.RefFrames; int? numAudioStreams = item.GetStreamCount(MediaStreamType.Audio); int? numVideoStreams = item.GetStreamCount(MediaStreamType.Video); @@ -870,7 +870,7 @@ namespace MediaBrowser.Model.Dlna return playlistItem; } - private int GetDefaultAudioBitrateIfUnknown(MediaStream audioStream) + private static int GetDefaultAudioBitrateIfUnknown(MediaStream audioStream) { if ((audioStream.Channels ?? 0) >= 6) { @@ -880,33 +880,37 @@ namespace MediaBrowser.Model.Dlna return 192000; } - private int GetAudioBitrate(string subProtocol, long maxTotalBitrate, string[] targetAudioCodecs, MediaStream audioStream, StreamInfo item) + private static int GetAudioBitrate(string subProtocol, long maxTotalBitrate, string[] targetAudioCodecs, MediaStream audioStream, StreamInfo item) { - var targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0]; + string targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0]; - var targetAudioChannels = item.GetTargetAudioChannels(targetAudioCodec); - - int defaultBitrate = audioStream == null ? 192000 : audioStream.BitRate ?? GetDefaultAudioBitrateIfUnknown(audioStream); - - // Reduce the bitrate if we're downmixing - if (targetAudioChannels.HasValue && audioStream != null && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value) - { - defaultBitrate = targetAudioChannels.Value <= 2 ? 128000 : 192000; - } + int? targetAudioChannels = item.GetTargetAudioChannels(targetAudioCodec); + int defaultBitrate; int encoderAudioBitrateLimit = int.MaxValue; - if (audioStream != null) + if (audioStream == null) { + defaultBitrate = 192000; + } + else + { + if (targetAudioChannels.HasValue && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value) + { + // Reduce the bitrate if we're downmixing + defaultBitrate = targetAudioChannels.Value <= 2 ? 128000 : 192000; + } + else + { + defaultBitrate = audioStream.BitRate ?? GetDefaultAudioBitrateIfUnknown(audioStream); + } + // Seeing webm encoding failures when source has 1 audio channel and 22k bitrate. // Any attempts to transcode over 64k will fail - if (audioStream.Channels.HasValue && - audioStream.Channels.Value == 1) + if (audioStream.Channels == 1 + && (audioStream.BitRate ?? 0) < 64000) { - if ((audioStream.BitRate ?? 0) < 64000) - { - encoderAudioBitrateLimit = 64000; - } + encoderAudioBitrateLimit = 64000; } } @@ -918,19 +922,17 @@ namespace MediaBrowser.Model.Dlna return Math.Min(defaultBitrate, encoderAudioBitrateLimit); } - private int GetMaxAudioBitrateForTotalBitrate(long totalBitrate) + private static int GetMaxAudioBitrateForTotalBitrate(long totalBitrate) { if (totalBitrate <= 640000) { return 128000; } - - if (totalBitrate <= 2000000) + else if (totalBitrate <= 2000000) { return 384000; } - - if (totalBitrate <= 3000000) + else if (totalBitrate <= 3000000) { return 448000; } @@ -938,24 +940,25 @@ namespace MediaBrowser.Model.Dlna return 640000; } - private Tuple> GetVideoDirectPlayProfile(VideoOptions options, + private (PlayMethod?, List) GetVideoDirectPlayProfile( + VideoOptions options, MediaSourceInfo mediaSource, MediaStream videoStream, MediaStream audioStream, bool isEligibleForDirectPlay, bool isEligibleForDirectStream) { - DeviceProfile profile = options.Profile; - if (options.ForceDirectPlay) { - return new Tuple>(PlayMethod.DirectPlay, new List()); + return (PlayMethod.DirectPlay, new List()); } if (options.ForceDirectStream) { - return new Tuple>(PlayMethod.DirectStream, new List()); + return (PlayMethod.DirectStream, new List()); } + DeviceProfile profile = options.Profile; + // See if it can be direct played DirectPlayProfile directPlay = null; foreach (var i in profile.DirectPlayProfiles) @@ -973,7 +976,7 @@ namespace MediaBrowser.Model.Dlna profile.Name ?? "Unknown Profile", mediaSource.Path ?? "Unknown path"); - return new Tuple>(null, GetTranscodeReasonsFromDirectPlayProfile(mediaSource, videoStream, audioStream, profile.DirectPlayProfiles)); + return (null, GetTranscodeReasonsFromDirectPlayProfile(mediaSource, videoStream, audioStream, profile.DirectPlayProfiles)); } string container = mediaSource.Container; @@ -981,8 +984,8 @@ namespace MediaBrowser.Model.Dlna var conditions = new List(); foreach (var i in profile.ContainerProfiles) { - if (i.Type == DlnaProfileType.Video && - i.ContainsContainer(container)) + if (i.Type == DlnaProfileType.Video + && i.ContainsContainer(container)) { foreach (var c in i.Conditions) { @@ -1026,13 +1029,13 @@ namespace MediaBrowser.Model.Dlna var transcodeReason = GetTranscodeReasonForFailedCondition(i); var transcodeReasons = transcodeReason.HasValue ? new List { transcodeReason.Value } - : new List { }; + : new List(); - return new Tuple>(null, transcodeReasons); + return (null, transcodeReasons); } } - string videoCodec = videoStream == null ? null : videoStream.Codec; + string videoCodec = videoStream?.Codec; conditions = new List(); foreach (var i in profile.CodecProfiles) @@ -1071,14 +1074,13 @@ namespace MediaBrowser.Model.Dlna ? new List { transcodeReason.Value } : new List(); - return new Tuple>(null, transcodeReasons); + return (null, transcodeReasons); } } if (audioStream != null) { string audioCodec = audioStream.Codec; - conditions = new List(); bool? isSecondaryAudio = audioStream == null ? null : mediaSource.IsSecondaryAudio(audioStream); @@ -1118,17 +1120,17 @@ namespace MediaBrowser.Model.Dlna ? new List { transcodeReason.Value } : new List(); - return new Tuple>(null, transcodeReasons); + return (null, transcodeReasons); } } } if (isEligibleForDirectStream && mediaSource.SupportsDirectStream) { - return new Tuple>(PlayMethod.DirectStream, new List()); + return (PlayMethod.DirectStream, new List()); } - return new Tuple>(null, new List { TranscodeReason.ContainerBitrateExceedsLimit }); + return (null, new List { TranscodeReason.ContainerBitrateExceedsLimit }); } private void LogConditionFailure(DeviceProfile profile, string type, ProfileCondition condition, MediaSourceInfo mediaSource) @@ -1166,7 +1168,14 @@ namespace MediaBrowser.Model.Dlna return (result, result ? (TranscodeReason?)null : TranscodeReason.ContainerBitrateExceedsLimit); } - public static SubtitleProfile GetSubtitleProfile(MediaSourceInfo mediaSource, MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, ITranscoderSupport transcoderSupport, string outputContainer, string transcodingSubProtocol) + public static SubtitleProfile GetSubtitleProfile( + MediaSourceInfo mediaSource, + MediaStream subtitleStream, + SubtitleProfile[] subtitleProfiles, + PlayMethod playMethod, + ITranscoderSupport transcoderSupport, + string outputContainer, + string transcodingSubProtocol) { if (!subtitleStream.IsExternal && (playMethod != PlayMethod.Transcode || !string.Equals(transcodingSubProtocol, "hls", StringComparison.OrdinalIgnoreCase))) { @@ -1249,15 +1258,15 @@ namespace MediaBrowser.Model.Dlna { return false; } - if (ContainerProfile.ContainsContainer(normalizedContainers, "mpegts")) + else if (ContainerProfile.ContainsContainer(normalizedContainers, "mpegts")) { return false; } - if (ContainerProfile.ContainsContainer(normalizedContainers, "mp4")) + else if (ContainerProfile.ContainsContainer(normalizedContainers, "mp4")) { return false; } - if (ContainerProfile.ContainsContainer(normalizedContainers, "mkv") || + else if (ContainerProfile.ContainsContainer(normalizedContainers, "mkv") || ContainerProfile.ContainsContainer(normalizedContainers, "matroska")) { return true; @@ -1330,10 +1339,10 @@ namespace MediaBrowser.Model.Dlna return true; } - var requestedMaxBitrate = maxBitrate > 0 ? maxBitrate : 1000000; + long requestedMaxBitrate = maxBitrate > 0 ? maxBitrate : 1000000; // If we don't know the bitrate, then force a transcode if requested max bitrate is under 40 mbps - var itemBitrate = item.Bitrate ?? 40000000; + int itemBitrate = item.Bitrate ?? 40000000; if (itemBitrate > requestedMaxBitrate) { @@ -1345,7 +1354,7 @@ namespace MediaBrowser.Model.Dlna return true; } - private void ValidateInput(VideoOptions options) + private static void ValidateInput(VideoOptions options) { ValidateAudioInput(options); @@ -1360,7 +1369,7 @@ namespace MediaBrowser.Model.Dlna } } - private void ValidateAudioInput(AudioOptions options) + private static void ValidateAudioInput(AudioOptions options) { if (options.ItemId.Equals(Guid.Empty)) { @@ -1380,32 +1389,6 @@ namespace MediaBrowser.Model.Dlna } } - private void ApplyTranscodingConditions(StreamInfo item, List codecProfiles) - { - foreach (var profile in codecProfiles) - { - ApplyTranscodingConditions(item, profile); - } - } - - private void ApplyTranscodingConditions(StreamInfo item, CodecProfile codecProfile) - { - var codecs = ContainerProfile.SplitValue(codecProfile.Codec); - if (codecs.Length == 0) - { - ApplyTranscodingConditions(item, codecProfile.Conditions, null, true, true); - return; - } - - var enableNonQualified = true; - - foreach (var codec in codecs) - { - ApplyTranscodingConditions(item, codecProfile.Conditions, codec, true, enableNonQualified); - enableNonQualified = false; - } - } - private void ApplyTranscodingConditions(StreamInfo item, IEnumerable conditions, string qualifier, bool enableQualifiedConditions, bool enableNonQualifiedConditions) { foreach (ProfileCondition condition in conditions) @@ -1780,7 +1763,7 @@ namespace MediaBrowser.Model.Dlna } } - private bool IsAudioDirectPlaySupported(DirectPlayProfile profile, MediaSourceInfo item, MediaStream audioStream) + private static bool IsAudioDirectPlaySupported(DirectPlayProfile profile, MediaSourceInfo item, MediaStream audioStream) { // Check container type if (!profile.SupportsContainer(item.Container)) @@ -1789,7 +1772,7 @@ namespace MediaBrowser.Model.Dlna } // Check audio codec - string audioCodec = audioStream == null ? null : audioStream.Codec; + string audioCodec = audioStream?.Codec; if (!profile.SupportsAudioCodec(audioCodec)) { return false; @@ -1807,20 +1790,16 @@ namespace MediaBrowser.Model.Dlna } // Check video codec - string videoCodec = videoStream == null ? null : videoStream.Codec; + string videoCodec = videoStream?.Codec; if (!profile.SupportsVideoCodec(videoCodec)) { return false; } // Check audio codec - if (audioStream != null) + if (audioStream != null && !profile.SupportsAudioCodec(audioStream.Codec)) { - string audioCodec = audioStream == null ? null : audioStream.Codec; - if (!profile.SupportsAudioCodec(audioCodec)) - { - return false; - } + return false; } return true; From 2f8f9e68533d7ddff804738451b321d5307c7aec Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 21 Jan 2019 16:57:10 +0100 Subject: [PATCH 04/19] Address comments --- MediaBrowser.Model/Dlna/StreamBuilder.cs | 25 +++++++----------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 8f0120a0d7..6c6e09ab1c 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -149,13 +149,9 @@ namespace MediaBrowser.Model.Dlna { switch (condition.Property) { - case ProfileConditionValue.AudioBitrate when condition.Condition == ProfileConditionType.LessThanEqual: - return TranscodeReason.AudioBitrateNotSupported; case ProfileConditionValue.AudioBitrate: return TranscodeReason.AudioBitrateNotSupported; - case ProfileConditionValue.AudioChannels when condition.Condition == ProfileConditionType.LessThanEqual: - return TranscodeReason.AudioChannelsNotSupported; case ProfileConditionValue.AudioChannels: return TranscodeReason.AudioChannelsNotSupported; @@ -898,7 +894,7 @@ namespace MediaBrowser.Model.Dlna if (targetAudioChannels.HasValue && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value) { // Reduce the bitrate if we're downmixing - defaultBitrate = targetAudioChannels.Value <= 2 ? 128000 : 192000; + defaultBitrate = targetAudioChannels.Value < 2 ? 128000 : 192000; } else { @@ -1252,27 +1248,20 @@ namespace MediaBrowser.Model.Dlna { if (!string.IsNullOrEmpty(transcodingContainer)) { - var normalizedContainers = ContainerProfile.SplitValue(transcodingContainer); + string[] normalizedContainers = ContainerProfile.SplitValue(transcodingContainer); - if (ContainerProfile.ContainsContainer(normalizedContainers, "ts")) + if (ContainerProfile.ContainsContainer(normalizedContainers, "ts") + || ContainerProfile.ContainsContainer(normalizedContainers, "mpegts") + || ContainerProfile.ContainsContainer(normalizedContainers, "mp4")) { return false; } - else if (ContainerProfile.ContainsContainer(normalizedContainers, "mpegts")) - { - return false; - } - else if (ContainerProfile.ContainsContainer(normalizedContainers, "mp4")) - { - return false; - } - else if (ContainerProfile.ContainsContainer(normalizedContainers, "mkv") || - ContainerProfile.ContainsContainer(normalizedContainers, "matroska")) + else if (ContainerProfile.ContainsContainer(normalizedContainers, "mkv") + || ContainerProfile.ContainsContainer(normalizedContainers, "matroska")) { return true; } } - return false; } From bc8a0eeead8721951250edade1047073030d1246 Mon Sep 17 00:00:00 2001 From: Andrew Rabert Date: Mon, 21 Jan 2019 19:22:08 -0500 Subject: [PATCH 05/19] Use TagLibSharp Nuget package --- .gitmodules | 3 --- Emby.Photos/Emby.Photos.csproj | 5 ++++- MediaBrowser.sln | 6 ------ 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.gitmodules b/.gitmodules index 7aeb94dfca..c10f5905c4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "ThirdParty/taglib-sharp"] - path = ThirdParty/taglib-sharp - url = https://github.com/mono/taglib-sharp.git [submodule "MediaBrowser.WebDashboard/jellyfin-web"] path = MediaBrowser.WebDashboard/jellyfin-web url = https://github.com/jellyfin/jellyfin-web.git diff --git a/Emby.Photos/Emby.Photos.csproj b/Emby.Photos/Emby.Photos.csproj index e6b445202f..c9830abc5f 100644 --- a/Emby.Photos/Emby.Photos.csproj +++ b/Emby.Photos/Emby.Photos.csproj @@ -3,13 +3,16 @@ - + + + + netstandard2.0 false diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 0f0c24a25f..dfaa2601fa 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -42,8 +42,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Notifications", "Emby. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Naming", "Emby.Naming\Emby.Naming.csproj", "{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "taglib-sharp", "ThirdParty\taglib-sharp\src\taglib-sharp.csproj", "{D45FC504-D06B-41A0-A220-C20B7E8F1304}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.XmlTv", "Emby.XmlTv\Emby.XmlTv\Emby.XmlTv.csproj", "{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IsoMounter", "Emby.IsoMounting\IsoMounter\IsoMounter.csproj", "{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}" @@ -144,10 +142,6 @@ Global {E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Debug|Any CPU.Build.0 = Debug|Any CPU {E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Release|Any CPU.ActiveCfg = Release|Any CPU {E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Release|Any CPU.Build.0 = Release|Any CPU - {D45FC504-D06B-41A0-A220-C20B7E8F1304}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D45FC504-D06B-41A0-A220-C20B7E8F1304}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D45FC504-D06B-41A0-A220-C20B7E8F1304}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D45FC504-D06B-41A0-A220-C20B7E8F1304}.Release|Any CPU.Build.0 = Release|Any CPU {6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Debug|Any CPU.Build.0 = Debug|Any CPU {6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Release|Any CPU.ActiveCfg = Release|Any CPU From 07cba6cbcfe5a5ce7701fbae43c13d16049728bc Mon Sep 17 00:00:00 2001 From: hawken Date: Mon, 21 Jan 2019 17:52:49 +0000 Subject: [PATCH 06/19] Do some logging in MediaInfoService --- MediaBrowser.Api/Playback/MediaInfoService.cs | 18 ++++++++++--- .../Playback/UniversalAudioService.cs | 26 +++++++++++++++++-- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 1c7be52f3e..ab3994a639 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -74,8 +74,19 @@ namespace MediaBrowser.Api.Playback private readonly IUserManager _userManager; private readonly IJsonSerializer _json; private readonly IAuthorizationContext _authContext; + private readonly ILogger _logger; - public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager, IMediaEncoder mediaEncoder, IUserManager userManager, IJsonSerializer json, IAuthorizationContext authContext) + public MediaInfoService( + IMediaSourceManager mediaSourceManager, + IDeviceManager deviceManager, + ILibraryManager libraryManager, + IServerConfigurationManager config, + INetworkManager networkManager, + IMediaEncoder mediaEncoder, + IUserManager userManager, + IJsonSerializer json, + IAuthorizationContext authContext, + ILoggerFactory loggerFactory) { _mediaSourceManager = mediaSourceManager; _deviceManager = deviceManager; @@ -86,6 +97,7 @@ namespace MediaBrowser.Api.Playback _userManager = userManager; _json = json; _authContext = authContext; + _logger = loggerFactory.CreateLogger(nameof(MediaInfoService)); } public object Get(GetBitrateTestBytes request) @@ -165,7 +177,7 @@ namespace MediaBrowser.Api.Playback var profile = request.DeviceProfile; - //Logger.Info("GetPostedPlaybackInfo profile: {0}", _json.SerializeToString(profile)); + //Logger.LogInformation("GetPostedPlaybackInfo profile: {profile}", _json.SerializeToString(profile)); if (profile == null) { @@ -262,7 +274,7 @@ namespace MediaBrowser.Api.Playback catch (Exception ex) { mediaSources = new List(); - // TODO Log exception + _logger.LogError(ex, "Could not find media sources for item id {id}", id); // TODO PlaybackException ?? //result.ErrorCode = ex.ErrorCode; } diff --git a/MediaBrowser.Api/Playback/UniversalAudioService.cs b/MediaBrowser.Api/Playback/UniversalAudioService.cs index 1faa32ba94..1aa77792ce 100644 --- a/MediaBrowser.Api/Playback/UniversalAudioService.cs +++ b/MediaBrowser.Api/Playback/UniversalAudioService.cs @@ -19,6 +19,7 @@ using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Services; using MediaBrowser.Model.System; +using Microsoft.Extensions.Logging; namespace MediaBrowser.Api.Playback { @@ -75,7 +76,24 @@ namespace MediaBrowser.Api.Playback [Authenticated] public class UniversalAudioService : BaseApiService { - public UniversalAudioService(IServerConfigurationManager serverConfigurationManager, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, IDeviceManager deviceManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IAuthorizationContext authorizationContext, IImageProcessor imageProcessor, INetworkManager networkManager, IEnvironmentInfo environmentInfo) + public UniversalAudioService( + IServerConfigurationManager serverConfigurationManager, + IUserManager userManager, + ILibraryManager libraryManager, + IIsoManager isoManager, + IMediaEncoder mediaEncoder, + IFileSystem fileSystem, + IDlnaManager dlnaManager, + IDeviceManager deviceManager, + ISubtitleEncoder subtitleEncoder, + IMediaSourceManager mediaSourceManager, + IZipClient zipClient, + IJsonSerializer jsonSerializer, + IAuthorizationContext authorizationContext, + IImageProcessor imageProcessor, + INetworkManager networkManager, + IEnvironmentInfo environmentInfo, + ILoggerFactory loggerFactory) { ServerConfigurationManager = serverConfigurationManager; UserManager = userManager; @@ -93,6 +111,8 @@ namespace MediaBrowser.Api.Playback ImageProcessor = imageProcessor; NetworkManager = networkManager; EnvironmentInfo = environmentInfo; + _loggerFactory = loggerFactory; + _logger = loggerFactory.CreateLogger(nameof(UniversalAudioService)); } protected IServerConfigurationManager ServerConfigurationManager { get; private set; } @@ -111,6 +131,8 @@ namespace MediaBrowser.Api.Playback protected IImageProcessor ImageProcessor { get; private set; } protected INetworkManager NetworkManager { get; private set; } protected IEnvironmentInfo EnvironmentInfo { get; private set; } + private ILoggerFactory _loggerFactory; + private ILogger _logger; public Task Get(GetUniversalAudioStream request) { @@ -221,7 +243,7 @@ namespace MediaBrowser.Api.Playback AuthorizationContext.GetAuthorizationInfo(Request).DeviceId = request.DeviceId; - var mediaInfoService = new MediaInfoService(MediaSourceManager, DeviceManager, LibraryManager, ServerConfigurationManager, NetworkManager, MediaEncoder, UserManager, JsonSerializer, AuthorizationContext) + var mediaInfoService = new MediaInfoService(MediaSourceManager, DeviceManager, LibraryManager, ServerConfigurationManager, NetworkManager, MediaEncoder, UserManager, JsonSerializer, AuthorizationContext, _loggerFactory) { Request = Request }; From a356c1417a90509a33fef2e49db66667e9c5b1ce Mon Sep 17 00:00:00 2001 From: hawken Date: Tue, 22 Jan 2019 12:19:50 +0000 Subject: [PATCH 07/19] Change MusicAlbum.Tracks to return Audio items --- MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index a3e05f0d2d..5b2939b759 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -96,7 +96,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// /// The tracks. [IgnoreDataMember] - public IEnumerable Tracks => GetRecursiveChildren(i => i is Audio); + public IEnumerable