aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Model
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Model')
-rw-r--r--MediaBrowser.Model/Configuration/EncodingOptions.cs3
-rw-r--r--MediaBrowser.Model/Dlna/ConditionProcessor.cs39
-rw-r--r--MediaBrowser.Model/Dlna/ContainerProfile.cs2
-rw-r--r--MediaBrowser.Model/Dlna/DirectPlayProfile.cs6
-rw-r--r--MediaBrowser.Model/Dlna/ITranscoderSupport.cs18
-rw-r--r--MediaBrowser.Model/Dlna/MediaOptions.cs10
-rw-r--r--MediaBrowser.Model/Dlna/SortCriteria.cs2
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs150
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs24
-rw-r--r--MediaBrowser.Model/Entities/ParentalRating.cs4
-rw-r--r--MediaBrowser.Model/Net/MimeTypes.cs5
-rw-r--r--MediaBrowser.Model/Tasks/ITaskManager.cs4
-rw-r--r--MediaBrowser.Model/Users/UserPolicy.cs11
13 files changed, 146 insertions, 132 deletions
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs
index 0ff95a2e1f..f348d8417b 100644
--- a/MediaBrowser.Model/Configuration/EncodingOptions.cs
+++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs
@@ -39,7 +39,8 @@ public class EncodingOptions
DeinterlaceMethod = "yadif";
EnableDecodingColorDepth10Hevc = true;
EnableDecodingColorDepth10Vp9 = true;
- EnableEnhancedNvdecDecoder = false;
+ // Enhanced Nvdec or system native decoder is required for DoVi to SDR tone-mapping.
+ EnableEnhancedNvdecDecoder = true;
PreferSystemNativeHwDecoder = true;
EnableIntelLowPowerH264HwEncoder = false;
EnableIntelLowPowerHevcHwEncoder = false;
diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs
index 5734224167..f5e1a3c496 100644
--- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs
+++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs
@@ -136,12 +136,26 @@ namespace MediaBrowser.Model.Dlna
return !condition.IsRequired;
}
- if (int.TryParse(condition.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var expected))
+ var conditionType = condition.Condition;
+ if (condition.Condition == ProfileConditionType.EqualsAny)
{
- switch (condition.Condition)
+ foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
+ {
+ if (int.TryParse(singleConditionString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int conditionValue)
+ && conditionValue.Equals(currentValue))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ if (int.TryParse(condition.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var expected))
+ {
+ switch (conditionType)
{
case ProfileConditionType.Equals:
- case ProfileConditionType.EqualsAny:
return currentValue.Value.Equals(expected);
case ProfileConditionType.GreaterThanEqual:
return currentValue.Value >= expected;
@@ -212,9 +226,24 @@ namespace MediaBrowser.Model.Dlna
return !condition.IsRequired;
}
- if (double.TryParse(condition.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var expected))
+ var conditionType = condition.Condition;
+ if (condition.Condition == ProfileConditionType.EqualsAny)
{
- switch (condition.Condition)
+ foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
+ {
+ if (double.TryParse(singleConditionString, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out double conditionValue)
+ && conditionValue.Equals(currentValue))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ if (double.TryParse(condition.Value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var expected))
+ {
+ switch (conditionType)
{
case ProfileConditionType.Equals:
return currentValue.Value.Equals(expected);
diff --git a/MediaBrowser.Model/Dlna/ContainerProfile.cs b/MediaBrowser.Model/Dlna/ContainerProfile.cs
index 927df8e4ef..9780042684 100644
--- a/MediaBrowser.Model/Dlna/ContainerProfile.cs
+++ b/MediaBrowser.Model/Dlna/ContainerProfile.cs
@@ -11,7 +11,7 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
- public ProfileCondition[]? Conditions { get; set; } = Array.Empty<ProfileCondition>();
+ public ProfileCondition[] Conditions { get; set; } = Array.Empty<ProfileCondition>();
[XmlAttribute("container")]
public string Container { get; set; } = string.Empty;
diff --git a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs
index 03c3a72657..f68235d869 100644
--- a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs
+++ b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs
@@ -18,17 +18,17 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
- public bool SupportsContainer(string container)
+ public bool SupportsContainer(string? container)
{
return ContainerProfile.ContainsContainer(Container, container);
}
- public bool SupportsVideoCodec(string codec)
+ public bool SupportsVideoCodec(string? codec)
{
return Type == DlnaProfileType.Video && ContainerProfile.ContainsContainer(VideoCodec, codec);
}
- public bool SupportsAudioCodec(string codec)
+ public bool SupportsAudioCodec(string? codec)
{
return (Type == DlnaProfileType.Audio || Type == DlnaProfileType.Video) && ContainerProfile.ContainsContainer(AudioCodec, codec);
}
diff --git a/MediaBrowser.Model/Dlna/ITranscoderSupport.cs b/MediaBrowser.Model/Dlna/ITranscoderSupport.cs
index a70ce44cc6..d7397399dd 100644
--- a/MediaBrowser.Model/Dlna/ITranscoderSupport.cs
+++ b/MediaBrowser.Model/Dlna/ITranscoderSupport.cs
@@ -10,22 +10,4 @@ namespace MediaBrowser.Model.Dlna
bool CanExtractSubtitles(string codec);
}
-
- public class FullTranscoderSupport : ITranscoderSupport
- {
- public bool CanEncodeToAudioCodec(string codec)
- {
- return true;
- }
-
- public bool CanEncodeToSubtitleCodec(string codec)
- {
- return true;
- }
-
- public bool CanExtractSubtitles(string codec)
- {
- return true;
- }
- }
}
diff --git a/MediaBrowser.Model/Dlna/MediaOptions.cs b/MediaBrowser.Model/Dlna/MediaOptions.cs
index 29aecf97fc..7ec0dd473b 100644
--- a/MediaBrowser.Model/Dlna/MediaOptions.cs
+++ b/MediaBrowser.Model/Dlna/MediaOptions.cs
@@ -1,5 +1,3 @@
-#nullable disable
-
using System;
using MediaBrowser.Model.Dto;
@@ -59,22 +57,22 @@ namespace MediaBrowser.Model.Dlna
/// <summary>
/// Gets or sets the media sources.
/// </summary>
- public MediaSourceInfo[] MediaSources { get; set; }
+ public MediaSourceInfo[] MediaSources { get; set; } = Array.Empty<MediaSourceInfo>();
/// <summary>
/// Gets or sets the device profile.
/// </summary>
- public DeviceProfile Profile { get; set; }
+ required public DeviceProfile Profile { get; set; }
/// <summary>
/// Gets or sets a media source id. Optional. Only needed if a specific AudioStreamIndex or SubtitleStreamIndex are requested.
/// </summary>
- public string MediaSourceId { get; set; }
+ public string? MediaSourceId { get; set; }
/// <summary>
/// Gets or sets the device id.
/// </summary>
- public string DeviceId { get; set; }
+ public string? DeviceId { get; set; }
/// <summary>
/// Gets or sets an override of supported number of audio channels
diff --git a/MediaBrowser.Model/Dlna/SortCriteria.cs b/MediaBrowser.Model/Dlna/SortCriteria.cs
index 7fef16e535..7df53c6d19 100644
--- a/MediaBrowser.Model/Dlna/SortCriteria.cs
+++ b/MediaBrowser.Model/Dlna/SortCriteria.cs
@@ -9,7 +9,7 @@ namespace MediaBrowser.Model.Dlna
{
public SortCriteria(string sortOrder)
{
- if (!string.IsNullOrEmpty(sortOrder) && Enum.TryParse<SortOrder>(sortOrder, true, out var sortOrderValue))
+ if (Enum.TryParse<SortOrder>(sortOrder, true, out var sortOrderValue))
{
SortOrder = sortOrderValue;
}
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index ef73096b43..6f99bbc13e 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -1,5 +1,3 @@
-#nullable disable
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -38,28 +36,19 @@ namespace MediaBrowser.Model.Dlna
}
/// <summary>
- /// Initializes a new instance of the <see cref="StreamBuilder"/> class.
- /// </summary>
- /// <param name="logger">The <see cref="ILogger"/> object.</param>
- public StreamBuilder(ILogger<StreamBuilder> logger)
- : this(new FullTranscoderSupport(), logger)
- {
- }
-
- /// <summary>
/// Gets the optimal audio stream.
/// </summary>
/// <param name="options">The <see cref="MediaOptions"/> object to get the audio stream from.</param>
/// <returns>The <see cref="StreamInfo"/> of the optimal audio stream.</returns>
- public StreamInfo GetOptimalAudioStream(MediaOptions options)
+ public StreamInfo? GetOptimalAudioStream(MediaOptions options)
{
ValidateMediaOptions(options, false);
var mediaSources = new List<MediaSourceInfo>();
foreach (var mediaSource in options.MediaSources)
{
- if (string.IsNullOrEmpty(options.MediaSourceId) ||
- string.Equals(mediaSource.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
+ if (string.IsNullOrEmpty(options.MediaSourceId)
+ || string.Equals(mediaSource.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
{
mediaSources.Add(mediaSource);
}
@@ -68,7 +57,7 @@ namespace MediaBrowser.Model.Dlna
var streams = new List<StreamInfo>();
foreach (var mediaSourceInfo in mediaSources)
{
- StreamInfo streamInfo = GetOptimalAudioStream(mediaSourceInfo, options);
+ StreamInfo? streamInfo = GetOptimalAudioStream(mediaSourceInfo, options);
if (streamInfo is not null)
{
streams.Add(streamInfo);
@@ -84,7 +73,7 @@ namespace MediaBrowser.Model.Dlna
return GetOptimalStream(streams, options.GetMaxBitrate(true) ?? 0);
}
- private StreamInfo GetOptimalAudioStream(MediaSourceInfo item, MediaOptions options)
+ private StreamInfo? GetOptimalAudioStream(MediaSourceInfo item, MediaOptions options)
{
var playlistItem = new StreamInfo
{
@@ -118,7 +107,7 @@ namespace MediaBrowser.Model.Dlna
var transcodeReasons = directPlayInfo.TranscodeReasons;
var inputAudioChannels = audioStream?.Channels;
- var inputAudioBitrate = audioStream?.BitDepth;
+ var inputAudioBitrate = audioStream?.BitRate;
var inputAudioSampleRate = audioStream?.SampleRate;
var inputAudioBitDepth = audioStream?.BitDepth;
@@ -138,12 +127,12 @@ namespace MediaBrowser.Model.Dlna
}
}
- TranscodingProfile transcodingProfile = null;
+ TranscodingProfile? transcodingProfile = null;
foreach (var tcProfile in options.Profile.TranscodingProfiles)
{
if (tcProfile.Type == playlistItem.MediaType
&& tcProfile.Context == options.Context
- && _transcoderSupport.CanEncodeToAudioCodec(transcodingProfile.AudioCodec ?? tcProfile.Container))
+ && _transcoderSupport.CanEncodeToAudioCodec(tcProfile.AudioCodec ?? tcProfile.Container))
{
transcodingProfile = tcProfile;
break;
@@ -190,15 +179,15 @@ namespace MediaBrowser.Model.Dlna
/// </summary>
/// <param name="options">The <see cref="MediaOptions"/> object to get the video stream from.</param>
/// <returns>The <see cref="StreamInfo"/> of the optimal video stream.</returns>
- public StreamInfo GetOptimalVideoStream(MediaOptions options)
+ public StreamInfo? GetOptimalVideoStream(MediaOptions options)
{
ValidateMediaOptions(options, true);
var mediaSources = new List<MediaSourceInfo>();
foreach (var mediaSourceInfo in options.MediaSources)
{
- if (string.IsNullOrEmpty(options.MediaSourceId) ||
- string.Equals(mediaSourceInfo.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
+ if (string.IsNullOrEmpty(options.MediaSourceId)
+ || string.Equals(mediaSourceInfo.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
{
mediaSources.Add(mediaSourceInfo);
}
@@ -223,7 +212,7 @@ namespace MediaBrowser.Model.Dlna
return GetOptimalStream(streams, options.GetMaxBitrate(false) ?? 0);
}
- private static StreamInfo GetOptimalStream(List<StreamInfo> streams, long maxBitrate)
+ private static StreamInfo? GetOptimalStream(List<StreamInfo> streams, long maxBitrate)
=> SortMediaSources(streams, maxBitrate).FirstOrDefault();
private static IOrderedEnumerable<StreamInfo> SortMediaSources(List<StreamInfo> streams, long maxBitrate)
@@ -366,7 +355,7 @@ namespace MediaBrowser.Model.Dlna
/// <param name="type">The <see cref="DlnaProfileType"/>.</param>
/// <param name="playProfile">The <see cref="DirectPlayProfile"/> object to get the video stream from.</param>
/// <returns>The the normalized input container.</returns>
- public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, DeviceProfile profile, DlnaProfileType type, DirectPlayProfile playProfile = null)
+ public static string? NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, DeviceProfile? profile, DlnaProfileType type, DirectPlayProfile? playProfile = null)
{
if (string.IsNullOrEmpty(inputContainer))
{
@@ -394,7 +383,7 @@ namespace MediaBrowser.Model.Dlna
return formats[0];
}
- private (DirectPlayProfile Profile, PlayMethod? PlayMethod, TranscodeReason TranscodeReasons) GetAudioDirectPlayProfile(MediaSourceInfo item, MediaStream audioStream, MediaOptions options)
+ private (DirectPlayProfile? Profile, PlayMethod? PlayMethod, TranscodeReason TranscodeReasons) GetAudioDirectPlayProfile(MediaSourceInfo item, MediaStream audioStream, MediaOptions options)
{
var directPlayProfile = options.Profile.DirectPlayProfiles
.FirstOrDefault(x => x.Type == DlnaProfileType.Audio && IsAudioDirectPlaySupported(x, item, audioStream));
@@ -449,7 +438,7 @@ namespace MediaBrowser.Model.Dlna
return (directPlayProfile, null, transcodeReasons);
}
- private static TranscodeReason GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable<DirectPlayProfile> directPlayProfiles)
+ private static TranscodeReason GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream? videoStream, MediaStream audioStream, IEnumerable<DirectPlayProfile> directPlayProfiles)
{
var mediaType = videoStream is null ? DlnaProfileType.Audio : DlnaProfileType.Video;
@@ -551,8 +540,7 @@ namespace MediaBrowser.Model.Dlna
}
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
- if (!string.IsNullOrEmpty(transcodingProfile.MaxAudioChannels)
- && int.TryParse(transcodingProfile.MaxAudioChannels, NumberStyles.Any, CultureInfo.InvariantCulture, out int transcodingMaxAudioChannels))
+ if (int.TryParse(transcodingProfile.MaxAudioChannels, CultureInfo.InvariantCulture, out int transcodingMaxAudioChannels))
{
playlistItem.TranscodingMaxAudioChannels = transcodingMaxAudioChannels;
}
@@ -576,7 +564,7 @@ namespace MediaBrowser.Model.Dlna
}
}
- private static void SetStreamInfoOptionsFromDirectPlayProfile(MediaOptions options, MediaSourceInfo item, StreamInfo playlistItem, DirectPlayProfile directPlayProfile)
+ private static void SetStreamInfoOptionsFromDirectPlayProfile(MediaOptions options, MediaSourceInfo item, StreamInfo playlistItem, DirectPlayProfile? directPlayProfile)
{
var container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Video, directPlayProfile);
var protocol = "http";
@@ -588,7 +576,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.SubProtocol = protocol;
playlistItem.VideoCodecs = new[] { item.VideoStream.Codec };
- playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile.AudioCodec);
+ playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile?.AudioCodec);
}
private StreamInfo BuildVideoItem(MediaSourceInfo item, MediaOptions options)
@@ -653,7 +641,7 @@ namespace MediaBrowser.Model.Dlna
isEligibleForDirectPlay,
isEligibleForDirectStream);
- DirectPlayProfile directPlayProfile = null;
+ DirectPlayProfile? directPlayProfile = null;
if (isEligibleForDirectPlay || isEligibleForDirectStream)
{
// See if it can be direct played
@@ -684,16 +672,16 @@ namespace MediaBrowser.Model.Dlna
playlistItem.AudioStreamIndex = audioStream?.Index;
if (audioStream is not null)
{
- playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile.AudioCodec);
+ playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile?.AudioCodec);
}
SetStreamInfoOptionsFromDirectPlayProfile(options, item, playlistItem, directPlayProfile);
- BuildStreamVideoItem(playlistItem, options, item, videoStream, audioStream, candidateAudioStreams, directPlayProfile.Container, directPlayProfile.VideoCodec, directPlayProfile.AudioCodec);
+ BuildStreamVideoItem(playlistItem, options, item, videoStream, audioStream, candidateAudioStreams, directPlayProfile?.Container, directPlayProfile?.VideoCodec, directPlayProfile?.AudioCodec);
}
if (subtitleStream is not null)
{
- var subtitleProfile = GetSubtitleProfile(item, subtitleStream, options.Profile.SubtitleProfiles, directPlay.Value, _transcoderSupport, directPlayProfile.Container, null);
+ var subtitleProfile = GetSubtitleProfile(item, subtitleStream, options.Profile.SubtitleProfiles, directPlay.Value, _transcoderSupport, directPlayProfile?.Container, null);
playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method;
playlistItem.SubtitleFormat = subtitleProfile.Format;
@@ -755,7 +743,14 @@ namespace MediaBrowser.Model.Dlna
return playlistItem;
}
- private TranscodingProfile GetVideoTranscodeProfile(MediaSourceInfo item, MediaOptions options, MediaStream videoStream, MediaStream audioStream, IEnumerable<MediaStream> candidateAudioStreams, MediaStream subtitleStream, StreamInfo playlistItem)
+ private TranscodingProfile? GetVideoTranscodeProfile(
+ MediaSourceInfo item,
+ MediaOptions options,
+ MediaStream? videoStream,
+ MediaStream? audioStream,
+ IEnumerable<MediaStream> candidateAudioStreams,
+ MediaStream? subtitleStream,
+ StreamInfo playlistItem)
{
if (!(item.SupportsTranscoding || item.SupportsDirectStream))
{
@@ -802,7 +797,16 @@ namespace MediaBrowser.Model.Dlna
return transcodingProfiles.FirstOrDefault();
}
- private void BuildStreamVideoItem(StreamInfo playlistItem, MediaOptions options, MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable<MediaStream> candidateAudioStreams, string container, string videoCodec, string audioCodec)
+ private void BuildStreamVideoItem(
+ StreamInfo playlistItem,
+ MediaOptions options,
+ MediaSourceInfo item,
+ MediaStream? videoStream,
+ MediaStream? audioStream,
+ IEnumerable<MediaStream> candidateAudioStreams,
+ string? container,
+ string? videoCodec,
+ string? audioCodec)
{
// Prefer matching video codecs
var videoCodecs = ContainerProfile.SplitValue(videoCodec);
@@ -869,12 +873,12 @@ namespace MediaBrowser.Model.Dlna
int? bitDepth = videoStream?.BitDepth;
int? videoBitrate = videoStream?.BitRate;
double? videoLevel = videoStream?.Level;
- string videoProfile = videoStream?.Profile;
- string videoRangeType = videoStream?.VideoRangeType;
+ string? videoProfile = videoStream?.Profile;
+ string? videoRangeType = videoStream?.VideoRangeType;
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
bool? isAnamorphic = videoStream?.IsAnamorphic;
bool? isInterlaced = videoStream?.IsInterlaced;
- string videoCodecTag = videoStream?.CodecTag;
+ string? videoCodecTag = videoStream?.CodecTag;
bool? isAvc = videoStream?.IsAVC;
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : item.Timestamp;
@@ -910,11 +914,11 @@ namespace MediaBrowser.Model.Dlna
playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate);
bool? isSecondaryAudio = audioStream is null ? null : item.IsSecondaryAudio(audioStream);
- int? inputAudioBitrate = audioStream is null ? null : audioStream.BitRate;
- int? audioChannels = audioStream is null ? null : audioStream.Channels;
- string audioProfile = audioStream is null ? null : audioStream.Profile;
- int? inputAudioSampleRate = audioStream is null ? null : audioStream.SampleRate;
- int? inputAudioBitDepth = audioStream is null ? null : audioStream.BitDepth;
+ int? inputAudioBitrate = audioStream?.BitRate;
+ int? audioChannels = audioStream?.Channels;
+ string? audioProfile = audioStream?.Profile;
+ int? inputAudioSampleRate = audioStream?.SampleRate;
+ int? inputAudioBitDepth = audioStream?.BitDepth;
var appliedAudioConditions = options.Profile.CodecProfiles
.Where(i => i.Type == CodecType.VideoAudio &&
@@ -962,7 +966,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem?.TranscodeReasons);
}
- private static int GetDefaultAudioBitrate(string audioCodec, int? audioChannels)
+ private static int GetDefaultAudioBitrate(string? audioCodec, int? audioChannels)
{
if (!string.IsNullOrEmpty(audioCodec))
{
@@ -995,9 +999,9 @@ namespace MediaBrowser.Model.Dlna
return 192000;
}
- private static int GetAudioBitrate(long maxTotalBitrate, string[] targetAudioCodecs, MediaStream audioStream, StreamInfo item)
+ private static int GetAudioBitrate(long maxTotalBitrate, string[] targetAudioCodecs, MediaStream? audioStream, StreamInfo item)
{
- string targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
+ string? targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
int? targetAudioChannels = item.GetTargetAudioChannels(targetAudioCodec);
@@ -1088,13 +1092,13 @@ namespace MediaBrowser.Model.Dlna
return 7168000;
}
- private (DirectPlayProfile Profile, PlayMethod? PlayMethod, int? AudioStreamIndex, TranscodeReason TranscodeReasons) GetVideoDirectPlayProfile(
+ private (DirectPlayProfile? Profile, PlayMethod? PlayMethod, int? AudioStreamIndex, TranscodeReason TranscodeReasons) GetVideoDirectPlayProfile(
MediaOptions options,
MediaSourceInfo mediaSource,
- MediaStream videoStream,
- MediaStream audioStream,
+ MediaStream? videoStream,
+ MediaStream? audioStream,
ICollection<MediaStream> candidateAudioStreams,
- MediaStream subtitleStream,
+ MediaStream? subtitleStream,
bool isEligibleForDirectPlay,
bool isEligibleForDirectStream)
{
@@ -1117,12 +1121,12 @@ namespace MediaBrowser.Model.Dlna
int? bitDepth = videoStream?.BitDepth;
int? videoBitrate = videoStream?.BitRate;
double? videoLevel = videoStream?.Level;
- string videoProfile = videoStream?.Profile;
- string videoRangeType = videoStream?.VideoRangeType;
+ string? videoProfile = videoStream?.Profile;
+ string? videoRangeType = videoStream?.VideoRangeType;
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
bool? isAnamorphic = videoStream?.IsAnamorphic;
bool? isInterlaced = videoStream?.IsInterlaced;
- string videoCodecTag = videoStream?.CodecTag;
+ string? videoCodecTag = videoStream?.CodecTag;
bool? isAvc = videoStream?.IsAVC;
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : mediaSource.Timestamp;
@@ -1210,14 +1214,14 @@ namespace MediaBrowser.Model.Dlna
}
// Check video codec
- string videoCodec = videoStream?.Codec;
+ string? videoCodec = videoStream?.Codec;
if (!directPlayProfile.SupportsVideoCodec(videoCodec))
{
directPlayProfileReasons |= TranscodeReason.VideoCodecNotSupported;
}
// Check audio codec
- MediaStream selectedAudioStream = null;
+ MediaStream? selectedAudioStream = null;
if (candidateAudioStreams.Any())
{
selectedAudioStream = candidateAudioStreams.FirstOrDefault(audioStream => directPlayProfile.SupportsAudioCodec(audioStream.Codec));
@@ -1338,8 +1342,8 @@ namespace MediaBrowser.Model.Dlna
SubtitleProfile[] subtitleProfiles,
PlayMethod playMethod,
ITranscoderSupport transcoderSupport,
- string outputContainer,
- string transcodingSubProtocol)
+ string? outputContainer,
+ string? transcodingSubProtocol)
{
if (!subtitleStream.IsExternal && (playMethod != PlayMethod.Transcode || !string.Equals(transcodingSubProtocol, "hls", StringComparison.OrdinalIgnoreCase)))
{
@@ -1412,7 +1416,7 @@ namespace MediaBrowser.Model.Dlna
};
}
- private static bool IsSubtitleEmbedSupported(string transcodingContainer)
+ private static bool IsSubtitleEmbedSupported(string? transcodingContainer)
{
if (!string.IsNullOrEmpty(transcodingContainer))
{
@@ -1434,7 +1438,7 @@ namespace MediaBrowser.Model.Dlna
return false;
}
- private static SubtitleProfile GetExternalSubtitleProfile(MediaSourceInfo mediaSource, MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, ITranscoderSupport transcoderSupport, bool allowConversion)
+ private static SubtitleProfile? GetExternalSubtitleProfile(MediaSourceInfo mediaSource, MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, ITranscoderSupport transcoderSupport, bool allowConversion)
{
foreach (var profile in subtitleProfiles)
{
@@ -1567,7 +1571,7 @@ namespace MediaBrowser.Model.Dlna
private static IEnumerable<ProfileCondition> GetProfileConditionsForAudio(
IEnumerable<CodecProfile> codecProfiles,
string container,
- string codec,
+ string? codec,
int? audioChannels,
int? audioBitrate,
int? audioSampleRate,
@@ -1587,7 +1591,7 @@ namespace MediaBrowser.Model.Dlna
return conditions.Where(condition => !ConditionProcessor.IsAudioConditionSatisfied(condition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth));
}
- private void ApplyTranscodingConditions(StreamInfo item, IEnumerable<ProfileCondition> conditions, string qualifier, bool enableQualifiedConditions, bool enableNonQualifiedConditions)
+ private void ApplyTranscodingConditions(StreamInfo item, IEnumerable<ProfileCondition> conditions, string? qualifier, bool enableQualifiedConditions, bool enableNonQualifiedConditions)
{
foreach (ProfileCondition condition in conditions)
{
@@ -1613,7 +1617,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -1639,7 +1643,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -1675,7 +1679,7 @@ namespace MediaBrowser.Model.Dlna
}
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -1799,7 +1803,7 @@ namespace MediaBrowser.Model.Dlna
}
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -1835,7 +1839,7 @@ namespace MediaBrowser.Model.Dlna
}
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -1925,7 +1929,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -1951,7 +1955,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -1977,7 +1981,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- if (float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (float.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -2003,7 +2007,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -2029,7 +2033,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var num))
{
if (condition.Condition == ProfileConditionType.Equals)
{
@@ -2063,7 +2067,7 @@ namespace MediaBrowser.Model.Dlna
}
// Check audio codec
- string audioCodec = audioStream?.Codec;
+ string? audioCodec = audioStream?.Codec;
if (!profile.SupportsAudioCodec(audioCodec))
{
return false;
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 0e814f036e..886b64a248 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -921,12 +921,8 @@ namespace MediaBrowser.Model.Dlna
public int? GetTargetVideoBitDepth(string codec)
{
var value = GetOption(codec, "videobitdepth");
- if (string.IsNullOrEmpty(value))
- {
- return null;
- }
- if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var result))
{
return result;
}
@@ -937,12 +933,8 @@ namespace MediaBrowser.Model.Dlna
public int? GetTargetAudioBitDepth(string codec)
{
var value = GetOption(codec, "audiobitdepth");
- if (string.IsNullOrEmpty(value))
- {
- return null;
- }
- if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var result))
{
return result;
}
@@ -953,12 +945,8 @@ namespace MediaBrowser.Model.Dlna
public double? GetTargetVideoLevel(string codec)
{
var value = GetOption(codec, "level");
- if (string.IsNullOrEmpty(value))
- {
- return null;
- }
- if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
+ if (double.TryParse(value, CultureInfo.InvariantCulture, out var result))
{
return result;
}
@@ -969,12 +957,8 @@ namespace MediaBrowser.Model.Dlna
public int? GetTargetRefFrames(string codec)
{
var value = GetOption(codec, "maxrefframes");
- if (string.IsNullOrEmpty(value))
- {
- return null;
- }
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
+ if (int.TryParse(value, CultureInfo.InvariantCulture, out var result))
{
return result;
}
diff --git a/MediaBrowser.Model/Entities/ParentalRating.cs b/MediaBrowser.Model/Entities/ParentalRating.cs
index 17b2868a31..c92640818c 100644
--- a/MediaBrowser.Model/Entities/ParentalRating.cs
+++ b/MediaBrowser.Model/Entities/ParentalRating.cs
@@ -12,7 +12,7 @@ namespace MediaBrowser.Model.Entities
{
}
- public ParentalRating(string name, int value)
+ public ParentalRating(string name, int? value)
{
Name = name;
Value = value;
@@ -28,6 +28,6 @@ namespace MediaBrowser.Model.Entities
/// Gets or sets the value.
/// </summary>
/// <value>The value.</value>
- public int Value { get; set; }
+ public int? Value { get; set; }
}
}
diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs
index 8157dc0c24..5a1871070d 100644
--- a/MediaBrowser.Model/Net/MimeTypes.cs
+++ b/MediaBrowser.Model/Net/MimeTypes.cs
@@ -117,7 +117,9 @@ namespace MediaBrowser.Model.Net
// Type image
{ "image/jpeg", ".jpg" },
+ { "image/tiff", ".tiff" },
{ "image/x-png", ".png" },
+ { "image/x-icon", ".ico" },
// Type text
{ "text/plain", ".txt" },
@@ -178,5 +180,8 @@ namespace MediaBrowser.Model.Net
var extension = Model.MimeTypes.GetMimeTypeExtensions(mimeType).FirstOrDefault();
return string.IsNullOrEmpty(extension) ? null : "." + extension;
}
+
+ public static bool IsImage(ReadOnlySpan<char> mimeType)
+ => mimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase);
}
}
diff --git a/MediaBrowser.Model/Tasks/ITaskManager.cs b/MediaBrowser.Model/Tasks/ITaskManager.cs
index 13bebc479e..5b55667e82 100644
--- a/MediaBrowser.Model/Tasks/ITaskManager.cs
+++ b/MediaBrowser.Model/Tasks/ITaskManager.cs
@@ -9,9 +9,9 @@ namespace MediaBrowser.Model.Tasks
{
public interface ITaskManager : IDisposable
{
- event EventHandler<GenericEventArgs<IScheduledTaskWorker>> TaskExecuting;
+ event EventHandler<GenericEventArgs<IScheduledTaskWorker>>? TaskExecuting;
- event EventHandler<TaskCompletionEventArgs> TaskCompleted;
+ event EventHandler<TaskCompletionEventArgs>? TaskCompleted;
/// <summary>
/// Gets the list of Scheduled Tasks.
diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs
index 3634d07058..80f5e2c37e 100644
--- a/MediaBrowser.Model/Users/UserPolicy.cs
+++ b/MediaBrowser.Model/Users/UserPolicy.cs
@@ -13,6 +13,7 @@ namespace MediaBrowser.Model.Users
public UserPolicy()
{
IsHidden = true;
+ EnableCollectionManagement = false;
EnableContentDeletion = false;
EnableContentDeletionFromFolders = Array.Empty<string>();
@@ -35,6 +36,7 @@ namespace MediaBrowser.Model.Users
EnableSharedDeviceControl = true;
BlockedTags = Array.Empty<string>();
+ AllowedTags = Array.Empty<string>();
BlockUnratedItems = Array.Empty<UnratedItem>();
EnableUserPreferenceAccess = true;
@@ -44,6 +46,7 @@ namespace MediaBrowser.Model.Users
LoginAttemptsBeforeLockout = -1;
MaxActiveSessions = 0;
+ MaxParentalRating = null;
EnableAllChannels = true;
EnabledChannels = Array.Empty<Guid>();
@@ -73,6 +76,12 @@ namespace MediaBrowser.Model.Users
public bool IsHidden { get; set; }
/// <summary>
+ /// Gets or sets a value indicating whether this instance can manage collections.
+ /// </summary>
+ /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
+ public bool EnableCollectionManagement { get; set; }
+
+ /// <summary>
/// Gets or sets a value indicating whether this instance is disabled.
/// </summary>
/// <value><c>true</c> if this instance is disabled; otherwise, <c>false</c>.</value>
@@ -86,6 +95,8 @@ namespace MediaBrowser.Model.Users
public string[] BlockedTags { get; set; }
+ public string[] AllowedTags { get; set; }
+
public bool EnableUserPreferenceAccess { get; set; }
public AccessSchedule[] AccessSchedules { get; set; }