#nullable disable #pragma warning disable CA1819 // Properties should not return arrays using System; using System.Linq; using System.Xml.Serialization; using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Model.Dlna { /// /// Defines the . /// [XmlRoot("Profile")] public class DeviceProfile { /// /// Initializes a new instance of the class. /// public DeviceProfile() { DirectPlayProfiles = Array.Empty(); TranscodingProfiles = Array.Empty(); ResponseProfiles = Array.Empty(); CodecProfiles = Array.Empty(); ContainerProfiles = Array.Empty(); SubtitleProfiles = Array.Empty(); XmlRootAttributes = Array.Empty(); SupportedMediaTypes = "Audio,Photo,Video"; MaxStreamingBitrate = 8000000; MaxStaticBitrate = 8000000; MusicStreamingTranscodingBitrate = 128000; } /// /// Gets or sets the Name. /// public string Name { get; set; } /// /// Gets or sets the Id. /// [XmlIgnore] public string Id { get; set; } /// /// Gets or sets the Identification. /// public DeviceIdentification Identification { get; set; } /// /// Gets or sets the FriendlyName. /// public string FriendlyName { get; set; } /// /// Gets or sets the Manufacturer. /// public string Manufacturer { get; set; } /// /// Gets or sets the ManufacturerUrl. /// public string ManufacturerUrl { get; set; } /// /// Gets or sets the ModelName. /// public string ModelName { get; set; } /// /// Gets or sets the ModelDescription. /// public string ModelDescription { get; set; } /// /// Gets or sets the ModelNumber. /// public string ModelNumber { get; set; } /// /// Gets or sets the ModelUrl. /// public string ModelUrl { get; set; } /// /// Gets or sets the SerialNumber. /// public string SerialNumber { get; set; } /// /// Gets or sets a value indicating whether EnableAlbumArtInDidl. /// public bool EnableAlbumArtInDidl { get; set; } /// /// Gets or sets a value indicating whether EnableSingleAlbumArtLimit. /// public bool EnableSingleAlbumArtLimit { get; set; } /// /// Gets or sets a value indicating whether EnableSingleSubtitleLimit. /// public bool EnableSingleSubtitleLimit { get; set; } /// /// Gets or sets the SupportedMediaTypes. /// public string SupportedMediaTypes { get; set; } /// /// Gets or sets the UserId. /// public string UserId { get; set; } /// /// Gets or sets the AlbumArtPn. /// public string AlbumArtPn { get; set; } /// /// Gets or sets the MaxAlbumArtWidth. /// public int MaxAlbumArtWidth { get; set; } /// /// Gets or sets the MaxAlbumArtHeight. /// public int MaxAlbumArtHeight { get; set; } /// /// Gets or sets the MaxIconWidth. /// public int? MaxIconWidth { get; set; } /// /// Gets or sets the MaxIconHeight. /// public int? MaxIconHeight { get; set; } /// /// Gets or sets the MaxStreamingBitrate. /// public int? MaxStreamingBitrate { get; set; } /// /// Gets or sets the MaxStaticBitrate. /// public int? MaxStaticBitrate { get; set; } /// /// Gets or sets the MusicStreamingTranscodingBitrate. /// public int? MusicStreamingTranscodingBitrate { get; set; } /// /// Gets or sets the MaxStaticMusicBitrate. /// public int? MaxStaticMusicBitrate { get; set; } /// /// Gets or sets the content of the aggregationFlags element in the urn:schemas-sonycom:av namespace. /// public string SonyAggregationFlags { get; set; } /// /// Gets or sets the ProtocolInfo. /// public string ProtocolInfo { get; set; } /// /// Gets or sets the TimelineOffsetSeconds. /// public int TimelineOffsetSeconds { get; set; } /// /// Gets or sets a value indicating whether RequiresPlainVideoItems. /// public bool RequiresPlainVideoItems { get; set; } /// /// Gets or sets a value indicating whether RequiresPlainFolders. /// public bool RequiresPlainFolders { get; set; } /// /// Gets or sets a value indicating whether EnableMSMediaReceiverRegistrar. /// public bool EnableMSMediaReceiverRegistrar { get; set; } /// /// Gets or sets a value indicating whether IgnoreTranscodeByteRangeRequests. /// public bool IgnoreTranscodeByteRangeRequests { get; set; } /// /// Gets or sets the XmlRootAttributes. /// public XmlAttribute[] XmlRootAttributes { get; set; } /// /// Gets or sets the direct play profiles. /// public DirectPlayProfile[] DirectPlayProfiles { get; set; } /// /// Gets or sets the transcoding profiles. /// public TranscodingProfile[] TranscodingProfiles { get; set; } /// /// Gets or sets the ContainerProfiles. /// public ContainerProfile[] ContainerProfiles { get; set; } /// /// Gets or sets the CodecProfiles. /// public CodecProfile[] CodecProfiles { get; set; } /// /// Gets or sets the ResponseProfiles. /// public ResponseProfile[] ResponseProfiles { get; set; } /// /// Gets or sets the SubtitleProfiles. /// public SubtitleProfile[] SubtitleProfiles { get; set; } /// /// The GetSupportedMediaTypes. /// /// The . public string[] GetSupportedMediaTypes() { return ContainerProfile.SplitValue(SupportedMediaTypes); } /// /// Gets the audio transcoding profile. /// /// The container. /// The audio Codec. /// A . public TranscodingProfile GetAudioTranscodingProfile(string container, string audioCodec) { container = (container ?? string.Empty).TrimStart('.'); foreach (var i in TranscodingProfiles) { if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Audio) { continue; } if (!string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase)) { continue; } if (!i.GetAudioCodecs().Contains(audioCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { continue; } return i; } return null; } /// /// Gets the video transcoding profile. /// /// The container. /// The audio Codec. /// The video Codec. /// The . public TranscodingProfile GetVideoTranscodingProfile(string container, string audioCodec, string videoCodec) { container = (container ?? string.Empty).TrimStart('.'); foreach (var i in TranscodingProfiles) { if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Video) { continue; } if (!string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase)) { continue; } if (!i.GetAudioCodecs().Contains(audioCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { continue; } if (!string.Equals(videoCodec, i.VideoCodec ?? string.Empty, StringComparison.OrdinalIgnoreCase)) { continue; } return i; } return null; } /// /// Gets the audio media profile. /// /// The container. /// The audio codec. /// The audio channels. /// The audio bitrate. /// The audio sample rate. /// The audio bit depth. /// The . public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth) { foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Audio) { continue; } if (!ContainerProfile.ContainsContainer(i.GetContainers(), container)) { continue; } var audioCodecs = i.GetAudioCodecs(); if (audioCodecs.Length > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { continue; } var anyOff = false; foreach (ProfileCondition c in i.Conditions) { if (!ConditionProcessor.IsAudioConditionSatisfied(GetModelProfileCondition(c), audioChannels, audioBitrate, audioSampleRate, audioBitDepth)) { anyOff = true; break; } } if (anyOff) { continue; } return i; } return null; } /// /// Gets the model profile condition. /// /// The c. /// The . private ProfileCondition GetModelProfileCondition(ProfileCondition c) { return new ProfileCondition { Condition = c.Condition, IsRequired = c.IsRequired, Property = c.Property, Value = c.Value }; } /// /// Gets the image media profile. /// /// The container. /// The width. /// The height. /// The . public ResponseProfile GetImageMediaProfile(string container, int? width, int? height) { foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Photo) { continue; } if (!ContainerProfile.ContainsContainer(i.GetContainers(), container)) { continue; } var anyOff = false; foreach (var c in i.Conditions) { if (!ConditionProcessor.IsImageConditionSatisfied(GetModelProfileCondition(c), width, height)) { anyOff = true; break; } } if (anyOff) { continue; } return i; } return null; } /// /// Gets the video media profile. /// /// The container. /// The audio codec. /// The video codec. /// The width. /// The height. /// The bit depth. /// The video bitrate. /// The video profile. /// The video level. /// The video framerate. /// The packet length. /// The timestamp. /// True if anamorphic. /// True if interlaced. /// The ref frames. /// The number of video streams. /// The number of audio streams. /// The video Codec tag. /// True if Avc. /// The . public ResponseProfile GetVideoMediaProfile( string container, string audioCodec, string videoCodec, int? width, int? height, int? bitDepth, int? videoBitrate, string videoProfile, double? videoLevel, float? videoFramerate, int? packetLength, TransportStreamTimestamp timestamp, bool? isAnamorphic, bool? isInterlaced, int? refFrames, int? numVideoStreams, int? numAudioStreams, string videoCodecTag, bool? isAvc) { foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Video) { continue; } if (!ContainerProfile.ContainsContainer(i.GetContainers(), container)) { continue; } var audioCodecs = i.GetAudioCodecs(); if (audioCodecs.Length > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { continue; } var videoCodecs = i.GetVideoCodecs(); if (videoCodecs.Length > 0 && !videoCodecs.Contains(videoCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { continue; } 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)) { anyOff = true; break; } } if (anyOff) { continue; } return i; } return null; } } }