#pragma warning disable CA1819 // Properties should not return arrays using System; using System.ComponentModel; using System.Linq; using System.Xml.Serialization; using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Model.Dlna { /// /// Defines the . /// [XmlRoot("Profile")] public class DeviceProfile { /// /// 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. /// [DefaultValue(false)] public bool EnableAlbumArtInDidl { get; set; } /// /// Gets or sets a value indicating whether EnableSingleAlbumArtLimit. /// [DefaultValue(false)] public bool EnableSingleAlbumArtLimit { get; set; } /// /// Gets or sets a value indicating whether EnableSingleSubtitleLimit. /// [DefaultValue(false)] public bool EnableSingleSubtitleLimit { get; set; } /// /// Gets or sets the SupportedMediaTypes. /// public string SupportedMediaTypes { get; set; } = "Audio,Photo,Video"; /// /// 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; } = 8000000; /// /// Gets or sets the MaxStaticBitrate. /// public int? MaxStaticBitrate { get; set; } = 8000000; /// /// Gets or sets the MusicStreamingTranscodingBitrate. /// public int? MusicStreamingTranscodingBitrate { get; set; } = 128000; /// /// Gets or sets the MaxStaticMusicBitrate. /// public int? MaxStaticMusicBitrate { get; set; } = 8000000; /// /// 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. /// [DefaultValue(0)] public int TimelineOffsetSeconds { get; set; } /// /// Gets or sets a value indicating whether RequiresPlainVideoItems. /// [DefaultValue(false)] public bool RequiresPlainVideoItems { get; set; } /// /// Gets or sets a value indicating whether RequiresPlainFolders. /// [DefaultValue(false)] public bool RequiresPlainFolders { get; set; } /// /// Gets or sets a value indicating whether EnableMSMediaReceiverRegistrar. /// [DefaultValue(false)] public bool EnableMSMediaReceiverRegistrar { get; set; } /// /// Gets or sets a value indicating whether IgnoreTranscodeByteRangeRequests. /// [DefaultValue(false)] public bool IgnoreTranscodeByteRangeRequests { get; set; } /// /// Gets or sets the XmlRootAttributes. /// public XmlAttribute[] XmlRootAttributes { get; set; } = Array.Empty(); /// /// Gets or sets the direct play profiles. /// public DirectPlayProfile[] DirectPlayProfiles { get; set; } = Array.Empty(); /// /// Gets or sets the transcoding profiles. /// public TranscodingProfile[] TranscodingProfiles { get; set; } = Array.Empty(); /// /// Gets or sets the ContainerProfiles. /// public ContainerProfile[] ContainerProfiles { get; set; } = Array.Empty(); /// /// Gets or sets the CodecProfiles. /// public CodecProfile[] CodecProfiles { get; set; } = Array.Empty(); /// /// Gets or sets the ResponseProfiles. /// public ResponseProfile[] ResponseProfiles { get; set; } = Array.Empty(); /// /// Gets or sets the SubtitleProfiles. /// public SubtitleProfile[] SubtitleProfiles { get; set; } = Array.Empty(); /// /// 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 != 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 != 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, 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; } } }