You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jellyfin/MediaBrowser.Model/Dlna/DeviceProfile.cs

500 lines
17 KiB

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