aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Model
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Model')
-rw-r--r--MediaBrowser.Model/Branding/BrandingOptions.cs5
-rw-r--r--MediaBrowser.Model/Configuration/EncodingOptions.cs8
-rw-r--r--MediaBrowser.Model/Configuration/UserConfiguration.cs16
-rw-r--r--MediaBrowser.Model/Dlna/ConditionProcessor.cs3
-rw-r--r--MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs4
-rw-r--r--MediaBrowser.Model/Dlna/DeviceProfile.cs4
-rw-r--r--MediaBrowser.Model/Dlna/ProfileConditionValue.cs3
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs45
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs23
-rw-r--r--MediaBrowser.Model/Dto/BaseItemDto.cs6
-rw-r--r--MediaBrowser.Model/Entities/MediaStream.cs182
-rw-r--r--MediaBrowser.Model/Entities/MetadataProvider.cs6
-rw-r--r--MediaBrowser.Model/LiveTv/TunerHostInfo.cs3
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj4
-rw-r--r--MediaBrowser.Model/MediaInfo/SubtitleFormat.cs1
-rw-r--r--MediaBrowser.Model/Querying/ItemSortBy.cs52
-rw-r--r--MediaBrowser.Model/Querying/NextUpQuery.cs2
-rw-r--r--MediaBrowser.Model/Search/SearchHint.cs66
-rw-r--r--MediaBrowser.Model/Session/GeneralCommand.cs4
-rw-r--r--MediaBrowser.Model/Session/PlayerStateInfo.cs6
-rw-r--r--MediaBrowser.Model/Session/TranscodeReason.cs1
-rw-r--r--MediaBrowser.Model/SyncPlay/GroupStateType.cs2
-rw-r--r--MediaBrowser.Model/Tasks/ITaskManager.cs10
-rw-r--r--MediaBrowser.Model/Tasks/ITaskTrigger.cs4
24 files changed, 384 insertions, 76 deletions
diff --git a/MediaBrowser.Model/Branding/BrandingOptions.cs b/MediaBrowser.Model/Branding/BrandingOptions.cs
index cc42c1718..a0adb56ef 100644
--- a/MediaBrowser.Model/Branding/BrandingOptions.cs
+++ b/MediaBrowser.Model/Branding/BrandingOptions.cs
@@ -21,6 +21,11 @@ public class BrandingOptions
public string? CustomCss { get; set; }
/// <summary>
+ /// Gets or sets a value indicating whether to enable the splashscreen.
+ /// </summary>
+ public bool SplashscreenEnabled { get; set; } = true;
+
+ /// <summary>
/// Gets or sets the splashscreen location on disk.
/// </summary>
/// <remarks>
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs
index 06931ac3b..73ebfba70 100644
--- a/MediaBrowser.Model/Configuration/EncodingOptions.cs
+++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs
@@ -26,6 +26,8 @@ namespace MediaBrowser.Model.Configuration
TonemappingThreshold = 0.8;
TonemappingPeak = 100;
TonemappingParam = 0;
+ VppTonemappingBrightness = 0;
+ VppTonemappingContrast = 1.2;
H264Crf = 23;
H265Crf = 28;
DeinterlaceDoubleRate = false;
@@ -39,7 +41,7 @@ namespace MediaBrowser.Model.Configuration
EnableHardwareEncoding = true;
AllowHevcEncoding = false;
EnableSubtitleExtraction = true;
- AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = Array.Empty<string>();
+ AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = new[] { "mkv" };
HardwareDecodingCodecs = new string[] { "h264", "vc1" };
}
@@ -89,6 +91,10 @@ namespace MediaBrowser.Model.Configuration
public double TonemappingParam { get; set; }
+ public double VppTonemappingBrightness { get; set; }
+
+ public double VppTonemappingContrast { get; set; }
+
public int H264Crf { get; set; }
public int H265Crf { get; set; }
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index 81359462c..94f354660 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -22,10 +22,10 @@ namespace MediaBrowser.Model.Configuration
HidePlayedInLatest = true;
PlayDefaultAudioTrack = true;
- LatestItemsExcludes = Array.Empty<string>();
- OrderedViews = Array.Empty<string>();
- MyMediaExcludes = Array.Empty<string>();
- GroupedFolders = Array.Empty<string>();
+ LatestItemsExcludes = Array.Empty<Guid>();
+ OrderedViews = Array.Empty<Guid>();
+ MyMediaExcludes = Array.Empty<Guid>();
+ GroupedFolders = Array.Empty<Guid>();
}
/// <summary>
@@ -48,7 +48,7 @@ namespace MediaBrowser.Model.Configuration
public bool DisplayMissingEpisodes { get; set; }
- public string[] GroupedFolders { get; set; }
+ public Guid[] GroupedFolders { get; set; }
public SubtitlePlaybackMode SubtitleMode { get; set; }
@@ -56,11 +56,11 @@ namespace MediaBrowser.Model.Configuration
public bool EnableLocalPassword { get; set; }
- public string[] OrderedViews { get; set; }
+ public Guid[] OrderedViews { get; set; }
- public string[] LatestItemsExcludes { get; set; }
+ public Guid[] LatestItemsExcludes { get; set; }
- public string[] MyMediaExcludes { get; set; }
+ public Guid[] MyMediaExcludes { get; set; }
public bool HidePlayedInLatest { get; set; }
diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs
index 8d03b4c0b..573422416 100644
--- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs
+++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs
@@ -16,6 +16,7 @@ namespace MediaBrowser.Model.Dlna
int? videoBitDepth,
int? videoBitrate,
string? videoProfile,
+ string? videoRangeType,
double? videoLevel,
float? videoFramerate,
int? packetLength,
@@ -42,6 +43,8 @@ namespace MediaBrowser.Model.Dlna
return IsConditionSatisfied(condition, videoLevel);
case ProfileConditionValue.VideoProfile:
return IsConditionSatisfied(condition, videoProfile);
+ case ProfileConditionValue.VideoRangeType:
+ return IsConditionSatisfied(condition, videoRangeType);
case ProfileConditionValue.VideoCodecTag:
return IsConditionSatisfied(condition, videoCodecTag);
case ProfileConditionValue.PacketLength:
diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
index 6e129246b..c32c1c108 100644
--- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
+++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
@@ -128,6 +128,7 @@ namespace MediaBrowser.Model.Dlna
bool isDirectStream,
long? runtimeTicks,
string videoProfile,
+ string videoRangeType,
double? videoLevel,
float? videoFramerate,
int? packetLength,
@@ -156,7 +157,7 @@ namespace MediaBrowser.Model.Dlna
flagValue |= DlnaFlags.ByteBasedSeek;
}
- // Time based seek is curently disabled when streaming. On LG CX3 adding DlnaFlags.TimeBasedSeek and orgPn causes the DLNA playback to fail (format not supported). Further investigations are needed before enabling the remaining code paths.
+ // Time based seek is currently disabled when streaming. On LG CX3 adding DlnaFlags.TimeBasedSeek and orgPn causes the DLNA playback to fail (format not supported). Further investigations are needed before enabling the remaining code paths.
// else if (runtimeTicks.HasValue)
// {
// flagValue = flagValue | DlnaFlags.TimeBasedSeek;
@@ -176,6 +177,7 @@ namespace MediaBrowser.Model.Dlna
bitDepth,
videoBitrate,
videoProfile,
+ videoRangeType,
videoLevel,
videoFramerate,
packetLength,
diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs
index 6170ff5bd..79ae95170 100644
--- a/MediaBrowser.Model/Dlna/DeviceProfile.cs
+++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs
@@ -423,6 +423,7 @@ namespace MediaBrowser.Model.Dlna
/// <param name="bitDepth">The bit depth.</param>
/// <param name="videoBitrate">The video bitrate.</param>
/// <param name="videoProfile">The video profile.</param>
+ /// <param name="videoRangeType">The video range type.</param>
/// <param name="videoLevel">The video level.</param>
/// <param name="videoFramerate">The video framerate.</param>
/// <param name="packetLength">The packet length.</param>
@@ -444,6 +445,7 @@ namespace MediaBrowser.Model.Dlna
int? bitDepth,
int? videoBitrate,
string videoProfile,
+ string videoRangeType,
double? videoLevel,
float? videoFramerate,
int? packetLength,
@@ -483,7 +485,7 @@ namespace MediaBrowser.Model.Dlna
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))
+ if (!ConditionProcessor.IsVideoConditionSatisfied(GetModelProfileCondition(c), width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
{
anyOff = true;
break;
diff --git a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs
index eb81fde75..a32433e18 100644
--- a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs
+++ b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs
@@ -26,6 +26,7 @@ namespace MediaBrowser.Model.Dlna
IsAvc = 20,
IsInterlaced = 21,
AudioSampleRate = 22,
- AudioBitDepth = 23
+ AudioBitDepth = 23,
+ VideoRangeType = 24
}
}
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index fe9ff2ebe..fdb9fd5d5 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -221,6 +221,9 @@ namespace MediaBrowser.Model.Dlna
case ProfileConditionValue.VideoProfile:
return TranscodeReason.VideoProfileNotSupported;
+ case ProfileConditionValue.VideoRangeType:
+ return TranscodeReason.VideoRangeTypeNotSupported;
+
case ProfileConditionValue.VideoTimestamp:
// TODO
return 0;
@@ -748,9 +751,9 @@ namespace MediaBrowser.Model.Dlna
var appliedVideoConditions = options.Profile.CodecProfiles
.Where(i => i.Type == CodecType.Video &&
i.ContainsAnyCodec(videoCodec, container) &&
- i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, videoStream?.Width, videoStream?.Height, videoStream?.BitDepth, videoStream?.BitRate, videoStream?.Profile, videoStream?.Level, videoFramerate, videoStream?.PacketLength, timestamp, videoStream?.IsAnamorphic, videoStream?.IsInterlaced, videoStream?.RefFrames, numVideoStreams, numAudioStreams, videoStream?.CodecTag, videoStream?.IsAVC)))
+ i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, videoStream?.Width, videoStream?.Height, videoStream?.BitDepth, videoStream?.BitRate, videoStream?.Profile, videoStream?.VideoRangeType, videoStream?.Level, videoFramerate, videoStream?.PacketLength, timestamp, videoStream?.IsAnamorphic, videoStream?.IsInterlaced, videoStream?.RefFrames, numVideoStreams, numAudioStreams, videoStream?.CodecTag, videoStream?.IsAVC)))
.Select(i =>
- i.Conditions.All(condition => ConditionProcessor.IsVideoConditionSatisfied(condition, videoStream?.Width, videoStream?.Height, videoStream?.BitDepth, videoStream?.BitRate, videoStream?.Profile, videoStream?.Level, videoFramerate, videoStream?.PacketLength, timestamp, videoStream?.IsAnamorphic, videoStream?.IsInterlaced, videoStream?.RefFrames, numVideoStreams, numAudioStreams, videoStream?.CodecTag, videoStream?.IsAVC)));
+ i.Conditions.All(condition => ConditionProcessor.IsVideoConditionSatisfied(condition, videoStream?.Width, videoStream?.Height, videoStream?.BitDepth, videoStream?.BitRate, videoStream?.Profile, videoStream?.VideoRangeType, videoStream?.Level, videoFramerate, videoStream?.PacketLength, timestamp, videoStream?.IsAnamorphic, videoStream?.IsInterlaced, videoStream?.RefFrames, numVideoStreams, numAudioStreams, videoStream?.CodecTag, videoStream?.IsAVC)));
// An empty appliedVideoConditions means that the codec has no conditions for the current video stream
var conditionsSatisfied = appliedVideoConditions.All(satisfied => satisfied);
@@ -834,6 +837,7 @@ namespace MediaBrowser.Model.Dlna
int? videoBitrate = videoStream?.BitRate;
double? videoLevel = videoStream?.Level;
string videoProfile = videoStream?.Profile;
+ string videoRangeType = videoStream?.VideoRangeType;
float videoFramerate = videoStream == null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
bool? isAnamorphic = videoStream?.IsAnamorphic;
bool? isInterlaced = videoStream?.IsInterlaced;
@@ -850,7 +854,7 @@ namespace MediaBrowser.Model.Dlna
var appliedVideoConditions = options.Profile.CodecProfiles
.Where(i => i.Type == CodecType.Video &&
i.ContainsAnyCodec(videoCodec, container) &&
- i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)));
+ i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)));
var isFirstAppliedCodecProfile = true;
foreach (var i in appliedVideoConditions)
{
@@ -1081,6 +1085,7 @@ namespace MediaBrowser.Model.Dlna
int? videoBitrate = videoStream?.BitRate;
double? videoLevel = videoStream?.Level;
string videoProfile = videoStream?.Profile;
+ string videoRangeType = videoStream?.VideoRangeType;
float videoFramerate = videoStream == null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
bool? isAnamorphic = videoStream?.IsAnamorphic;
bool? isInterlaced = videoStream?.IsInterlaced;
@@ -1098,7 +1103,7 @@ namespace MediaBrowser.Model.Dlna
int? numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video);
var checkVideoConditions = (ProfileCondition[] conditions) =>
- conditions.Where(applyCondition => !ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc));
+ conditions.Where(applyCondition => !ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc));
// Check container conditions
var containerProfileReasons = AggregateFailureConditions(
@@ -1852,6 +1857,38 @@ namespace MediaBrowser.Model.Dlna
break;
}
+ case ProfileConditionValue.VideoRangeType:
+ {
+ if (string.IsNullOrEmpty(qualifier))
+ {
+ continue;
+ }
+
+ // change from split by | to comma
+ // strip spaces to avoid having to encode
+ var values = value
+ .Split('|', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+
+ if (condition.Condition == ProfileConditionType.Equals)
+ {
+ item.SetOption(qualifier, "rangetype", string.Join(',', values));
+ }
+ else if (condition.Condition == ProfileConditionType.EqualsAny)
+ {
+ var currentValue = item.GetOption(qualifier, "rangetype");
+ if (!string.IsNullOrEmpty(currentValue) && values.Any(v => string.Equals(v, currentValue, StringComparison.OrdinalIgnoreCase)))
+ {
+ item.SetOption(qualifier, "rangetype", currentValue);
+ }
+ else
+ {
+ item.SetOption(qualifier, "rangetype", string.Join(',', values));
+ }
+ }
+
+ break;
+ }
+
case ProfileConditionValue.Height:
{
if (!enableNonQualifiedConditions)
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index da089602f..0c66351c7 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -281,6 +281,29 @@ namespace MediaBrowser.Model.Dlna
}
/// <summary>
+ /// Gets the target video range type that will be in the output stream.
+ /// </summary>
+ public string TargetVideoRangeType
+ {
+ get
+ {
+ if (IsDirectStream)
+ {
+ return TargetVideoStream?.VideoRangeType;
+ }
+
+ var targetVideoCodecs = TargetVideoCodec;
+ var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
+ if (!string.IsNullOrEmpty(videoCodec))
+ {
+ return GetOption(videoCodec, "rangetype");
+ }
+
+ return TargetVideoStream?.VideoRangeType;
+ }
+ }
+
+ /// <summary>
/// Gets the target video codec tag.
/// </summary>
/// <value>The target video codec tag.</value>
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index 094dc73b2..fdb84fa32 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -294,13 +294,13 @@ namespace MediaBrowser.Model.Dto
public NameGuidPair[] GenreItems { get; set; }
/// <summary>
- /// Gets or sets wether the item has a logo, this will hold the Id of the Parent that has one.
+ /// Gets or sets whether the item has a logo, this will hold the Id of the Parent that has one.
/// </summary>
/// <value>The parent logo item id.</value>
public Guid? ParentLogoItemId { get; set; }
/// <summary>
- /// Gets or sets wether the item has any backdrops, this will hold the Id of the Parent that has one.
+ /// Gets or sets whether the item has any backdrops, this will hold the Id of the Parent that has one.
/// </summary>
/// <value>The parent backdrop item id.</value>
public Guid? ParentBackdropItemId { get; set; }
@@ -506,7 +506,7 @@ namespace MediaBrowser.Model.Dto
public string ParentLogoImageTag { get; set; }
/// <summary>
- /// Gets or sets wether the item has fan art, this will hold the Id of the Parent that has one.
+ /// Gets or sets whether the item has fan art, this will hold the Id of the Parent that has one.
/// </summary>
/// <value>The parent art item id.</value>
public Guid? ParentArtItemId { get; set; }
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index 4742d21e9..90a60cf47 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -73,6 +73,54 @@ namespace MediaBrowser.Model.Entities
public string ColorPrimaries { get; set; }
/// <summary>
+ /// Gets or sets the Dolby Vision version major.
+ /// </summary>
+ /// <value>The Dolby Vision version major.</value>
+ public int? DvVersionMajor { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Dolby Vision version minor.
+ /// </summary>
+ /// <value>The Dolby Vision version minor.</value>
+ public int? DvVersionMinor { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Dolby Vision profile.
+ /// </summary>
+ /// <value>The Dolby Vision profile.</value>
+ public int? DvProfile { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Dolby Vision level.
+ /// </summary>
+ /// <value>The Dolby Vision level.</value>
+ public int? DvLevel { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Dolby Vision rpu present flag.
+ /// </summary>
+ /// <value>The Dolby Vision rpu present flag.</value>
+ public int? RpuPresentFlag { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Dolby Vision el present flag.
+ /// </summary>
+ /// <value>The Dolby Vision el present flag.</value>
+ public int? ElPresentFlag { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Dolby Vision bl present flag.
+ /// </summary>
+ /// <value>The Dolby Vision bl present flag.</value>
+ public int? BlPresentFlag { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Dolby Vision bl signal compatibility id.
+ /// </summary>
+ /// <value>The Dolby Vision bl signal compatibility id.</value>
+ public int? DvBlSignalCompatibilityId { get; set; }
+
+ /// <summary>
/// Gets or sets the comment.
/// </summary>
/// <value>The comment.</value>
@@ -104,33 +152,64 @@ namespace MediaBrowser.Model.Entities
{
get
{
- if (Type != MediaStreamType.Video)
- {
- return null;
- }
+ var (videoRange, _) = GetVideoColorRange();
- var colorTransfer = ColorTransfer;
-
- if (string.Equals(colorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase)
- || string.Equals(colorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase))
- {
- return "HDR";
- }
+ return videoRange;
+ }
+ }
- // For some Dolby Vision files, no color transfer is provided, so check the codec
+ /// <summary>
+ /// Gets the video range type.
+ /// </summary>
+ /// <value>The video range type.</value>
+ public string VideoRangeType
+ {
+ get
+ {
+ var (_, videoRangeType) = GetVideoColorRange();
- var codecTag = CodecTag;
+ return videoRangeType;
+ }
+ }
- if (string.Equals(codecTag, "dva1", StringComparison.OrdinalIgnoreCase)
- || string.Equals(codecTag, "dvav", StringComparison.OrdinalIgnoreCase)
- || string.Equals(codecTag, "dvh1", StringComparison.OrdinalIgnoreCase)
- || string.Equals(codecTag, "dvhe", StringComparison.OrdinalIgnoreCase)
- || string.Equals(codecTag, "dav1", StringComparison.OrdinalIgnoreCase))
+ /// <summary>
+ /// Gets the video dovi title.
+ /// </summary>
+ /// <value>The video dovi title.</value>
+ public string VideoDoViTitle
+ {
+ get
+ {
+ var dvProfile = DvProfile;
+ var rpuPresentFlag = RpuPresentFlag == 1;
+ var blPresentFlag = BlPresentFlag == 1;
+ var dvBlCompatId = DvBlSignalCompatibilityId;
+
+ if (rpuPresentFlag
+ && blPresentFlag
+ && (dvProfile == 4
+ || dvProfile == 5
+ || dvProfile == 7
+ || dvProfile == 8
+ || dvProfile == 9))
{
- return "HDR";
+ var title = "DV Profile " + dvProfile;
+
+ if (dvBlCompatId > 0)
+ {
+ title += "." + dvBlCompatId;
+ }
+
+ return dvBlCompatId switch
+ {
+ 1 => title + " (HDR10)",
+ 2 => title + " (SDR)",
+ 4 => title + " (HLG)",
+ _ => title
+ };
}
- return "SDR";
+ return null;
}
}
@@ -509,15 +588,26 @@ namespace MediaBrowser.Model.Entities
return Width switch
{
- <= 720 when Height <= 480 => IsInterlaced ? "480i" : "480p",
- // 720x576 (PAL) (768 when rescaled for square pixels)
- <= 768 when Height <= 576 => IsInterlaced ? "576i" : "576p",
- // 960x540 (sometimes 544 which is multiple of 16)
+ // 256x144 (16:9 square pixel format)
+ <= 256 when Height <= 144 => IsInterlaced ? "144i" : "144p",
+ // 426x240 (16:9 square pixel format)
+ <= 426 when Height <= 240 => IsInterlaced ? "240i" : "240p",
+ // 640x360 (16:9 square pixel format)
+ <= 640 when Height <= 360 => IsInterlaced ? "360i" : "360p",
+ // 682x384 (16:9 square pixel format)
+ <= 682 when Height <= 384 => IsInterlaced ? "384i" : "384p",
+ // 720x404 (16:9 square pixel format)
+ <= 720 when Height <= 404 => IsInterlaced ? "404i" : "404p",
+ // 854x480 (16:9 square pixel format)
+ <= 854 when Height <= 480 => IsInterlaced ? "480i" : "480p",
+ // 960x544 (16:9 square pixel format)
<= 960 when Height <= 544 => IsInterlaced ? "540i" : "540p",
+ // 1024x576 (16:9 square pixel format)
+ <= 1024 when Height <= 576 => IsInterlaced ? "576i" : "576p",
// 1280x720
<= 1280 when Height <= 962 => IsInterlaced ? "720i" : "720p",
- // 1920x1080
- <= 1920 when Height <= 1440 => IsInterlaced ? "1080i" : "1080p",
+ // 2560x1080 (FHD ultra wide 21:9) using 1440px width to accommodate WQHD
+ <= 2560 when Height <= 1440 => IsInterlaced ? "1080i" : "1080p",
// 4K
<= 4096 when Height <= 3072 => "4K",
// 8K
@@ -572,5 +662,45 @@ namespace MediaBrowser.Model.Entities
return true;
}
+
+ public (string VideoRange, string VideoRangeType) GetVideoColorRange()
+ {
+ if (Type != MediaStreamType.Video)
+ {
+ return (null, null);
+ }
+
+ var colorTransfer = ColorTransfer;
+
+ if (string.Equals(colorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase))
+ {
+ return ("HDR", "HDR10");
+ }
+
+ if (string.Equals(colorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase))
+ {
+ return ("HDR", "HLG");
+ }
+
+ var codecTag = CodecTag;
+ var dvProfile = DvProfile;
+ var rpuPresentFlag = RpuPresentFlag == 1;
+ var blPresentFlag = BlPresentFlag == 1;
+ var dvBlCompatId = DvBlSignalCompatibilityId;
+
+ var isDoViHDRProfile = dvProfile == 5 || dvProfile == 7 || dvProfile == 8;
+ var isDoViHDRFlag = rpuPresentFlag && blPresentFlag && (dvBlCompatId == 0 || dvBlCompatId == 1 || dvBlCompatId == 4);
+
+ if ((isDoViHDRProfile && isDoViHDRFlag)
+ || string.Equals(codecTag, "dovi", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(codecTag, "dvh1", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(codecTag, "dvhe", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(codecTag, "dav1", StringComparison.OrdinalIgnoreCase))
+ {
+ return ("HDR", "DOVI");
+ }
+
+ return ("SDR", "SDR");
+ }
}
}
diff --git a/MediaBrowser.Model/Entities/MetadataProvider.cs b/MediaBrowser.Model/Entities/MetadataProvider.cs
index e9c098021..37e3d8864 100644
--- a/MediaBrowser.Model/Entities/MetadataProvider.cs
+++ b/MediaBrowser.Model/Entities/MetadataProvider.cs
@@ -8,6 +8,12 @@ namespace MediaBrowser.Model.Entities
public enum MetadataProvider
{
/// <summary>
+ /// This metadata provider is for users and/or plugins to override the
+ /// default merging behaviour.
+ /// </summary>
+ Custom = 0,
+
+ /// <summary>
/// The imdb.
/// </summary>
Imdb = 2,
diff --git a/MediaBrowser.Model/LiveTv/TunerHostInfo.cs b/MediaBrowser.Model/LiveTv/TunerHostInfo.cs
index 05576a0f8..a832169c2 100644
--- a/MediaBrowser.Model/LiveTv/TunerHostInfo.cs
+++ b/MediaBrowser.Model/LiveTv/TunerHostInfo.cs
@@ -8,6 +8,7 @@ namespace MediaBrowser.Model.LiveTv
public TunerHostInfo()
{
AllowHWTranscoding = true;
+ IgnoreDts = true;
}
public string Id { get; set; }
@@ -31,5 +32,7 @@ namespace MediaBrowser.Model.LiveTv
public int TunerCount { get; set; }
public string UserAgent { get; set; }
+
+ public bool IgnoreDts { get; set; }
}
}
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index b3a581543..4f511f996 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -8,7 +8,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Model</PackageId>
- <VersionPrefix>10.8.0</VersionPrefix>
+ <VersionPrefix>10.9.0</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>
@@ -40,7 +40,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Globalization" Version="4.3.0" />
- <PackageReference Include="System.Text.Json" Version="6.0.4" />
+ <PackageReference Include="System.Text.Json" Version="6.0.5" />
</ItemGroup>
<ItemGroup>
diff --git a/MediaBrowser.Model/MediaInfo/SubtitleFormat.cs b/MediaBrowser.Model/MediaInfo/SubtitleFormat.cs
index 9bc5c31f6..85de91694 100644
--- a/MediaBrowser.Model/MediaInfo/SubtitleFormat.cs
+++ b/MediaBrowser.Model/MediaInfo/SubtitleFormat.cs
@@ -5,6 +5,7 @@ namespace MediaBrowser.Model.MediaInfo
public static class SubtitleFormat
{
public const string SRT = "srt";
+ public const string SUBRIP = "subrip";
public const string SSA = "ssa";
public const string ASS = "ass";
public const string VTT = "vtt";
diff --git a/MediaBrowser.Model/Querying/ItemSortBy.cs b/MediaBrowser.Model/Querying/ItemSortBy.cs
index 0a28acf37..470507c53 100644
--- a/MediaBrowser.Model/Querying/ItemSortBy.cs
+++ b/MediaBrowser.Model/Querying/ItemSortBy.cs
@@ -1,5 +1,3 @@
-#pragma warning disable CS1591
-
namespace MediaBrowser.Model.Querying
{
/// <summary>
@@ -7,6 +5,9 @@ namespace MediaBrowser.Model.Querying
/// </summary>
public static class ItemSortBy
{
+ /// <summary>
+ /// The aired episode order.
+ /// </summary>
public const string AiredEpisodeOrder = "AiredEpisodeOrder";
/// <summary>
@@ -44,6 +45,9 @@ namespace MediaBrowser.Model.Querying
/// </summary>
public const string PremiereDate = "PremiereDate";
+ /// <summary>
+ /// The start date.
+ /// </summary>
public const string StartDate = "StartDate";
/// <summary>
@@ -51,6 +55,9 @@ namespace MediaBrowser.Model.Querying
/// </summary>
public const string SortName = "SortName";
+ /// <summary>
+ /// The name.
+ /// </summary>
public const string Name = "Name";
/// <summary>
@@ -83,28 +90,69 @@ namespace MediaBrowser.Model.Querying
/// </summary>
public const string CriticRating = "CriticRating";
+ /// <summary>
+ /// The IsFolder boolean.
+ /// </summary>
public const string IsFolder = "IsFolder";
+ /// <summary>
+ /// The IsUnplayed boolean.
+ /// </summary>
public const string IsUnplayed = "IsUnplayed";
+ /// <summary>
+ /// The IsPlayed boolean.
+ /// </summary>
public const string IsPlayed = "IsPlayed";
+ /// <summary>
+ /// The series sort.
+ /// </summary>
public const string SeriesSortName = "SeriesSortName";
+ /// <summary>
+ /// The video bitrate.
+ /// </summary>
public const string VideoBitRate = "VideoBitRate";
+ /// <summary>
+ /// The air time.
+ /// </summary>
public const string AirTime = "AirTime";
+ /// <summary>
+ /// The studio.
+ /// </summary>
public const string Studio = "Studio";
+ /// <summary>
+ /// The IsFavouriteOrLiked boolean.
+ /// </summary>
public const string IsFavoriteOrLiked = "IsFavoriteOrLiked";
+ /// <summary>
+ /// The last content added date.
+ /// </summary>
public const string DateLastContentAdded = "DateLastContentAdded";
+ /// <summary>
+ /// The series last played date.
+ /// </summary>
public const string SeriesDatePlayed = "SeriesDatePlayed";
+ /// <summary>
+ /// The parent index number.
+ /// </summary>
public const string ParentIndexNumber = "ParentIndexNumber";
+ /// <summary>
+ /// The index number.
+ /// </summary>
public const string IndexNumber = "IndexNumber";
+
+ /// <summary>
+ /// The similarity score.
+ /// </summary>
+ public const string SimilarityScore = "SimilarityScore";
}
}
diff --git a/MediaBrowser.Model/Querying/NextUpQuery.cs b/MediaBrowser.Model/Querying/NextUpQuery.cs
index 133d6a916..0fb996df9 100644
--- a/MediaBrowser.Model/Querying/NextUpQuery.cs
+++ b/MediaBrowser.Model/Querying/NextUpQuery.cs
@@ -33,7 +33,7 @@ namespace MediaBrowser.Model.Querying
/// Gets or sets the series id.
/// </summary>
/// <value>The series id.</value>
- public string SeriesId { get; set; }
+ public Guid? SeriesId { get; set; }
/// <summary>
/// Gets or sets the start index. Use for paging.
diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs
index 983dbd2bc..4696c3797 100644
--- a/MediaBrowser.Model/Search/SearchHint.cs
+++ b/MediaBrowser.Model/Search/SearchHint.cs
@@ -1,8 +1,6 @@
-#nullable disable
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
+using Jellyfin.Data.Enums;
namespace MediaBrowser.Model.Search
{
@@ -12,11 +10,27 @@ namespace MediaBrowser.Model.Search
public class SearchHint
{
/// <summary>
+ /// Initializes a new instance of the <see cref="SearchHint" /> class.
+ /// </summary>
+ public SearchHint()
+ {
+ Name = string.Empty;
+ MatchedTerm = string.Empty;
+ MediaType = string.Empty;
+ Artists = Array.Empty<string>();
+ }
+
+ /// <summary>
/// Gets or sets the item id.
/// </summary>
/// <value>The item id.</value>
+ [Obsolete("Use Id instead")]
public Guid ItemId { get; set; }
+ /// <summary>
+ /// Gets or sets the item id.
+ /// </summary>
+ /// <value>The item id.</value>
public Guid Id { get; set; }
/// <summary>
@@ -53,38 +67,42 @@ namespace MediaBrowser.Model.Search
/// Gets or sets the image tag.
/// </summary>
/// <value>The image tag.</value>
- public string PrimaryImageTag { get; set; }
+ public string? PrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets the thumb image tag.
/// </summary>
/// <value>The thumb image tag.</value>
- public string ThumbImageTag { get; set; }
+ public string? ThumbImageTag { get; set; }
/// <summary>
/// Gets or sets the thumb image item identifier.
/// </summary>
/// <value>The thumb image item identifier.</value>
- public string ThumbImageItemId { get; set; }
+ public string? ThumbImageItemId { get; set; }
/// <summary>
/// Gets or sets the backdrop image tag.
/// </summary>
/// <value>The backdrop image tag.</value>
- public string BackdropImageTag { get; set; }
+ public string? BackdropImageTag { get; set; }
/// <summary>
/// Gets or sets the backdrop image item identifier.
/// </summary>
/// <value>The backdrop image item identifier.</value>
- public string BackdropImageItemId { get; set; }
+ public string? BackdropImageItemId { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
- public string Type { get; set; }
+ public BaseItemKind Type { get; set; }
+ /// <summary>
+ /// Gets a value indicating whether this instance is folder.
+ /// </summary>
+ /// <value><c>true</c> if this instance is folder; otherwise, <c>false</c>.</value>
public bool? IsFolder { get; set; }
/// <summary>
@@ -99,31 +117,47 @@ namespace MediaBrowser.Model.Search
/// <value>The type of the media.</value>
public string MediaType { get; set; }
+ /// <summary>
+ /// Gets or sets the start date.
+ /// </summary>
+ /// <value>The start date.</value>
public DateTime? StartDate { get; set; }
+ /// <summary>
+ /// Gets or sets the end date.
+ /// </summary>
+ /// <value>The end date.</value>
public DateTime? EndDate { get; set; }
/// <summary>
/// Gets or sets the series.
/// </summary>
/// <value>The series.</value>
- public string Series { get; set; }
+ public string? Series { get; set; }
- public string Status { get; set; }
+ /// <summary>
+ /// Gets or sets the status.
+ /// </summary>
+ /// <value>The status.</value>
+ public string? Status { get; set; }
/// <summary>
/// Gets or sets the album.
/// </summary>
/// <value>The album.</value>
- public string Album { get; set; }
+ public string? Album { get; set; }
- public Guid AlbumId { get; set; }
+ /// <summary>
+ /// Gets or sets the album id.
+ /// </summary>
+ /// <value>The album id.</value>
+ public Guid? AlbumId { get; set; }
/// <summary>
/// Gets or sets the album artist.
/// </summary>
/// <value>The album artist.</value>
- public string AlbumArtist { get; set; }
+ public string? AlbumArtist { get; set; }
/// <summary>
/// Gets or sets the artists.
@@ -147,13 +181,13 @@ namespace MediaBrowser.Model.Search
/// Gets or sets the channel identifier.
/// </summary>
/// <value>The channel identifier.</value>
- public Guid ChannelId { get; set; }
+ public Guid? ChannelId { get; set; }
/// <summary>
/// Gets or sets the name of the channel.
/// </summary>
/// <value>The name of the channel.</value>
- public string ChannelName { get; set; }
+ public string? ChannelName { get; set; }
/// <summary>
/// Gets or sets the primary image aspect ratio.
diff --git a/MediaBrowser.Model/Session/GeneralCommand.cs b/MediaBrowser.Model/Session/GeneralCommand.cs
index 757b19b31..dfbb616aa 100644
--- a/MediaBrowser.Model/Session/GeneralCommand.cs
+++ b/MediaBrowser.Model/Session/GeneralCommand.cs
@@ -14,9 +14,9 @@ public class GeneralCommand
}
[JsonConstructor]
- public GeneralCommand(Dictionary<string, string> arguments)
+ public GeneralCommand(Dictionary<string, string>? arguments)
{
- Arguments = arguments;
+ Arguments = arguments ?? new Dictionary<string, string>();
}
public GeneralCommandType Name { get; set; }
diff --git a/MediaBrowser.Model/Session/PlayerStateInfo.cs b/MediaBrowser.Model/Session/PlayerStateInfo.cs
index 0f10605ea..80e6d4e0b 100644
--- a/MediaBrowser.Model/Session/PlayerStateInfo.cs
+++ b/MediaBrowser.Model/Session/PlayerStateInfo.cs
@@ -64,5 +64,11 @@ namespace MediaBrowser.Model.Session
/// </summary>
/// <value>The repeat mode.</value>
public RepeatMode RepeatMode { get; set; }
+
+ /// <summary>
+ /// Gets or sets the now playing live stream identifier.
+ /// </summary>
+ /// <value>The live stream identifier.</value>
+ public string LiveStreamId { get; set; }
}
}
diff --git a/MediaBrowser.Model/Session/TranscodeReason.cs b/MediaBrowser.Model/Session/TranscodeReason.cs
index 9da9f3323..bbdf4536b 100644
--- a/MediaBrowser.Model/Session/TranscodeReason.cs
+++ b/MediaBrowser.Model/Session/TranscodeReason.cs
@@ -17,6 +17,7 @@ namespace MediaBrowser.Model.Session
// Video Constraints
VideoProfileNotSupported = 1 << 6,
+ VideoRangeTypeNotSupported = 1 << 24,
VideoLevelNotSupported = 1 << 7,
VideoResolutionNotSupported = 1 << 8,
VideoBitDepthNotSupported = 1 << 9,
diff --git a/MediaBrowser.Model/SyncPlay/GroupStateType.cs b/MediaBrowser.Model/SyncPlay/GroupStateType.cs
index 7aa454f92..96364cacc 100644
--- a/MediaBrowser.Model/SyncPlay/GroupStateType.cs
+++ b/MediaBrowser.Model/SyncPlay/GroupStateType.cs
@@ -11,7 +11,7 @@ namespace MediaBrowser.Model.SyncPlay
Idle = 0,
/// <summary>
- /// The group is in wating state. Playback is paused. Will start playing when users are ready.
+ /// The group is in waiting state. Playback is paused. Will start playing when users are ready.
/// </summary>
Waiting = 1,
diff --git a/MediaBrowser.Model/Tasks/ITaskManager.cs b/MediaBrowser.Model/Tasks/ITaskManager.cs
index a86bf2a1c..13bebc479 100644
--- a/MediaBrowser.Model/Tasks/ITaskManager.cs
+++ b/MediaBrowser.Model/Tasks/ITaskManager.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Model.Tasks
/// <summary>
/// Cancels if running and queue.
/// </summary>
- /// <typeparam name="T">An implementatin of <see cref="IScheduledTask" />.</typeparam>
+ /// <typeparam name="T">An implementation of <see cref="IScheduledTask" />.</typeparam>
/// <param name="options">Task options.</param>
void CancelIfRunningAndQueue<T>(TaskOptions options)
where T : IScheduledTask;
@@ -30,21 +30,21 @@ namespace MediaBrowser.Model.Tasks
/// <summary>
/// Cancels if running and queue.
/// </summary>
- /// <typeparam name="T">An implementatin of <see cref="IScheduledTask" />.</typeparam>
+ /// <typeparam name="T">An implementation of <see cref="IScheduledTask" />.</typeparam>
void CancelIfRunningAndQueue<T>()
where T : IScheduledTask;
/// <summary>
/// Cancels if running.
/// </summary>
- /// <typeparam name="T">An implementatin of <see cref="IScheduledTask" />.</typeparam>
+ /// <typeparam name="T">An implementation of <see cref="IScheduledTask" />.</typeparam>
void CancelIfRunning<T>()
where T : IScheduledTask;
/// <summary>
/// Queues the scheduled task.
/// </summary>
- /// <typeparam name="T">An implementatin of <see cref="IScheduledTask" />.</typeparam>
+ /// <typeparam name="T">An implementation of <see cref="IScheduledTask" />.</typeparam>
/// <param name="options">Task options.</param>
void QueueScheduledTask<T>(TaskOptions options)
where T : IScheduledTask;
@@ -52,7 +52,7 @@ namespace MediaBrowser.Model.Tasks
/// <summary>
/// Queues the scheduled task.
/// </summary>
- /// <typeparam name="T">An implementatin of <see cref="IScheduledTask" />.</typeparam>
+ /// <typeparam name="T">An implementation of <see cref="IScheduledTask" />.</typeparam>
void QueueScheduledTask<T>()
where T : IScheduledTask;
diff --git a/MediaBrowser.Model/Tasks/ITaskTrigger.cs b/MediaBrowser.Model/Tasks/ITaskTrigger.cs
index 8c3ec6626..0536f4ef7 100644
--- a/MediaBrowser.Model/Tasks/ITaskTrigger.cs
+++ b/MediaBrowser.Model/Tasks/ITaskTrigger.cs
@@ -21,10 +21,10 @@ namespace MediaBrowser.Model.Tasks
/// <summary>
/// Stars waiting for the trigger action.
/// </summary>
- /// <param name="lastResult">Result of the last run triggerd task.</param>
+ /// <param name="lastResult">Result of the last run triggered task.</param>
/// <param name="logger">The <see cref="ILogger"/>.</param>
/// <param name="taskName">The name of the task.</param>
- /// <param name="isApplicationStartup">Wheter or not this is is fired during startup.</param>
+ /// <param name="isApplicationStartup">Whether or not this is is fired during startup.</param>
void Start(TaskResult? lastResult, ILogger logger, string taskName, bool isApplicationStartup);
/// <summary>