diff options
| author | 7illusions <z@7illusions.com> | 2014-05-12 16:55:07 +0200 |
|---|---|---|
| committer | 7illusions <z@7illusions.com> | 2014-05-12 16:55:07 +0200 |
| commit | baf5cf2544fcaad2246923f60caaf3fed4a94aaf (patch) | |
| tree | a808b700095f876e437b95c432c0220e241f9fda /MediaBrowser.Model/Dlna | |
| parent | 8f3a6279e173dcbaaa05a56556afb410ee12dd4d (diff) | |
| parent | b9b568de13d81f9db1a8502d50940475c1d79c72 (diff) | |
Merge pull request #3 from MediaBrowser/master
Sync with Master
Diffstat (limited to 'MediaBrowser.Model/Dlna')
30 files changed, 727 insertions, 501 deletions
diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs new file mode 100644 index 0000000000..d04133a3d9 --- /dev/null +++ b/MediaBrowser.Model/Dlna/AudioOptions.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using MediaBrowser.Model.Dto; + +namespace MediaBrowser.Model.Dlna +{ + /// <summary> + /// Class AudioOptions. + /// </summary> + public class AudioOptions + { + public string ItemId { get; set; } + public List<MediaSourceInfo> MediaSources { get; set; } + public DeviceProfile Profile { get; set; } + + /// <summary> + /// Optional. Only needed if a specific AudioStreamIndex or SubtitleStreamIndex are requested. + /// </summary> + public string MediaSourceId { get; set; } + + public string DeviceId { get; set; } + + /// <summary> + /// Allows an override of supported number of audio channels + /// Example: DeviceProfile supports five channel, but user only has stereo speakers + /// </summary> + public int? MaxAudioChannels { get; set; } + + /// <summary> + /// The application's configured quality setting + /// </summary> + public int? MaxBitrate { get; set; } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/CodecProfile.cs b/MediaBrowser.Model/Dlna/CodecProfile.cs index 2b04b7fdb7..3e67b49f91 100644 --- a/MediaBrowser.Model/Dlna/CodecProfile.cs +++ b/MediaBrowser.Model/Dlna/CodecProfile.cs @@ -22,66 +22,19 @@ namespace MediaBrowser.Model.Dlna public List<string> GetCodecs() { - return (Codec ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (Codec ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) list.Add(i); + } + return list; } public bool ContainsCodec(string codec) { - var codecs = GetCodecs(); + List<string> codecs = GetCodecs(); return codecs.Count == 0 || codecs.Contains(codec, StringComparer.OrdinalIgnoreCase); } } - - public enum CodecType - { - Video = 0, - VideoAudio = 1, - Audio = 2 - } - - public class ProfileCondition - { - [XmlAttribute("condition")] - public ProfileConditionType Condition { get; set; } - - [XmlAttribute("property")] - public ProfileConditionValue Property { get; set; } - - [XmlAttribute("value")] - public string Value { get; set; } - - [XmlAttribute("isRequired")] - public bool IsRequired { get; set; } - - public ProfileCondition() - { - IsRequired = true; - } - } - - public enum ProfileConditionType - { - Equals = 0, - NotEquals = 1, - LessThanEqual = 2, - GreaterThanEqual = 3 - } - - public enum ProfileConditionValue - { - AudioChannels, - AudioBitrate, - AudioProfile, - Width, - Height, - Has64BitOffsets, - PacketLength, - VideoBitDepth, - VideoBitrate, - VideoFramerate, - VideoLevel, - VideoProfile, - VideoTimestamp - } } diff --git a/MediaBrowser.Model/Dlna/CodecType.cs b/MediaBrowser.Model/Dlna/CodecType.cs new file mode 100644 index 0000000000..415cae7acf --- /dev/null +++ b/MediaBrowser.Model/Dlna/CodecType.cs @@ -0,0 +1,9 @@ +namespace MediaBrowser.Model.Dlna +{ + public enum CodecType + { + Video = 0, + VideoAudio = 1, + Audio = 2 + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs index 27c4850e8c..488d742f52 100644 --- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs +++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs @@ -136,7 +136,7 @@ namespace MediaBrowser.Model.Dlna return !condition.IsRequired; } - var expected = condition.Value; + string expected = condition.Value; switch (condition.Condition) { @@ -186,7 +186,7 @@ namespace MediaBrowser.Model.Dlna return !condition.IsRequired; } - var expected = (TransportStreamTimestamp)Enum.Parse(typeof(TransportStreamTimestamp), condition.Value, true); + TransportStreamTimestamp expected = (TransportStreamTimestamp)Enum.Parse(typeof(TransportStreamTimestamp), condition.Value, true); switch (condition.Condition) { diff --git a/MediaBrowser.Model/Dlna/ContainerProfile.cs b/MediaBrowser.Model/Dlna/ContainerProfile.cs index 3a5fe3bd50..931194dd3d 100644 --- a/MediaBrowser.Model/Dlna/ContainerProfile.cs +++ b/MediaBrowser.Model/Dlna/ContainerProfile.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using System.Xml.Serialization; namespace MediaBrowser.Model.Dlna @@ -20,7 +19,12 @@ namespace MediaBrowser.Model.Dlna public List<string> GetContainers() { - return (Container ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (Container ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) list.Add(i); + } + return list; } } } diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs index 7e21e1ef2f..c97c06d34a 100644 --- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -1,8 +1,5 @@ -using System; +using MediaBrowser.Model.MediaInfo; using System.Collections.Generic; -using System.Linq; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Model.Dlna { @@ -19,30 +16,30 @@ namespace MediaBrowser.Model.Dlna int? width, int? height) { - var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetImageOrgOpValue(); + string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetImageOrgOpValue(); // 0 = native, 1 = transcoded const string orgCi = ";DLNA.ORG_CI=0"; - var flagValue = DlnaFlags.StreamingTransferMode | + DlnaFlags flagValue = DlnaFlags.StreamingTransferMode | DlnaFlags.BackgroundTransferMode | DlnaFlags.DlnaV15; - var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", - FlagsToString(flagValue)); + string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", + DlnaMaps.FlagsToString(flagValue)); - var mediaProfile = _profile.GetImageMediaProfile(container, + ResponseProfile mediaProfile = _profile.GetImageMediaProfile(container, width, height); - var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; + string orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; if (string.IsNullOrEmpty(orgPn)) { orgPn = GetImageOrgPnValue(container, width, height); } - var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; + string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); } @@ -57,12 +54,12 @@ namespace MediaBrowser.Model.Dlna TranscodeSeekInfo transcodeSeekInfo) { // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none - var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo); + string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo); // 0 = native, 1 = transcoded - var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; + string orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; - var flagValue = DlnaFlags.StreamingTransferMode | + DlnaFlags flagValue = DlnaFlags.StreamingTransferMode | DlnaFlags.BackgroundTransferMode | DlnaFlags.DlnaV15; @@ -75,32 +72,26 @@ namespace MediaBrowser.Model.Dlna //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK; } - var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", - FlagsToString(flagValue)); + string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", + DlnaMaps.FlagsToString(flagValue)); - var mediaProfile = _profile.GetAudioMediaProfile(container, + ResponseProfile mediaProfile = _profile.GetAudioMediaProfile(container, audioCodec, audioChannels, audioBitrate); - var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; + string orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; if (string.IsNullOrEmpty(orgPn)) { orgPn = GetAudioOrgPnValue(container, audioBitrate, audioSampleRate, audioChannels); } - var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; + string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); } - private static string FlagsToString(DlnaFlags flags) - { - //return Enum.Format(typeof(DlnaFlags), flags, "x"); - return string.Format("{0:X8}{1:D24}", (ulong)flags, 0); - } - public string BuildVideoHeader(string container, string videoCodec, string audioCodec, @@ -120,12 +111,12 @@ namespace MediaBrowser.Model.Dlna TranscodeSeekInfo transcodeSeekInfo) { // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none - var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo); + string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo); // 0 = native, 1 = transcoded - var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; + string orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; - var flagValue = DlnaFlags.StreamingTransferMode | + DlnaFlags flagValue = DlnaFlags.StreamingTransferMode | DlnaFlags.BackgroundTransferMode | DlnaFlags.DlnaV15; @@ -138,10 +129,10 @@ namespace MediaBrowser.Model.Dlna //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK; } - var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", - FlagsToString(flagValue)); + string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", + DlnaMaps.FlagsToString(flagValue)); - var mediaProfile = _profile.GetVideoMediaProfile(container, + ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(container, audioCodec, videoCodec, audioBitrate, @@ -156,25 +147,35 @@ namespace MediaBrowser.Model.Dlna packetLength, timestamp); - var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; + string orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; if (string.IsNullOrEmpty(orgPn)) { - orgPn = GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp) - .FirstOrDefault(); + foreach (string s in GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp)) + { + orgPn = s; + break; + } + } + if (string.IsNullOrEmpty(orgPn)) + { // TODO: Support multiple values and return multiple headers? - orgPn = (orgPn ?? string.Empty).Split(',').FirstOrDefault(); + foreach (string s in (orgPn ?? string.Empty).Split(',')) + { + orgPn = s; + break; + } } - var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; + string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); } private string GetImageOrgPnValue(string container, int? width, int? height) { - var format = new MediaFormatProfileResolver() + MediaFormatProfile? format = new MediaFormatProfileResolver() .ResolveImageFormat(container, width, height); @@ -184,7 +185,7 @@ namespace MediaBrowser.Model.Dlna private string GetAudioOrgPnValue(string container, int? audioBitrate, int? audioSampleRate, int? audioChannels) { - var format = new MediaFormatProfileResolver() + MediaFormatProfile? format = new MediaFormatProfileResolver() .ResolveAudioFormat(container, audioBitrate, audioSampleRate, @@ -193,16 +194,12 @@ namespace MediaBrowser.Model.Dlna return format.HasValue ? format.Value.ToString() : null; } - private IEnumerable<string> GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp) + private List<string> GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp) { - return new MediaFormatProfileResolver() - .ResolveVideoFormat(container, - videoCodec, - audioCodec, - width, - height, - timestamp) - .Select(i => i.ToString()); + List<string> list = new List<string>(); + foreach (MediaFormatProfile i in new MediaFormatProfileResolver().ResolveVideoFormat(container, videoCodec, audioCodec, width, height, timestamp)) + list.Add(i.ToString()); + return list; } } } diff --git a/MediaBrowser.Model/Dlna/DeviceIdentification.cs b/MediaBrowser.Model/Dlna/DeviceIdentification.cs index 87cf000b1a..97f4409daf 100644 --- a/MediaBrowser.Model/Dlna/DeviceIdentification.cs +++ b/MediaBrowser.Model/Dlna/DeviceIdentification.cs @@ -1,6 +1,4 @@ -using System.Xml.Serialization; - -namespace MediaBrowser.Model.Dlna +namespace MediaBrowser.Model.Dlna { public class DeviceIdentification { @@ -60,23 +58,4 @@ namespace MediaBrowser.Model.Dlna Headers = new HttpHeaderInfo[] {}; } } - - public class HttpHeaderInfo - { - [XmlAttribute("name")] - public string Name { get; set; } - - [XmlAttribute("value")] - public string Value { get; set; } - - [XmlAttribute("match")] - public HeaderMatchType Match { get; set; } - } - - public enum HeaderMatchType - { - Equals = 0, - Regex = 1, - Substring = 2 - } } diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index b23ad876c7..42ba5840cf 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -105,116 +105,154 @@ namespace MediaBrowser.Model.Dlna public List<string> GetSupportedMediaTypes() { - return (SupportedMediaTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (SupportedMediaTypes ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) + list.Add(i); + } + return list; } public TranscodingProfile GetAudioTranscodingProfile(string container, string audioCodec) { container = (container ?? string.Empty).TrimStart('.'); - return TranscodingProfiles.FirstOrDefault(i => + foreach (var i in TranscodingProfiles) { if (i.Type != DlnaProfileType.Audio) { - return false; + continue; } if (!string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase)) { - return false; + continue; } - if (!i.GetAudioCodecs().Contains(audioCodec ?? string.Empty)) + if (!i.GetAudioCodecs().Contains(audioCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { - return false; + continue; } - return true; - }); + return i; + } + return null; } public TranscodingProfile GetVideoTranscodingProfile(string container, string audioCodec, string videoCodec) { container = (container ?? string.Empty).TrimStart('.'); - return TranscodingProfiles.FirstOrDefault(i => + foreach (var i in TranscodingProfiles) { if (i.Type != DlnaProfileType.Video) { - return false; + continue; } if (!string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase)) { - return false; + continue; } if (!i.GetAudioCodecs().Contains(audioCodec ?? string.Empty)) { - return false; + continue; } if (!string.Equals(videoCodec, i.VideoCodec, StringComparison.OrdinalIgnoreCase)) { - return false; + continue; } - return true; - }); + return i; + } + return null; } public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, int? audioChannels, int? audioBitrate) { container = (container ?? string.Empty).TrimStart('.'); - return ResponseProfiles.FirstOrDefault(i => + foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Audio) { - return false; + continue; + } + + List<string> containers = i.GetContainers(); + if (containers.Count > 0 && !containers.Contains(container, StringComparer.OrdinalIgnoreCase)) + { + continue; } - var containers = i.GetContainers().ToList(); - if (containers.Count > 0 && !containers.Contains(container)) + List<string> audioCodecs = i.GetAudioCodecs(); + if (audioCodecs.Count > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { - return false; + continue; } - var audioCodecs = i.GetAudioCodecs().ToList(); - if (audioCodecs.Count > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty)) + ConditionProcessor conditionProcessor = new ConditionProcessor(); + + var anyOff = false; + foreach (ProfileCondition c in i.Conditions) { - return false; + if (!conditionProcessor.IsAudioConditionSatisfied(c, audioChannels, audioBitrate)) + { + anyOff = true; + break; + } } - var conditionProcessor = new ConditionProcessor(); - return i.Conditions.All(c => conditionProcessor.IsAudioConditionSatisfied(c, - audioChannels, - audioBitrate)); - }); + if (anyOff) + { + continue; + } + + return i; + } + return null; } public ResponseProfile GetImageMediaProfile(string container, int? width, int? height) { container = (container ?? string.Empty).TrimStart('.'); - return ResponseProfiles.FirstOrDefault(i => + foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Photo) { - return false; + continue; + } + + List<string> containers = i.GetContainers(); + if (containers.Count > 0 && !containers.Contains(container, StringComparer.OrdinalIgnoreCase)) + { + continue; + } + + ConditionProcessor conditionProcessor = new ConditionProcessor(); + + var anyOff = false; + foreach (ProfileCondition c in i.Conditions) + { + if (!conditionProcessor.IsImageConditionSatisfied(c, width, height)) + { + anyOff = true; + break; + } } - var containers = i.GetContainers().ToList(); - if (containers.Count > 0 && !containers.Contains(container)) + if (anyOff) { - return false; + continue; } - var conditionProcessor = new ConditionProcessor(); - return i.Conditions.All(c => conditionProcessor.IsImageConditionSatisfied(c, - width, - height)); - }); + return i; + } + return null; } public ResponseProfile GetVideoMediaProfile(string container, @@ -234,69 +272,90 @@ namespace MediaBrowser.Model.Dlna { container = (container ?? string.Empty).TrimStart('.'); - return ResponseProfiles.FirstOrDefault(i => + foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Video) { - return false; + continue; + } + + List<string> containers = i.GetContainers(); + if (containers.Count > 0 && !containers.Contains(container, StringComparer.OrdinalIgnoreCase)) + { + continue; } - var containers = i.GetContainers().ToList(); - if (containers.Count > 0 && !containers.Contains(container)) + List<string> audioCodecs = i.GetAudioCodecs(); + if (audioCodecs.Count > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { - return false; + continue; } - var audioCodecs = i.GetAudioCodecs().ToList(); - if (audioCodecs.Count > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty)) + List<string> videoCodecs = i.GetVideoCodecs(); + if (videoCodecs.Count > 0 && !videoCodecs.Contains(videoCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + continue; + } + + ConditionProcessor conditionProcessor = new ConditionProcessor(); + + var anyOff = false; + foreach (ProfileCondition c in i.Conditions) { - return false; + if (!conditionProcessor.IsVideoConditionSatisfied(c, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp)) + { + anyOff = true; + break; + } } - var videoCodecs = i.GetVideoCodecs().ToList(); - if (videoCodecs.Count > 0 && !videoCodecs.Contains(videoCodec ?? string.Empty)) + if (anyOff) { - return false; + continue; } - var conditionProcessor = new ConditionProcessor(); - return i.Conditions.All(c => conditionProcessor.IsVideoConditionSatisfied(c, - audioBitrate, - audioChannels, - width, - height, - bitDepth, - videoBitrate, - videoProfile, - videoLevel, - videoFramerate, - packetLength, - timestamp)); - }); + return i; + } + return null; } public ResponseProfile GetPhotoMediaProfile(string container, int? width, int? height) { container = (container ?? string.Empty).TrimStart('.'); - return ResponseProfiles.FirstOrDefault(i => + foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Photo) { - return false; + continue; + } + + List<string> containers = i.GetContainers().ToList(); + if (containers.Count > 0 && !containers.Contains(container, StringComparer.OrdinalIgnoreCase)) + { + continue; + } + + ConditionProcessor conditionProcessor = new ConditionProcessor(); + + var anyOff = false; + foreach (ProfileCondition c in i.Conditions) + { + if (!conditionProcessor.IsImageConditionSatisfied(c, width, height)) + { + anyOff = true; + break; + } } - var containers = i.GetContainers().ToList(); - if (containers.Count > 0 && !containers.Contains(container)) + if (anyOff) { - return false; + continue; } - var conditionProcessor = new ConditionProcessor(); - return i.Conditions.All(c => conditionProcessor.IsImageConditionSatisfied(c, - width, - height)); - }); + return i; + } + return null; } } } diff --git a/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs b/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs index ceb27386c1..b2afdf2924 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs @@ -21,10 +21,4 @@ namespace MediaBrowser.Model.Dlna /// <value>The type.</value> public DeviceProfileType Type { get; set; } } - - public enum DeviceProfileType - { - System = 0, - User = 1 - } } diff --git a/MediaBrowser.Model/Dlna/DeviceProfileType.cs b/MediaBrowser.Model/Dlna/DeviceProfileType.cs new file mode 100644 index 0000000000..f881a45395 --- /dev/null +++ b/MediaBrowser.Model/Dlna/DeviceProfileType.cs @@ -0,0 +1,8 @@ +namespace MediaBrowser.Model.Dlna +{ + public enum DeviceProfileType + { + System = 0, + User = 1 + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs index e195c94507..183299425e 100644 --- a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs +++ b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using System.Xml.Serialization; namespace MediaBrowser.Model.Dlna @@ -20,33 +19,32 @@ namespace MediaBrowser.Model.Dlna public List<string> GetContainers() { - return (Container ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (Container ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) list.Add(i); + } + return list; } public List<string> GetAudioCodecs() { - return (AudioCodec ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (AudioCodec ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) list.Add(i); + } + return list; } public List<string> GetVideoCodecs() { - return (VideoCodec ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (VideoCodec ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) list.Add(i); + } + return list; } } - - public class XmlAttribute - { - [XmlAttribute("name")] - public string Name { get; set; } - - [XmlAttribute("value")] - public string Value { get; set; } - } - - public enum DlnaProfileType - { - Audio = 0, - Video = 1, - Photo = 2 - } } diff --git a/MediaBrowser.Model/Dlna/DlnaFlags.cs b/MediaBrowser.Model/Dlna/DlnaFlags.cs new file mode 100644 index 0000000000..23859312dc --- /dev/null +++ b/MediaBrowser.Model/Dlna/DlnaFlags.cs @@ -0,0 +1,21 @@ +using System; + +namespace MediaBrowser.Model.Dlna +{ + [Flags] + public enum DlnaFlags : ulong + { + BackgroundTransferMode = (1 << 22), + ByteBasedSeek = (1 << 29), + ConnectionStall = (1 << 21), + DlnaV15 = (1 << 20), + InteractiveTransferMode = (1 << 23), + PlayContainer = (1 << 28), + RtspPause = (1 << 25), + S0Increase = (1 << 27), + SenderPaced = (1L << 31), + SnIncrease = (1 << 26), + StreamingTransferMode = (1 << 24), + TimeBasedSeek = (1 << 30) + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/DlnaMaps.cs b/MediaBrowser.Model/Dlna/DlnaMaps.cs index d2871474ad..036c1fc749 100644 --- a/MediaBrowser.Model/Dlna/DlnaMaps.cs +++ b/MediaBrowser.Model/Dlna/DlnaMaps.cs @@ -1,6 +1,4 @@ -using System; - -namespace MediaBrowser.Model.Dlna +namespace MediaBrowser.Model.Dlna { public class DlnaMaps { @@ -27,7 +25,7 @@ namespace MediaBrowser.Model.Dlna { if (hasKnownRuntime) { - var orgOp = string.Empty; + string orgOp = string.Empty; // Time-based seeking currently only possible when transcoding orgOp += isDirectStream ? "0" : "1"; @@ -44,7 +42,7 @@ namespace MediaBrowser.Model.Dlna public static string GetImageOrgOpValue() { - var orgOp = string.Empty; + string orgOp = string.Empty; // Time-based seeking currently only possible when transcoding orgOp += "0"; @@ -55,21 +53,4 @@ namespace MediaBrowser.Model.Dlna return orgOp; } } - - [Flags] - public enum DlnaFlags : ulong - { - BackgroundTransferMode = (1 << 22), - ByteBasedSeek = (1 << 29), - ConnectionStall = (1 << 21), - DlnaV15 = (1 << 20), - InteractiveTransferMode = (1 << 23), - PlayContainer = (1 << 28), - RtspPause = (1 << 25), - S0Increase = (1 << 27), - SenderPaced = (1L << 31), - SnIncrease = (1 << 26), - StreamingTransferMode = (1 << 24), - TimeBasedSeek = (1 << 30) - } } diff --git a/MediaBrowser.Model/Dlna/DlnaProfileType.cs b/MediaBrowser.Model/Dlna/DlnaProfileType.cs new file mode 100644 index 0000000000..1bad14081a --- /dev/null +++ b/MediaBrowser.Model/Dlna/DlnaProfileType.cs @@ -0,0 +1,9 @@ +namespace MediaBrowser.Model.Dlna +{ + public enum DlnaProfileType + { + Audio = 0, + Video = 1, + Photo = 2 + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/Filter.cs b/MediaBrowser.Model/Dlna/Filter.cs index c8940734b2..760adb5859 100644 --- a/MediaBrowser.Model/Dlna/Filter.cs +++ b/MediaBrowser.Model/Dlna/Filter.cs @@ -19,9 +19,10 @@ namespace MediaBrowser.Model.Dlna { _all = string.Equals(filter, "*", StringComparison.OrdinalIgnoreCase); - _fields = (filter ?? string.Empty) - .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) - .ToList(); + List<string> list = new List<string>(); + foreach (string s in (filter ?? string.Empty).Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)) + list.Add(s); + _fields = list; } public bool Contains(string field) diff --git a/MediaBrowser.Model/Dlna/HeaderMatchType.cs b/MediaBrowser.Model/Dlna/HeaderMatchType.cs new file mode 100644 index 0000000000..7a0d5c24f9 --- /dev/null +++ b/MediaBrowser.Model/Dlna/HeaderMatchType.cs @@ -0,0 +1,9 @@ +namespace MediaBrowser.Model.Dlna +{ + public enum HeaderMatchType + { + Equals = 0, + Regex = 1, + Substring = 2 + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/HttpHeaderInfo.cs b/MediaBrowser.Model/Dlna/HttpHeaderInfo.cs new file mode 100644 index 0000000000..926963ef67 --- /dev/null +++ b/MediaBrowser.Model/Dlna/HttpHeaderInfo.cs @@ -0,0 +1,16 @@ +using System.Xml.Serialization; + +namespace MediaBrowser.Model.Dlna +{ + public class HttpHeaderInfo + { + [XmlAttribute("name")] + public string Name { get; set; } + + [XmlAttribute("value")] + public string Value { get; set; } + + [XmlAttribute("match")] + public HeaderMatchType Match { get; set; } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs index a62508fb1a..3c35ca0f6d 100644 --- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs +++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs @@ -1,7 +1,6 @@ -using System; +using MediaBrowser.Model.MediaInfo; +using System; using System.Collections.Generic; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Model.Dlna { @@ -11,13 +10,13 @@ namespace MediaBrowser.Model.Dlna { if (string.Equals(container, "asf", StringComparison.OrdinalIgnoreCase)) { - var val = ResolveVideoASFFormat(videoCodec, audioCodec, width, height); + MediaFormatProfile? val = ResolveVideoASFFormat(videoCodec, audioCodec, width, height); return val.HasValue ? new List<MediaFormatProfile> { val.Value } : new List<MediaFormatProfile>(); } if (string.Equals(container, "mp4", StringComparison.OrdinalIgnoreCase)) { - var val = ResolveVideoMP4Format(videoCodec, audioCodec, width, height); + MediaFormatProfile? val = ResolveVideoMP4Format(videoCodec, audioCodec, width, height); return val.HasValue ? new List<MediaFormatProfile> { val.Value } : new List<MediaFormatProfile>(); } @@ -51,7 +50,7 @@ namespace MediaBrowser.Model.Dlna if (string.Equals(container, "3gp", StringComparison.OrdinalIgnoreCase)) { - var val = ResolveVideo3GPFormat(videoCodec, audioCodec); + MediaFormatProfile? val = ResolveVideo3GPFormat(videoCodec, audioCodec); return val.HasValue ? new List<MediaFormatProfile> { val.Value } : new List<MediaFormatProfile>(); } @@ -63,7 +62,7 @@ namespace MediaBrowser.Model.Dlna private IEnumerable<MediaFormatProfile> ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType) { - var suffix = ""; + string suffix = ""; switch (timestampType) { @@ -75,7 +74,7 @@ namespace MediaBrowser.Model.Dlna break; } - var resolution = "S"; + string resolution = "S"; if ((width.HasValue && width.Value > 720) || (height.HasValue && height.Value > 576)) { resolution = "H"; @@ -83,7 +82,7 @@ namespace MediaBrowser.Model.Dlna if (string.Equals(videoCodec, "mpeg2video", StringComparison.OrdinalIgnoreCase)) { - var list = new List<MediaFormatProfile>(); + List<MediaFormatProfile> list = new List<MediaFormatProfile>(); list.Add(ValueOf("MPEG_TS_SD_NA" + suffix)); list.Add(ValueOf("MPEG_TS_SD_EU" + suffix)); diff --git a/MediaBrowser.Model/Dlna/ProfileCondition.cs b/MediaBrowser.Model/Dlna/ProfileCondition.cs new file mode 100644 index 0000000000..24733426c8 --- /dev/null +++ b/MediaBrowser.Model/Dlna/ProfileCondition.cs @@ -0,0 +1,24 @@ +using System.Xml.Serialization; + +namespace MediaBrowser.Model.Dlna +{ + public class ProfileCondition + { + [XmlAttribute("condition")] + public ProfileConditionType Condition { get; set; } + + [XmlAttribute("property")] + public ProfileConditionValue Property { get; set; } + + [XmlAttribute("value")] + public string Value { get; set; } + + [XmlAttribute("isRequired")] + public bool IsRequired { get; set; } + + public ProfileCondition() + { + IsRequired = true; + } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/ProfileConditionType.cs b/MediaBrowser.Model/Dlna/ProfileConditionType.cs new file mode 100644 index 0000000000..22156c47d7 --- /dev/null +++ b/MediaBrowser.Model/Dlna/ProfileConditionType.cs @@ -0,0 +1,10 @@ +namespace MediaBrowser.Model.Dlna +{ + public enum ProfileConditionType + { + Equals = 0, + NotEquals = 1, + LessThanEqual = 2, + GreaterThanEqual = 3 + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs new file mode 100644 index 0000000000..56a322f5ad --- /dev/null +++ b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs @@ -0,0 +1,19 @@ +namespace MediaBrowser.Model.Dlna +{ + public enum ProfileConditionValue + { + AudioChannels, + AudioBitrate, + AudioProfile, + Width, + Height, + Has64BitOffsets, + PacketLength, + VideoBitDepth, + VideoBitrate, + VideoFramerate, + VideoLevel, + VideoProfile, + VideoTimestamp + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/ResponseProfile.cs b/MediaBrowser.Model/Dlna/ResponseProfile.cs index e84095ffe5..c1735f3b7c 100644 --- a/MediaBrowser.Model/Dlna/ResponseProfile.cs +++ b/MediaBrowser.Model/Dlna/ResponseProfile.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using System.Xml.Serialization; namespace MediaBrowser.Model.Dlna @@ -33,17 +32,32 @@ namespace MediaBrowser.Model.Dlna public List<string> GetContainers() { - return (Container ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (Container ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) list.Add(i); + } + return list; } - + public List<string> GetAudioCodecs() { - return (AudioCodec ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (AudioCodec ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) list.Add(i); + } + return list; } public List<string> GetVideoCodecs() { - return (VideoCodec ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (VideoCodec ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) list.Add(i); + } + return list; } } } diff --git a/MediaBrowser.Model/Dlna/SearchCriteria.cs b/MediaBrowser.Model/Dlna/SearchCriteria.cs index d3f8b83322..bb4221b513 100644 --- a/MediaBrowser.Model/Dlna/SearchCriteria.cs +++ b/MediaBrowser.Model/Dlna/SearchCriteria.cs @@ -37,13 +37,4 @@ namespace MediaBrowser.Model.Dlna } } } - - public enum SearchType - { - Unknown = 0, - Audio = 1, - Image = 2, - Video = 3, - Playlist = 4 - } } diff --git a/MediaBrowser.Model/Dlna/SearchType.cs b/MediaBrowser.Model/Dlna/SearchType.cs new file mode 100644 index 0000000000..68c047603d --- /dev/null +++ b/MediaBrowser.Model/Dlna/SearchType.cs @@ -0,0 +1,11 @@ +namespace MediaBrowser.Model.Dlna +{ + public enum SearchType + { + Unknown = 0, + Audio = 1, + Image = 2, + Video = 3, + Playlist = 4 + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 21441d36af..48356ef924 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -16,22 +16,27 @@ namespace MediaBrowser.Model.Dlna { ValidateAudioInput(options); - var mediaSources = options.MediaSources; + List<MediaSourceInfo> mediaSources = options.MediaSources; // If the client wants a specific media soure, filter now if (!string.IsNullOrEmpty(options.MediaSourceId)) { // Avoid implicitly captured closure - var mediaSourceId = options.MediaSourceId; + string mediaSourceId = options.MediaSourceId; - mediaSources = mediaSources - .Where(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)) - .ToList(); + mediaSources = new List<MediaSourceInfo>(); + foreach (MediaSourceInfo i in mediaSources) + { + if (string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)) + mediaSources.Add(i); + } } - var streams = mediaSources.Select(i => BuildAudioItem(i, options)).ToList(); + List<StreamInfo> streams = new List<StreamInfo>(); + foreach (MediaSourceInfo i in mediaSources) + streams.Add(BuildAudioItem(i, options)); - foreach (var stream in streams) + foreach (StreamInfo stream in streams) { stream.DeviceId = options.DeviceId; stream.DeviceProfileId = options.Profile.Id; @@ -44,22 +49,27 @@ namespace MediaBrowser.Model.Dlna { ValidateInput(options); - var mediaSources = options.MediaSources; + List<MediaSourceInfo> mediaSources = options.MediaSources; // If the client wants a specific media soure, filter now if (!string.IsNullOrEmpty(options.MediaSourceId)) { // Avoid implicitly captured closure - var mediaSourceId = options.MediaSourceId; + string mediaSourceId = options.MediaSourceId; - mediaSources = mediaSources - .Where(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)) - .ToList(); + mediaSources = new List<MediaSourceInfo>(); + foreach (MediaSourceInfo i in mediaSources) + { + if (string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)) + mediaSources.Add(i); + } } - var streams = mediaSources.Select(i => BuildVideoItem(i, options)).ToList(); + List<StreamInfo> streams = new List<StreamInfo>(); + foreach (MediaSourceInfo i in mediaSources) + streams.Add(BuildVideoItem(i, options)); - foreach (var stream in streams) + foreach (StreamInfo stream in streams) { stream.DeviceId = options.DeviceId; stream.DeviceProfileId = options.Profile.Id; @@ -72,13 +82,24 @@ namespace MediaBrowser.Model.Dlna { // Grab the first one that can be direct streamed // If that doesn't produce anything, just take the first - return streams.FirstOrDefault(i => i.IsDirectStream) ?? - streams.FirstOrDefault(); + foreach (StreamInfo i in streams) + { + if (i.IsDirectStream) + { + return i; + } + } + + foreach (StreamInfo stream in streams) + { + return stream; + } + return null; } private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options) { - var playlistItem = new StreamInfo + StreamInfo playlistItem = new StreamInfo { ItemId = options.ItemId, MediaType = DlnaProfileType.Audio, @@ -86,32 +107,53 @@ namespace MediaBrowser.Model.Dlna RunTimeTicks = item.RunTimeTicks }; - var maxBitrateSetting = options.MaxBitrate ?? options.Profile.MaxBitrate; + int? maxBitrateSetting = options.MaxBitrate ?? options.Profile.MaxBitrate; - var audioStream = item.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); + MediaStream audioStream = item.DefaultAudioStream; // Honor the max bitrate setting if (IsAudioEligibleForDirectPlay(item, maxBitrateSetting)) { - var directPlay = options.Profile.DirectPlayProfiles - .FirstOrDefault(i => i.Type == playlistItem.MediaType && IsAudioDirectPlaySupported(i, item, audioStream)); + DirectPlayProfile directPlay = null; + foreach (DirectPlayProfile i in options.Profile.DirectPlayProfiles) + { + if (i.Type == playlistItem.MediaType && IsAudioDirectPlaySupported(i, item, audioStream)) + { + directPlay = i; + break; + } + } if (directPlay != null) { - var audioCodec = audioStream == null ? null : audioStream.Codec; + string audioCodec = audioStream == null ? null : audioStream.Codec; // Make sure audio codec profiles are satisfied if (!string.IsNullOrEmpty(audioCodec)) { - var conditionProcessor = new ConditionProcessor(); + ConditionProcessor conditionProcessor = new ConditionProcessor(); + + List<ProfileCondition> conditions = new List<ProfileCondition>(); + foreach (CodecProfile i in options.Profile.CodecProfiles) + { + if (i.Type == CodecType.Audio && i.ContainsCodec(audioCodec)) + conditions.AddRange(i.Conditions); + } - var conditions = options.Profile.CodecProfiles.Where(i => i.Type == CodecType.Audio && i.ContainsCodec(audioCodec)) - .SelectMany(i => i.Conditions); + int? audioChannels = audioStream.Channels; + int? audioBitrate = audioStream.BitRate; - var audioChannels = audioStream == null ? null : audioStream.Channels; - var audioBitrate = audioStream == null ? null : audioStream.BitRate; + bool all = true; + foreach (ProfileCondition c in conditions) + { + if (!conditionProcessor.IsAudioConditionSatisfied(c, audioChannels, audioBitrate)) + { + all = false; + break; + } + } - if (conditions.All(c => conditionProcessor.IsAudioConditionSatisfied(c, audioChannels, audioBitrate))) + if (all) { playlistItem.IsDirectStream = true; playlistItem.Container = item.Container; @@ -122,8 +164,15 @@ namespace MediaBrowser.Model.Dlna } } - var transcodingProfile = options.Profile.TranscodingProfiles - .FirstOrDefault(i => i.Type == playlistItem.MediaType); + TranscodingProfile transcodingProfile = null; + foreach (TranscodingProfile i in options.Profile.TranscodingProfiles) + { + if (i.Type == playlistItem.MediaType) + { + transcodingProfile = i; + break; + } + } if (transcodingProfile != null) { @@ -134,17 +183,27 @@ namespace MediaBrowser.Model.Dlna playlistItem.AudioCodec = transcodingProfile.AudioCodec; playlistItem.Protocol = transcodingProfile.Protocol; - var audioTranscodingConditions = options.Profile.CodecProfiles - .Where(i => i.Type == CodecType.Audio && i.ContainsCodec(transcodingProfile.AudioCodec)) - .Take(1) - .SelectMany(i => i.Conditions); + List<CodecProfile> audioCodecProfiles = new List<CodecProfile>(); + foreach (CodecProfile i in options.Profile.CodecProfiles) + { + if (i.Type == CodecType.Audio && i.ContainsCodec(transcodingProfile.AudioCodec)) + { + audioCodecProfiles.Add(i); + } + + if (audioCodecProfiles.Count >= 1) break; + } + + List<ProfileCondition> audioTranscodingConditions = new List<ProfileCondition>(); + foreach (CodecProfile i in audioCodecProfiles) + audioTranscodingConditions.AddRange(i.Conditions); ApplyTranscodingConditions(playlistItem, audioTranscodingConditions); // Honor requested max channels if (options.MaxAudioChannels.HasValue) { - var currentValue = playlistItem.MaxAudioChannels ?? options.MaxAudioChannels.Value; + int currentValue = playlistItem.MaxAudioChannels ?? options.MaxAudioChannels.Value; playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue); } @@ -152,7 +211,7 @@ namespace MediaBrowser.Model.Dlna // Honor requested max bitrate if (maxBitrateSetting.HasValue) { - var currentValue = playlistItem.AudioBitrate ?? maxBitrateSetting.Value; + int currentValue = playlistItem.AudioBitrate ?? maxBitrateSetting.Value; playlistItem.AudioBitrate = Math.Min(maxBitrateSetting.Value, currentValue); } @@ -163,7 +222,7 @@ namespace MediaBrowser.Model.Dlna private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options) { - var playlistItem = new StreamInfo + StreamInfo playlistItem = new StreamInfo { ItemId = options.ItemId, MediaType = DlnaProfileType.Video, @@ -171,15 +230,15 @@ namespace MediaBrowser.Model.Dlna RunTimeTicks = item.RunTimeTicks }; - var audioStream = item.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); - var videoStream = item.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); + MediaStream audioStream = item.DefaultAudioStream; + MediaStream videoStream = item.VideoStream; - var maxBitrateSetting = options.MaxBitrate ?? options.Profile.MaxBitrate; + int? maxBitrateSetting = options.MaxBitrate ?? options.Profile.MaxBitrate; if (IsEligibleForDirectPlay(item, options, maxBitrateSetting)) { // See if it can be direct played - var directPlay = GetVideoDirectPlayProfile(options.Profile, item, videoStream, audioStream); + DirectPlayProfile directPlay = GetVideoDirectPlayProfile(options.Profile, item, videoStream, audioStream); if (directPlay != null) { @@ -191,8 +250,15 @@ namespace MediaBrowser.Model.Dlna } // Can't direct play, find the transcoding profile - var transcodingProfile = options.Profile.TranscodingProfiles - .FirstOrDefault(i => i.Type == playlistItem.MediaType); + TranscodingProfile transcodingProfile = null; + foreach (TranscodingProfile i in options.Profile.TranscodingProfiles) + { + if (i.Type == playlistItem.MediaType) + { + transcodingProfile = i; + break; + } + } if (transcodingProfile != null) { @@ -200,30 +266,38 @@ namespace MediaBrowser.Model.Dlna playlistItem.Container = transcodingProfile.Container; playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength; playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo; - playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',').FirstOrDefault(); + playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',')[0]; playlistItem.VideoCodec = transcodingProfile.VideoCodec; playlistItem.Protocol = transcodingProfile.Protocol; playlistItem.AudioStreamIndex = options.AudioStreamIndex; playlistItem.SubtitleStreamIndex = options.SubtitleStreamIndex; - var videoTranscodingConditions = options.Profile.CodecProfiles - .Where(i => i.Type == CodecType.Video && i.ContainsCodec(transcodingProfile.VideoCodec)) - .Take(1) - .SelectMany(i => i.Conditions); - + List<ProfileCondition> videoTranscodingConditions = new List<ProfileCondition>(); + foreach (CodecProfile i in options.Profile.CodecProfiles) + { + if (i.Type == CodecType.Video && i.ContainsCodec(transcodingProfile.VideoCodec)) + { + videoTranscodingConditions.AddRange(i.Conditions); + break; + } + } ApplyTranscodingConditions(playlistItem, videoTranscodingConditions); - var audioTranscodingConditions = options.Profile.CodecProfiles - .Where(i => i.Type == CodecType.VideoAudio && i.ContainsCodec(transcodingProfile.AudioCodec)) - .Take(1) - .SelectMany(i => i.Conditions); - + List<ProfileCondition> audioTranscodingConditions = new List<ProfileCondition>(); + foreach (CodecProfile i in options.Profile.CodecProfiles) + { + if (i.Type == CodecType.VideoAudio && i.ContainsCodec(transcodingProfile.AudioCodec)) + { + audioTranscodingConditions.AddRange(i.Conditions); + break; + } + } ApplyTranscodingConditions(playlistItem, audioTranscodingConditions); // Honor requested max channels if (options.MaxAudioChannels.HasValue) { - var currentValue = playlistItem.MaxAudioChannels ?? options.MaxAudioChannels.Value; + int currentValue = playlistItem.MaxAudioChannels ?? options.MaxAudioChannels.Value; playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue); } @@ -231,7 +305,7 @@ namespace MediaBrowser.Model.Dlna // Honor requested max bitrate if (options.MaxAudioTranscodingBitrate.HasValue) { - var currentValue = playlistItem.AudioBitrate ?? options.MaxAudioTranscodingBitrate.Value; + int currentValue = playlistItem.AudioBitrate ?? options.MaxAudioTranscodingBitrate.Value; playlistItem.AudioBitrate = Math.Min(options.MaxAudioTranscodingBitrate.Value, currentValue); } @@ -239,14 +313,14 @@ namespace MediaBrowser.Model.Dlna // Honor max rate if (maxBitrateSetting.HasValue) { - var videoBitrate = maxBitrateSetting.Value; + int videoBitrate = maxBitrateSetting.Value; if (playlistItem.AudioBitrate.HasValue) { videoBitrate -= playlistItem.AudioBitrate.Value; } - var currentValue = playlistItem.VideoBitrate ?? videoBitrate; + int currentValue = playlistItem.VideoBitrate ?? videoBitrate; playlistItem.VideoBitrate = Math.Min(videoBitrate, currentValue); } @@ -261,100 +335,103 @@ namespace MediaBrowser.Model.Dlna MediaStream audioStream) { // See if it can be direct played - var directPlay = profile.DirectPlayProfiles - .FirstOrDefault(i => i.Type == DlnaProfileType.Video && IsVideoDirectPlaySupported(i, mediaSource, videoStream, audioStream)); + DirectPlayProfile directPlay = null; + foreach (DirectPlayProfile i in profile.DirectPlayProfiles) + { + if (i.Type == DlnaProfileType.Video && IsVideoDirectPlaySupported(i, mediaSource, videoStream, audioStream)) + { + directPlay = i; + break; + } + } if (directPlay == null) { return null; } - var container = mediaSource.Container; + string container = mediaSource.Container; - var conditions = profile.ContainerProfiles - .Where(i => i.Type == DlnaProfileType.Video && i.GetContainers().Contains(container, StringComparer.OrdinalIgnoreCase)) - .SelectMany(i => i.Conditions); + List<ProfileCondition> conditions = new List<ProfileCondition>(); + foreach (ContainerProfile i in profile.ContainerProfiles) + { + if (i.Type == DlnaProfileType.Video && + i.GetContainers().Contains(container, StringComparer.OrdinalIgnoreCase)) + { + conditions.AddRange(i.Conditions); + } + } - var conditionProcessor = new ConditionProcessor(); + ConditionProcessor conditionProcessor = new ConditionProcessor(); - var width = videoStream == null ? null : videoStream.Width; - var height = videoStream == null ? null : videoStream.Height; - var bitDepth = videoStream == null ? null : videoStream.BitDepth; - var videoBitrate = videoStream == null ? null : videoStream.BitRate; - var videoLevel = videoStream == null ? null : videoStream.Level; - var videoProfile = videoStream == null ? null : videoStream.Profile; - var videoFramerate = videoStream == null ? null : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate; + 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; + float? videoFramerate = videoStream == null ? null : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate; - var audioBitrate = audioStream == null ? null : audioStream.BitRate; - var audioChannels = audioStream == null ? null : audioStream.Channels; - var audioProfile = audioStream == null ? null : audioStream.Profile; + int? audioBitrate = audioStream == null ? null : audioStream.BitRate; + int? audioChannels = audioStream == null ? null : audioStream.Channels; + string audioProfile = audioStream == null ? null : audioStream.Profile; - var timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp; - var packetLength = videoStream == null ? null : videoStream.PacketLength; + TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp; + int? packetLength = videoStream == null ? null : videoStream.PacketLength; // Check container conditions - if (!conditions.All(i => conditionProcessor.IsVideoConditionSatisfied(i, - audioBitrate, - audioChannels, - width, - height, - bitDepth, - videoBitrate, - videoProfile, - videoLevel, - videoFramerate, - packetLength, - timestamp))) + foreach (ProfileCondition i in conditions) { - return null; + if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp)) + { + return null; + } } - var videoCodec = videoStream == null ? null : videoStream.Codec; + string videoCodec = videoStream == null ? null : videoStream.Codec; if (string.IsNullOrEmpty(videoCodec)) { return null; } - conditions = profile.CodecProfiles - .Where(i => i.Type == CodecType.Video && i.ContainsCodec(videoCodec)) - .SelectMany(i => i.Conditions); + conditions = new List<ProfileCondition>(); + foreach (CodecProfile i in profile.CodecProfiles) + { + if (i.Type == CodecType.Video && i.ContainsCodec(videoCodec)) + conditions.AddRange(i.Conditions); + } - if (!conditions.All(i => conditionProcessor.IsVideoConditionSatisfied(i, - audioBitrate, - audioChannels, - width, - height, - bitDepth, - videoBitrate, - videoProfile, - videoLevel, - videoFramerate, - packetLength, - timestamp))) + foreach (ProfileCondition i in conditions) { - return null; + if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp)) + { + return null; + } } if (audioStream != null) { - var audioCodec = audioStream.Codec; + string audioCodec = audioStream.Codec; if (string.IsNullOrEmpty(audioCodec)) { return null; } - conditions = profile.CodecProfiles - .Where(i => i.Type == CodecType.VideoAudio && i.ContainsCodec(audioCodec)) - .SelectMany(i => i.Conditions); + conditions = new List<ProfileCondition>(); + foreach (CodecProfile i in profile.CodecProfiles) + { + if (i.Type == CodecType.VideoAudio && i.ContainsCodec(audioCodec)) + conditions.AddRange(i.Conditions); + } - if (!conditions.All(i => conditionProcessor.IsVideoAudioConditionSatisfied(i, - audioChannels, - audioBitrate, - audioProfile))) + foreach (ProfileCondition i in conditions) { - return null; + if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioProfile)) + { + return null; + } } } @@ -368,12 +445,6 @@ namespace MediaBrowser.Model.Dlna return false; } - if (options.AudioStreamIndex.HasValue && - item.MediaStreams.Count(i => i.Type == MediaStreamType.Audio) > 1) - { - return false; - } - return IsAudioEligibleForDirectPlay(item, maxBitrate); } @@ -420,10 +491,14 @@ namespace MediaBrowser.Model.Dlna private void ApplyTranscodingConditions(StreamInfo item, IEnumerable<ProfileCondition> conditions) { - foreach (var condition in conditions - .Where(i => !string.IsNullOrEmpty(i.Value))) + foreach (ProfileCondition condition in conditions) { - var value = condition.Value; + string value = condition.Value; + + if (string.IsNullOrEmpty(value)) + { + continue; + } switch (condition.Property) { @@ -515,8 +590,17 @@ namespace MediaBrowser.Model.Dlna if (profile.Container.Length > 0) { // Check container type - var mediaContainer = item.Container ?? string.Empty; - if (!profile.GetContainers().Any(i => string.Equals(i, mediaContainer, StringComparison.OrdinalIgnoreCase))) + string mediaContainer = item.Container ?? string.Empty; + bool any = false; + foreach (string i in profile.GetContainers()) + { + if (string.Equals(i, mediaContainer, StringComparison.OrdinalIgnoreCase)) + { + any = true; + break; + } + } + if (!any) { return false; } @@ -536,29 +620,38 @@ namespace MediaBrowser.Model.Dlna if (profile.Container.Length > 0) { // Check container type - var mediaContainer = item.Container ?? string.Empty; - if (!profile.GetContainers().Any(i => string.Equals(i, mediaContainer, StringComparison.OrdinalIgnoreCase))) + string mediaContainer = item.Container ?? string.Empty; + bool any = false; + foreach (string i in profile.GetContainers()) + { + if (string.Equals(i, mediaContainer, StringComparison.OrdinalIgnoreCase)) + { + any = true; + break; + } + } + if (!any) { return false; } } // Check video codec - var videoCodecs = profile.GetVideoCodecs(); + List<string> videoCodecs = profile.GetVideoCodecs(); if (videoCodecs.Count > 0) { - var videoCodec = videoStream == null ? null : videoStream.Codec; + string videoCodec = videoStream == null ? null : videoStream.Codec; if (string.IsNullOrEmpty(videoCodec) || !videoCodecs.Contains(videoCodec, StringComparer.OrdinalIgnoreCase)) { return false; } } - var audioCodecs = profile.GetAudioCodecs(); + List<string> audioCodecs = profile.GetAudioCodecs(); if (audioCodecs.Count > 0) { // Check audio codecs - var audioCodec = audioStream == null ? null : audioStream.Codec; + string audioCodec = audioStream == null ? null : audioStream.Codec; if (string.IsNullOrEmpty(audioCodec) || !audioCodecs.Contains(audioCodec, StringComparer.OrdinalIgnoreCase)) { return false; diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index fe49227e40..e4ec0d8539 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -1,11 +1,10 @@ using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; using System.Globalization; -using System.Linq; -using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Model.Dlna { @@ -79,9 +78,9 @@ namespace MediaBrowser.Model.Dlna throw new ArgumentNullException(baseUrl); } - var dlnaCommand = BuildDlnaParam(this); + string dlnaCommand = BuildDlnaParam(this); - var extension = string.IsNullOrEmpty(Container) ? string.Empty : "." + Container; + string extension = string.IsNullOrEmpty(Container) ? string.Empty : "." + Container; baseUrl = baseUrl.TrimEnd('/'); @@ -98,11 +97,11 @@ namespace MediaBrowser.Model.Dlna return string.Format("{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, dlnaCommand); } + private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); + private static string BuildDlnaParam(StreamInfo item) { - var usCulture = new CultureInfo("en-US"); - - var list = new List<string> + List<string> list = new List<string> { item.DeviceProfileId ?? string.Empty, item.DeviceId ?? string.Empty, @@ -110,16 +109,16 @@ namespace MediaBrowser.Model.Dlna (item.IsDirectStream).ToString().ToLower(), item.VideoCodec ?? string.Empty, item.AudioCodec ?? string.Empty, - item.AudioStreamIndex.HasValue ? item.AudioStreamIndex.Value.ToString(usCulture) : string.Empty, - item.SubtitleStreamIndex.HasValue ? item.SubtitleStreamIndex.Value.ToString(usCulture) : string.Empty, - item.VideoBitrate.HasValue ? item.VideoBitrate.Value.ToString(usCulture) : string.Empty, - item.AudioBitrate.HasValue ? item.AudioBitrate.Value.ToString(usCulture) : string.Empty, - item.MaxAudioChannels.HasValue ? item.MaxAudioChannels.Value.ToString(usCulture) : string.Empty, - item.MaxFramerate.HasValue ? item.MaxFramerate.Value.ToString(usCulture) : string.Empty, - item.MaxWidth.HasValue ? item.MaxWidth.Value.ToString(usCulture) : string.Empty, - item.MaxHeight.HasValue ? item.MaxHeight.Value.ToString(usCulture) : string.Empty, - item.StartPositionTicks.ToString(usCulture), - item.VideoLevel.HasValue ? item.VideoLevel.Value.ToString(usCulture) : string.Empty + item.AudioStreamIndex.HasValue ? item.AudioStreamIndex.Value.ToString(UsCulture) : string.Empty, + item.SubtitleStreamIndex.HasValue ? item.SubtitleStreamIndex.Value.ToString(UsCulture) : string.Empty, + item.VideoBitrate.HasValue ? item.VideoBitrate.Value.ToString(UsCulture) : string.Empty, + item.AudioBitrate.HasValue ? item.AudioBitrate.Value.ToString(UsCulture) : string.Empty, + item.MaxAudioChannels.HasValue ? item.MaxAudioChannels.Value.ToString(UsCulture) : string.Empty, + item.MaxFramerate.HasValue ? item.MaxFramerate.Value.ToString(UsCulture) : string.Empty, + item.MaxWidth.HasValue ? item.MaxWidth.Value.ToString(UsCulture) : string.Empty, + item.MaxHeight.HasValue ? item.MaxHeight.Value.ToString(UsCulture) : string.Empty, + item.StartPositionTicks.ToString(UsCulture), + item.VideoLevel.HasValue ? item.VideoLevel.Value.ToString(UsCulture) : string.Empty }; return string.Format("Params={0}", string.Join(";", list.ToArray())); @@ -134,14 +133,17 @@ namespace MediaBrowser.Model.Dlna { if (MediaSource != null) { - var audioStreams = MediaSource.MediaStreams.Where(i => i.Type == MediaStreamType.Audio); - if (AudioStreamIndex.HasValue) { - return audioStreams.FirstOrDefault(i => i.Index == AudioStreamIndex.Value); + foreach (MediaStream i in MediaSource.MediaStreams) + { + if (i.Index == AudioStreamIndex.Value && i.Type == MediaStreamType.Audio) + return i; + } + return null; } - return audioStreams.FirstOrDefault(); + return MediaSource.DefaultAudioStream; } return null; @@ -157,8 +159,7 @@ namespace MediaBrowser.Model.Dlna { if (MediaSource != null) { - return MediaSource.MediaStreams - .FirstOrDefault(i => i.Type == MediaStreamType.Video && (i.Codec ?? string.Empty).IndexOf("jpeg", StringComparison.OrdinalIgnoreCase) == -1); + return MediaSource.VideoStream; } return null; @@ -172,7 +173,7 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetAudioStream; + MediaStream stream = TargetAudioStream; return stream == null ? null : stream.SampleRate; } } @@ -184,7 +185,7 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetVideoStream; + MediaStream stream = TargetVideoStream; return stream == null || !IsDirectStream ? null : stream.BitDepth; } } @@ -196,7 +197,7 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetVideoStream; + MediaStream stream = TargetVideoStream; return MaxFramerate.HasValue && !IsDirectStream ? MaxFramerate : stream == null ? null : stream.AverageFrameRate ?? stream.RealFrameRate; @@ -210,7 +211,7 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetVideoStream; + MediaStream stream = TargetVideoStream; return VideoLevel.HasValue && !IsDirectStream ? VideoLevel : stream == null ? null : stream.Level; @@ -224,7 +225,7 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetVideoStream; + MediaStream stream = TargetVideoStream; return !IsDirectStream ? null : stream == null ? null : stream.PacketLength; @@ -238,7 +239,7 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetVideoStream; + MediaStream stream = TargetVideoStream; return !string.IsNullOrEmpty(VideoProfile) && !IsDirectStream ? VideoProfile : stream == null ? null : stream.Profile; @@ -252,7 +253,7 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetAudioStream; + MediaStream stream = TargetAudioStream; return AudioBitrate.HasValue && !IsDirectStream ? AudioBitrate : stream == null ? null : stream.BitRate; @@ -266,8 +267,8 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetAudioStream; - var streamChannels = stream == null ? null : stream.Channels; + MediaStream stream = TargetAudioStream; + int? streamChannels = stream == null ? null : stream.Channels; return MaxAudioChannels.HasValue && !IsDirectStream ? (streamChannels.HasValue ? Math.Min(MaxAudioChannels.Value, streamChannels.Value) : MaxAudioChannels.Value) @@ -282,7 +283,7 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetAudioStream; + MediaStream stream = TargetAudioStream; return IsDirectStream ? (stream == null ? null : stream.Codec) @@ -304,10 +305,10 @@ namespace MediaBrowser.Model.Dlna if (RunTimeTicks.HasValue) { - var totalBitrate = TargetTotalBitrate; + int? totalBitrate = TargetTotalBitrate; return totalBitrate.HasValue ? - Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(RunTimeTicks.Value).TotalSeconds) : + Convert.ToInt64(totalBitrate.Value * TimeSpan.FromTicks(RunTimeTicks.Value).TotalSeconds) : (long?)null; } @@ -319,7 +320,7 @@ namespace MediaBrowser.Model.Dlna { get { - var stream = TargetVideoStream; + MediaStream stream = TargetVideoStream; return VideoBitrate.HasValue && !IsDirectStream ? VideoBitrate @@ -331,7 +332,7 @@ namespace MediaBrowser.Model.Dlna { get { - var defaultValue = string.Equals(Container, "m2ts", StringComparison.OrdinalIgnoreCase) + TransportStreamTimestamp defaultValue = string.Equals(Container, "m2ts", StringComparison.OrdinalIgnoreCase) ? TransportStreamTimestamp.Valid : TransportStreamTimestamp.None; @@ -353,17 +354,17 @@ namespace MediaBrowser.Model.Dlna { get { - var videoStream = TargetVideoStream; + MediaStream videoStream = TargetVideoStream; if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue) { - var size = new ImageSize + ImageSize size = new ImageSize { Width = videoStream.Width.Value, Height = videoStream.Height.Value }; - var newSize = DrawingUtils.Resize(size, + ImageSize newSize = DrawingUtils.Resize(size, null, null, MaxWidth, @@ -380,17 +381,17 @@ namespace MediaBrowser.Model.Dlna { get { - var videoStream = TargetVideoStream; + MediaStream videoStream = TargetVideoStream; if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue) { - var size = new ImageSize + ImageSize size = new ImageSize { Width = videoStream.Width.Value, Height = videoStream.Height.Value }; - var newSize = DrawingUtils.Resize(size, + ImageSize newSize = DrawingUtils.Resize(size, null, null, MaxWidth, @@ -403,47 +404,4 @@ namespace MediaBrowser.Model.Dlna } } } - - /// <summary> - /// Class AudioOptions. - /// </summary> - public class AudioOptions - { - public string ItemId { get; set; } - public List<MediaSourceInfo> MediaSources { get; set; } - public DeviceProfile Profile { get; set; } - - /// <summary> - /// Optional. Only needed if a specific AudioStreamIndex or SubtitleStreamIndex are requested. - /// </summary> - public string MediaSourceId { get; set; } - - public string DeviceId { get; set; } - - /// <summary> - /// Allows an override of supported number of audio channels - /// Example: DeviceProfile supports five channel, but user only has stereo speakers - /// </summary> - public int? MaxAudioChannels { get; set; } - - /// <summary> - /// The application's configured quality setting - /// </summary> - public int? MaxBitrate { get; set; } - } - - /// <summary> - /// Class VideoOptions. - /// </summary> - public class VideoOptions : AudioOptions - { - public int? AudioStreamIndex { get; set; } - public int? SubtitleStreamIndex { get; set; } - public int? MaxAudioTranscodingBitrate { get; set; } - - public VideoOptions() - { - MaxAudioTranscodingBitrate = 128000; - } - } } diff --git a/MediaBrowser.Model/Dlna/TranscodeSeekInfo.cs b/MediaBrowser.Model/Dlna/TranscodeSeekInfo.cs new file mode 100644 index 0000000000..564ce5c605 --- /dev/null +++ b/MediaBrowser.Model/Dlna/TranscodeSeekInfo.cs @@ -0,0 +1,8 @@ +namespace MediaBrowser.Model.Dlna +{ + public enum TranscodeSeekInfo + { + Auto = 0, + Bytes = 1 + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs index ba02e9be25..51f4bfe619 100644 --- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using System.Xml.Serialization; namespace MediaBrowser.Model.Dlna @@ -35,13 +34,12 @@ namespace MediaBrowser.Model.Dlna public List<string> GetAudioCodecs() { - return (AudioCodec ?? string.Empty).Split(',').Where(i => !string.IsNullOrEmpty(i)).ToList(); + List<string> list = new List<string>(); + foreach (string i in (AudioCodec ?? string.Empty).Split(',')) + { + if (!string.IsNullOrEmpty(i)) list.Add(i); + } + return list; } } - - public enum TranscodeSeekInfo - { - Auto = 0, - Bytes = 1 - } } diff --git a/MediaBrowser.Model/Dlna/VideoOptions.cs b/MediaBrowser.Model/Dlna/VideoOptions.cs new file mode 100644 index 0000000000..39a5ab1b1c --- /dev/null +++ b/MediaBrowser.Model/Dlna/VideoOptions.cs @@ -0,0 +1,17 @@ +namespace MediaBrowser.Model.Dlna +{ + /// <summary> + /// Class VideoOptions. + /// </summary> + public class VideoOptions : AudioOptions + { + public int? AudioStreamIndex { get; set; } + public int? SubtitleStreamIndex { get; set; } + public int? MaxAudioTranscodingBitrate { get; set; } + + public VideoOptions() + { + MaxAudioTranscodingBitrate = 128000; + } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/XmlAttribute.cs b/MediaBrowser.Model/Dlna/XmlAttribute.cs new file mode 100644 index 0000000000..e8e13ba0de --- /dev/null +++ b/MediaBrowser.Model/Dlna/XmlAttribute.cs @@ -0,0 +1,13 @@ +using System.Xml.Serialization; + +namespace MediaBrowser.Model.Dlna +{ + public class XmlAttribute + { + [XmlAttribute("name")] + public string Name { get; set; } + + [XmlAttribute("value")] + public string Value { get; set; } + } +}
\ No newline at end of file |
