aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Model
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Model')
-rw-r--r--MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs41
-rw-r--r--MediaBrowser.Model/Configuration/EncodingOptions.cs2
-rw-r--r--MediaBrowser.Model/Dlna/ContainerProfile.cs59
-rw-r--r--MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs85
-rw-r--r--MediaBrowser.Model/Dlna/DeviceProfile.cs149
-rw-r--r--MediaBrowser.Model/Dlna/DirectPlayProfile.cs8
-rw-r--r--MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs37
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs39
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs4
-rw-r--r--MediaBrowser.Model/Dlna/TranscodingProfile.cs22
-rw-r--r--MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs2
-rw-r--r--MediaBrowser.Model/Drawing/DrawingUtils.cs46
-rw-r--r--MediaBrowser.Model/Dto/NameIdPair.cs2
-rw-r--r--MediaBrowser.Model/Entities/MediaStream.cs23
-rw-r--r--MediaBrowser.Model/Entities/ProviderIdsExtensions.cs5
-rw-r--r--MediaBrowser.Model/IO/FileSystemMetadata.cs6
-rw-r--r--MediaBrowser.Model/IO/IFileSystem.cs14
-rw-r--r--MediaBrowser.Model/IO/IShortcutHandler.cs2
-rw-r--r--MediaBrowser.Model/IO/IStreamHelper.cs2
-rw-r--r--MediaBrowser.Model/LiveTv/TunerHostInfo.cs3
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj2
-rw-r--r--MediaBrowser.Model/Notifications/NotificationOptions.cs11
-rw-r--r--MediaBrowser.Model/Querying/EpisodeQuery.cs75
-rw-r--r--MediaBrowser.Model/Querying/MovieRecommendationQuery.cs47
-rw-r--r--MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs64
-rw-r--r--MediaBrowser.Model/Session/MessageCommand.cs3
-rw-r--r--MediaBrowser.Model/Sync/SyncCategory.cs22
-rw-r--r--MediaBrowser.Model/Sync/SyncJob.cs135
-rw-r--r--MediaBrowser.Model/Sync/SyncJobStatus.cs15
-rw-r--r--MediaBrowser.Model/Sync/SyncTarget.cs20
-rw-r--r--MediaBrowser.Model/Tasks/ITaskTrigger.cs2
-rw-r--r--MediaBrowser.Model/Users/UserAction.cs24
32 files changed, 294 insertions, 677 deletions
diff --git a/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs b/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs
index fcc90a1f7..f9f474586 100644
--- a/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs
+++ b/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs
@@ -1,32 +1,43 @@
-#nullable disable
-#pragma warning disable CS1591
-
namespace MediaBrowser.Model.ApiClient
{
+ /// <summary>
+ /// The server discovery info model.
+ /// </summary>
public class ServerDiscoveryInfo
{
/// <summary>
- /// Gets or sets the address.
+ /// Initializes a new instance of the <see cref="ServerDiscoveryInfo"/> class.
+ /// </summary>
+ /// <param name="address">The server address.</param>
+ /// <param name="id">The server id.</param>
+ /// <param name="name">The server name.</param>
+ /// <param name="endpointAddress">The endpoint address.</param>
+ public ServerDiscoveryInfo(string address, string id, string name, string? endpointAddress = null)
+ {
+ Address = address;
+ Id = id;
+ Name = name;
+ EndpointAddress = endpointAddress;
+ }
+
+ /// <summary>
+ /// Gets the address.
/// </summary>
- /// <value>The address.</value>
- public string Address { get; set; }
+ public string Address { get; }
/// <summary>
- /// Gets or sets the server identifier.
+ /// Gets the server identifier.
/// </summary>
- /// <value>The server identifier.</value>
- public string Id { get; set; }
+ public string Id { get; }
/// <summary>
- /// Gets or sets the name.
+ /// Gets the name.
/// </summary>
- /// <value>The name.</value>
- public string Name { get; set; }
+ public string Name { get; }
/// <summary>
- /// Gets or sets the endpoint address.
+ /// Gets the endpoint address.
/// </summary>
- /// <value>The endpoint address.</value>
- public string EndpointAddress { get; set; }
+ public string? EndpointAddress { get; }
}
}
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs
index a9b280301..365bbeef6 100644
--- a/MediaBrowser.Model/Configuration/EncodingOptions.cs
+++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs
@@ -35,7 +35,7 @@ namespace MediaBrowser.Model.Configuration
EnableDecodingColorDepth10Vp9 = true;
EnableEnhancedNvdecDecoder = true;
EnableHardwareEncoding = true;
- AllowHevcEncoding = true;
+ AllowHevcEncoding = false;
EnableSubtitleExtraction = true;
HardwareDecodingCodecs = new string[] { "h264", "vc1" };
}
diff --git a/MediaBrowser.Model/Dlna/ContainerProfile.cs b/MediaBrowser.Model/Dlna/ContainerProfile.cs
index d83c8f2f3..740966088 100644
--- a/MediaBrowser.Model/Dlna/ContainerProfile.cs
+++ b/MediaBrowser.Model/Dlna/ContainerProfile.cs
@@ -1,4 +1,3 @@
-#nullable disable
#pragma warning disable CS1591
using System;
@@ -9,25 +8,15 @@ namespace MediaBrowser.Model.Dlna
{
public class ContainerProfile
{
- public ContainerProfile()
- {
- Conditions = Array.Empty<ProfileCondition>();
- }
-
[XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
- public ProfileCondition[] Conditions { get; set; }
+ public ProfileCondition[]? Conditions { get; set; } = Array.Empty<ProfileCondition>();
[XmlAttribute("container")]
- public string Container { get; set; }
-
- public string[] GetContainers()
- {
- return SplitValue(Container);
- }
+ public string Container { get; set; } = string.Empty;
- public static string[] SplitValue(string value)
+ public static string[] SplitValue(string? value)
{
if (string.IsNullOrEmpty(value))
{
@@ -37,14 +26,14 @@ namespace MediaBrowser.Model.Dlna
return value.Split(',', StringSplitOptions.RemoveEmptyEntries);
}
- public bool ContainsContainer(string container)
+ public bool ContainsContainer(string? container)
{
- var containers = GetContainers();
+ var containers = SplitValue(Container);
return ContainsContainer(containers, container);
}
- public static bool ContainsContainer(string profileContainers, string inputContainer)
+ public static bool ContainsContainer(string? profileContainers, string? inputContainer)
{
var isNegativeList = false;
if (profileContainers != null && profileContainers.StartsWith('-'))
@@ -56,46 +45,30 @@ namespace MediaBrowser.Model.Dlna
return ContainsContainer(SplitValue(profileContainers), isNegativeList, inputContainer);
}
- public static bool ContainsContainer(string[] profileContainers, string inputContainer)
+ public static bool ContainsContainer(string[]? profileContainers, string? inputContainer)
{
return ContainsContainer(profileContainers, false, inputContainer);
}
- public static bool ContainsContainer(string[] profileContainers, bool isNegativeList, string inputContainer)
+ public static bool ContainsContainer(string[]? profileContainers, bool isNegativeList, string? inputContainer)
{
- if (profileContainers.Length == 0)
+ if (profileContainers == null || profileContainers.Length == 0)
{
+ // Empty profiles always support all containers/codecs
return true;
}
- if (isNegativeList)
- {
- var allInputContainers = SplitValue(inputContainer);
+ var allInputContainers = SplitValue(inputContainer);
- foreach (var container in allInputContainers)
- {
- if (profileContainers.Contains(container, StringComparer.OrdinalIgnoreCase))
- {
- return false;
- }
- }
-
- return true;
- }
- else
+ foreach (var container in allInputContainers)
{
- var allInputContainers = SplitValue(inputContainer);
-
- foreach (var container in allInputContainers)
+ if (profileContainers.Contains(container, StringComparer.OrdinalIgnoreCase))
{
- if (profileContainers.Contains(container, StringComparer.OrdinalIgnoreCase))
- {
- return true;
- }
+ return !isNegativeList;
}
-
- return false;
}
+
+ return isNegativeList;
}
}
}
diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
index ec106f105..600a44157 100644
--- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
+++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
@@ -10,14 +10,8 @@ namespace MediaBrowser.Model.Dlna
{
public class ContentFeatureBuilder
{
- private readonly DeviceProfile _profile;
-
- public ContentFeatureBuilder(DeviceProfile profile)
- {
- _profile = profile;
- }
-
- public string BuildImageHeader(
+ public static string BuildImageHeader(
+ DeviceProfile profile,
string container,
int? width,
int? height,
@@ -38,27 +32,31 @@ namespace MediaBrowser.Model.Dlna
";DLNA.ORG_FLAGS={0}",
DlnaMaps.FlagsToString(flagValue));
- ResponseProfile mediaProfile = _profile.GetImageMediaProfile(
- container,
- width,
- height);
-
if (string.IsNullOrEmpty(orgPn))
{
+ ResponseProfile mediaProfile = profile.GetImageMediaProfile(
+ container,
+ width,
+ height);
+
orgPn = mediaProfile?.OrgPn;
+
+ if (string.IsNullOrEmpty(orgPn))
+ {
+ orgPn = GetImageOrgPnValue(container, width, height);
+ }
}
if (string.IsNullOrEmpty(orgPn))
{
- orgPn = GetImageOrgPnValue(container, width, height);
+ return orgOp.TrimStart(';') + orgCi + dlnaflags;
}
- string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
-
- return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
+ return "DLNA.ORG_PN=" + orgPn + orgOp + orgCi + dlnaflags;
}
- public string BuildAudioHeader(
+ public static string BuildAudioHeader(
+ DeviceProfile profile,
string container,
string audioCodec,
int? audioBitrate,
@@ -94,7 +92,7 @@ namespace MediaBrowser.Model.Dlna
";DLNA.ORG_FLAGS={0}",
DlnaMaps.FlagsToString(flagValue));
- ResponseProfile mediaProfile = _profile.GetAudioMediaProfile(
+ ResponseProfile mediaProfile = profile.GetAudioMediaProfile(
container,
audioCodec,
audioChannels,
@@ -109,12 +107,16 @@ namespace MediaBrowser.Model.Dlna
orgPn = GetAudioOrgPnValue(container, audioBitrate, audioSampleRate, audioChannels);
}
- string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
+ if (string.IsNullOrEmpty(orgPn))
+ {
+ return orgOp.TrimStart(';') + orgCi + dlnaflags;
+ }
- return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
+ return "DLNA.ORG_PN=" + orgPn + orgOp + orgCi + dlnaflags;
}
- public List<string> BuildVideoHeader(
+ public static List<string> BuildVideoHeader(
+ DeviceProfile profile,
string container,
string videoCodec,
string audioCodec,
@@ -163,7 +165,7 @@ namespace MediaBrowser.Model.Dlna
";DLNA.ORG_FLAGS={0}",
DlnaMaps.FlagsToString(flagValue));
- ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(
+ ResponseProfile mediaProfile = profile.GetVideoMediaProfile(
container,
audioCodec,
videoCodec,
@@ -192,9 +194,9 @@ namespace MediaBrowser.Model.Dlna
}
else
{
- foreach (string s in GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp))
+ foreach (var s in GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp))
{
- orgPnValues.Add(s);
+ orgPnValues.Add(s.ToString());
break;
}
}
@@ -203,20 +205,20 @@ namespace MediaBrowser.Model.Dlna
foreach (string orgPn in orgPnValues)
{
- string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
-
- var value = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
-
- contentFeatureList.Add(value);
+ if (string.IsNullOrEmpty(orgPn))
+ {
+ contentFeatureList.Add(orgOp.TrimStart(';') + orgCi + dlnaflags);
+ continue;
+ }
+ else
+ {
+ contentFeatureList.Add("DLNA.ORG_PN=" + orgPn + orgCi + dlnaflags);
+ }
}
if (orgPnValues.Count == 0)
{
- string contentFeatures = string.Empty;
-
- var value = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
-
- contentFeatureList.Add(value);
+ contentFeatureList.Add(orgOp.TrimStart(';') + orgCi + dlnaflags);
}
return contentFeatureList;
@@ -224,19 +226,14 @@ namespace MediaBrowser.Model.Dlna
private static string GetImageOrgPnValue(string container, int? width, int? height)
{
- MediaFormatProfile? format = new MediaFormatProfileResolver()
- .ResolveImageFormat(
- container,
- width,
- height);
+ MediaFormatProfile? format = MediaFormatProfileResolver.ResolveImageFormat(container, width, height);
return format.HasValue ? format.Value.ToString() : null;
}
private static string GetAudioOrgPnValue(string container, int? audioBitrate, int? audioSampleRate, int? audioChannels)
{
- MediaFormatProfile? format = new MediaFormatProfileResolver()
- .ResolveAudioFormat(
+ MediaFormatProfile? format = MediaFormatProfileResolver.ResolveAudioFormat(
container,
audioBitrate,
audioSampleRate,
@@ -245,9 +242,9 @@ namespace MediaBrowser.Model.Dlna
return format.HasValue ? format.Value.ToString() : null;
}
- private static string[] GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp)
+ private static MediaFormatProfile[] GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp)
{
- return new MediaFormatProfileResolver().ResolveVideoFormat(container, videoCodec, audioCodec, width, height, timestamp);
+ return MediaFormatProfileResolver.ResolveVideoFormat(container, videoCodec, audioCodec, width, height, timestamp);
}
}
}
diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs
index ff5186658..feb3d880e 100644
--- a/MediaBrowser.Model/Dlna/DeviceProfile.cs
+++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs
@@ -1,6 +1,6 @@
-#nullable disable
#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;
@@ -8,226 +8,219 @@ using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Model.Dlna
{
/// <summary>
- /// Defines the <see cref="DeviceProfile" />.
+ /// A <see cref="DeviceProfile" /> represents a set of metadata which determines which content a certain device is able to play.
+ /// <br/>
+ /// Specifically, it defines the supported <see cref="ContainerProfiles">containers</see> and
+ /// <see cref="CodecProfiles">codecs</see> (video and/or audio, including codec profiles and levels)
+ /// the device is able to direct play (without transcoding or remuxing),
+ /// as well as which <see cref="TranscodingProfiles">containers/codecs to transcode to</see> in case it isn't.
/// </summary>
[XmlRoot("Profile")]
public class DeviceProfile
{
/// <summary>
- /// Initializes a new instance of the <see cref="DeviceProfile"/> class.
+ /// Gets or sets the name of this device profile.
/// </summary>
- public DeviceProfile()
- {
- DirectPlayProfiles = Array.Empty<DirectPlayProfile>();
- TranscodingProfiles = Array.Empty<TranscodingProfile>();
- ResponseProfiles = Array.Empty<ResponseProfile>();
- CodecProfiles = Array.Empty<CodecProfile>();
- ContainerProfiles = Array.Empty<ContainerProfile>();
- SubtitleProfiles = Array.Empty<SubtitleProfile>();
-
- XmlRootAttributes = Array.Empty<XmlAttribute>();
-
- SupportedMediaTypes = "Audio,Photo,Video";
- MaxStreamingBitrate = 8000000;
- MaxStaticBitrate = 8000000;
- MusicStreamingTranscodingBitrate = 128000;
- }
-
- /// <summary>
- /// Gets or sets the Name.
- /// </summary>
- public string Name { get; set; }
+ public string? Name { get; set; }
/// <summary>
/// Gets or sets the Id.
/// </summary>
[XmlIgnore]
- public string Id { get; set; }
+ public string? Id { get; set; }
/// <summary>
/// Gets or sets the Identification.
/// </summary>
- public DeviceIdentification Identification { get; set; }
+ public DeviceIdentification? Identification { get; set; }
/// <summary>
- /// Gets or sets the FriendlyName.
+ /// Gets or sets the friendly name of the device profile, which can be shown to users.
/// </summary>
- public string FriendlyName { get; set; }
+ public string? FriendlyName { get; set; }
/// <summary>
- /// Gets or sets the Manufacturer.
+ /// Gets or sets the manufacturer of the device which this profile represents.
/// </summary>
- public string Manufacturer { get; set; }
+ public string? Manufacturer { get; set; }
/// <summary>
- /// Gets or sets the ManufacturerUrl.
+ /// Gets or sets an url for the manufacturer of the device which this profile represents.
/// </summary>
- public string ManufacturerUrl { get; set; }
+ public string? ManufacturerUrl { get; set; }
/// <summary>
- /// Gets or sets the ModelName.
+ /// Gets or sets the model name of the device which this profile represents.
/// </summary>
- public string ModelName { get; set; }
+ public string? ModelName { get; set; }
/// <summary>
- /// Gets or sets the ModelDescription.
+ /// Gets or sets the model description of the device which this profile represents.
/// </summary>
- public string ModelDescription { get; set; }
+ public string? ModelDescription { get; set; }
/// <summary>
- /// Gets or sets the ModelNumber.
+ /// Gets or sets the model number of the device which this profile represents.
/// </summary>
- public string ModelNumber { get; set; }
+ public string? ModelNumber { get; set; }
/// <summary>
/// Gets or sets the ModelUrl.
/// </summary>
- public string ModelUrl { get; set; }
+ public string? ModelUrl { get; set; }
/// <summary>
- /// Gets or sets the SerialNumber.
+ /// Gets or sets the serial number of the device which this profile represents.
/// </summary>
- public string SerialNumber { get; set; }
+ public string? SerialNumber { get; set; }
/// <summary>
/// Gets or sets a value indicating whether EnableAlbumArtInDidl.
/// </summary>
+ [DefaultValue(false)]
public bool EnableAlbumArtInDidl { get; set; }
/// <summary>
/// Gets or sets a value indicating whether EnableSingleAlbumArtLimit.
/// </summary>
+ [DefaultValue(false)]
public bool EnableSingleAlbumArtLimit { get; set; }
/// <summary>
/// Gets or sets a value indicating whether EnableSingleSubtitleLimit.
/// </summary>
+ [DefaultValue(false)]
public bool EnableSingleSubtitleLimit { get; set; }
/// <summary>
/// Gets or sets the SupportedMediaTypes.
/// </summary>
- public string SupportedMediaTypes { get; set; }
+ public string SupportedMediaTypes { get; set; } = "Audio,Photo,Video";
/// <summary>
/// Gets or sets the UserId.
/// </summary>
- public string UserId { get; set; }
+ public string? UserId { get; set; }
/// <summary>
/// Gets or sets the AlbumArtPn.
/// </summary>
- public string AlbumArtPn { get; set; }
+ public string? AlbumArtPn { get; set; }
/// <summary>
/// Gets or sets the MaxAlbumArtWidth.
/// </summary>
- public int MaxAlbumArtWidth { get; set; }
+ public int? MaxAlbumArtWidth { get; set; }
/// <summary>
/// Gets or sets the MaxAlbumArtHeight.
/// </summary>
- public int MaxAlbumArtHeight { get; set; }
+ public int? MaxAlbumArtHeight { get; set; }
/// <summary>
- /// Gets or sets the MaxIconWidth.
+ /// Gets or sets the maximum allowed width of embedded icons.
/// </summary>
public int? MaxIconWidth { get; set; }
/// <summary>
- /// Gets or sets the MaxIconHeight.
+ /// Gets or sets the maximum allowed height of embedded icons.
/// </summary>
public int? MaxIconHeight { get; set; }
/// <summary>
- /// Gets or sets the MaxStreamingBitrate.
+ /// Gets or sets the maximum allowed bitrate for all streamed content.
/// </summary>
- public int? MaxStreamingBitrate { get; set; }
+ public int? MaxStreamingBitrate { get; set; } = 8000000;
/// <summary>
- /// Gets or sets the MaxStaticBitrate.
+ /// Gets or sets the maximum allowed bitrate for statically streamed content (= direct played files).
/// </summary>
- public int? MaxStaticBitrate { get; set; }
+ public int? MaxStaticBitrate { get; set; } = 8000000;
/// <summary>
- /// Gets or sets the MusicStreamingTranscodingBitrate.
+ /// Gets or sets the maximum allowed bitrate for transcoded music streams.
/// </summary>
- public int? MusicStreamingTranscodingBitrate { get; set; }
+ public int? MusicStreamingTranscodingBitrate { get; set; } = 128000;
/// <summary>
- /// Gets or sets the MaxStaticMusicBitrate.
+ /// Gets or sets the maximum allowed bitrate for statically streamed (= direct played) music files.
/// </summary>
- public int? MaxStaticMusicBitrate { get; set; }
+ public int? MaxStaticMusicBitrate { get; set; } = 8000000;
/// <summary>
/// Gets or sets the content of the aggregationFlags element in the urn:schemas-sonycom:av namespace.
/// </summary>
- public string SonyAggregationFlags { get; set; }
+ public string? SonyAggregationFlags { get; set; }
/// <summary>
/// Gets or sets the ProtocolInfo.
/// </summary>
- public string ProtocolInfo { get; set; }
+ public string? ProtocolInfo { get; set; }
/// <summary>
/// Gets or sets the TimelineOffsetSeconds.
/// </summary>
+ [DefaultValue(0)]
public int TimelineOffsetSeconds { get; set; }
/// <summary>
/// Gets or sets a value indicating whether RequiresPlainVideoItems.
/// </summary>
+ [DefaultValue(false)]
public bool RequiresPlainVideoItems { get; set; }
/// <summary>
/// Gets or sets a value indicating whether RequiresPlainFolders.
/// </summary>
+ [DefaultValue(false)]
public bool RequiresPlainFolders { get; set; }
/// <summary>
/// Gets or sets a value indicating whether EnableMSMediaReceiverRegistrar.
/// </summary>
+ [DefaultValue(false)]
public bool EnableMSMediaReceiverRegistrar { get; set; }
/// <summary>
/// Gets or sets a value indicating whether IgnoreTranscodeByteRangeRequests.
/// </summary>
+ [DefaultValue(false)]
public bool IgnoreTranscodeByteRangeRequests { get; set; }
/// <summary>
/// Gets or sets the XmlRootAttributes.
/// </summary>
- public XmlAttribute[] XmlRootAttributes { get; set; }
+ public XmlAttribute[] XmlRootAttributes { get; set; } = Array.Empty<XmlAttribute>();
/// <summary>
/// Gets or sets the direct play profiles.
/// </summary>
- public DirectPlayProfile[] DirectPlayProfiles { get; set; }
+ public DirectPlayProfile[] DirectPlayProfiles { get; set; } = Array.Empty<DirectPlayProfile>();
/// <summary>
/// Gets or sets the transcoding profiles.
/// </summary>
- public TranscodingProfile[] TranscodingProfiles { get; set; }
+ public TranscodingProfile[] TranscodingProfiles { get; set; } = Array.Empty<TranscodingProfile>();
/// <summary>
- /// Gets or sets the ContainerProfiles.
+ /// Gets or sets the container profiles.
/// </summary>
- public ContainerProfile[] ContainerProfiles { get; set; }
+ public ContainerProfile[] ContainerProfiles { get; set; } = Array.Empty<ContainerProfile>();
/// <summary>
- /// Gets or sets the CodecProfiles.
+ /// Gets or sets the codec profiles.
/// </summary>
- public CodecProfile[] CodecProfiles { get; set; }
+ public CodecProfile[] CodecProfiles { get; set; } = Array.Empty<CodecProfile>();
/// <summary>
/// Gets or sets the ResponseProfiles.
/// </summary>
- public ResponseProfile[] ResponseProfiles { get; set; }
+ public ResponseProfile[] ResponseProfiles { get; set; } = Array.Empty<ResponseProfile>();
/// <summary>
- /// Gets or sets the SubtitleProfiles.
+ /// Gets or sets the subtitle profiles.
/// </summary>
- public SubtitleProfile[] SubtitleProfiles { get; set; }
+ public SubtitleProfile[] SubtitleProfiles { get; set; } = Array.Empty<SubtitleProfile>();
/// <summary>
/// The GetSupportedMediaTypes.
@@ -244,13 +237,13 @@ namespace MediaBrowser.Model.Dlna
/// <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)
+ public TranscodingProfile? GetAudioTranscodingProfile(string? container, string? audioCodec)
{
container = (container ?? string.Empty).TrimStart('.');
foreach (var i in TranscodingProfiles)
{
- if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Audio)
+ if (i.Type != DlnaProfileType.Audio)
{
continue;
}
@@ -278,13 +271,13 @@ namespace MediaBrowser.Model.Dlna
/// <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)
+ public TranscodingProfile? GetVideoTranscodingProfile(string? container, string? audioCodec, string? videoCodec)
{
container = (container ?? string.Empty).TrimStart('.');
foreach (var i in TranscodingProfiles)
{
- if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Video)
+ if (i.Type != DlnaProfileType.Video)
{
continue;
}
@@ -299,7 +292,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- if (!string.Equals(videoCodec, i.VideoCodec ?? string.Empty, StringComparison.OrdinalIgnoreCase))
+ if (!string.Equals(videoCodec, i.VideoCodec, StringComparison.OrdinalIgnoreCase))
{
continue;
}
@@ -320,7 +313,7 @@ namespace MediaBrowser.Model.Dlna
/// <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)
+ public ResponseProfile? GetAudioMediaProfile(string container, string? audioCodec, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth)
{
foreach (var i in ResponseProfiles)
{
@@ -384,7 +377,7 @@ namespace MediaBrowser.Model.Dlna
/// <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)
+ public ResponseProfile? GetImageMediaProfile(string container, int? width, int? height)
{
foreach (var i in ResponseProfiles)
{
@@ -442,10 +435,10 @@ namespace MediaBrowser.Model.Dlna
/// <param name="videoCodecTag">The video Codec tag.</param>
/// <param name="isAvc">True if Avc.</param>
/// <returns>The <see cref="ResponseProfile"/>.</returns>
- public ResponseProfile GetVideoMediaProfile(
+ public ResponseProfile? GetVideoMediaProfile(
string container,
- string audioCodec,
- string videoCodec,
+ string? audioCodec,
+ string? videoCodec,
int? width,
int? height,
int? bitDepth,
diff --git a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs
index 88cb83991..fa3ad098f 100644
--- a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs
+++ b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs
@@ -1,6 +1,6 @@
-#nullable disable
#pragma warning disable CS1591
+using System.ComponentModel.DataAnnotations;
using System.Xml.Serialization;
namespace MediaBrowser.Model.Dlna
@@ -8,13 +8,13 @@ namespace MediaBrowser.Model.Dlna
public class DirectPlayProfile
{
[XmlAttribute("container")]
- public string Container { get; set; }
+ public string? Container { get; set; }
[XmlAttribute("audioCodec")]
- public string AudioCodec { get; set; }
+ public string? AudioCodec { get; set; }
[XmlAttribute("videoCodec")]
- public string VideoCodec { get; set; }
+ public string? VideoCodec { get; set; }
[XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
index f61b8d59e..7ce248509 100644
--- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
+++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
@@ -9,16 +9,9 @@ using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Model.Dlna
{
- public class MediaFormatProfileResolver
+ public static class MediaFormatProfileResolver
{
- public string[] ResolveVideoFormat(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType)
- {
- return ResolveVideoFormatInternal(container, videoCodec, audioCodec, width, height, timestampType)
- .Select(i => i.ToString())
- .ToArray();
- }
-
- private MediaFormatProfile[] ResolveVideoFormatInternal(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType)
+ public static MediaFormatProfile[] ResolveVideoFormat(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType)
{
if (string.Equals(container, "asf", StringComparison.OrdinalIgnoreCase))
{
@@ -84,7 +77,7 @@ namespace MediaBrowser.Model.Dlna
return Array.Empty<MediaFormatProfile>();
}
- private MediaFormatProfile[] ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType)
+ private static MediaFormatProfile[] ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType)
{
string suffix = string.Empty;
@@ -209,12 +202,12 @@ namespace MediaBrowser.Model.Dlna
return Array.Empty<MediaFormatProfile>();
}
- private MediaFormatProfile ValueOf(string value)
+ private static MediaFormatProfile ValueOf(string value)
{
return (MediaFormatProfile)Enum.Parse(typeof(MediaFormatProfile), value, true);
}
- private MediaFormatProfile? ResolveVideoMP4Format(string videoCodec, string audioCodec, int? width, int? height)
+ private static MediaFormatProfile? ResolveVideoMP4Format(string videoCodec, string audioCodec, int? width, int? height)
{
if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase))
{
@@ -287,7 +280,7 @@ namespace MediaBrowser.Model.Dlna
return null;
}
- private MediaFormatProfile? ResolveVideo3GPFormat(string videoCodec, string audioCodec)
+ private static MediaFormatProfile? ResolveVideo3GPFormat(string videoCodec, string audioCodec)
{
if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase))
{
@@ -317,7 +310,7 @@ namespace MediaBrowser.Model.Dlna
return null;
}
- private MediaFormatProfile? ResolveVideoASFFormat(string videoCodec, string audioCodec, int? width, int? height)
+ private static MediaFormatProfile? ResolveVideoASFFormat(string videoCodec, string audioCodec, int? width, int? height)
{
if (string.Equals(videoCodec, "wmv", StringComparison.OrdinalIgnoreCase) &&
(string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "wma", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "wmapro", StringComparison.OrdinalIgnoreCase)))
@@ -371,7 +364,7 @@ namespace MediaBrowser.Model.Dlna
return null;
}
- public MediaFormatProfile? ResolveAudioFormat(string container, int? bitrate, int? frequency, int? channels)
+ public static MediaFormatProfile? ResolveAudioFormat(string container, int? bitrate, int? frequency, int? channels)
{
if (string.Equals(container, "asf", StringComparison.OrdinalIgnoreCase))
{
@@ -413,7 +406,7 @@ namespace MediaBrowser.Model.Dlna
return null;
}
- private MediaFormatProfile ResolveAudioASFFormat(int? bitrate)
+ private static MediaFormatProfile ResolveAudioASFFormat(int? bitrate)
{
if (bitrate.HasValue && bitrate.Value <= 193)
{
@@ -423,7 +416,7 @@ namespace MediaBrowser.Model.Dlna
return MediaFormatProfile.WMA_FULL;
}
- private MediaFormatProfile? ResolveAudioLPCMFormat(int? frequency, int? channels)
+ private static MediaFormatProfile? ResolveAudioLPCMFormat(int? frequency, int? channels)
{
if (frequency.HasValue && channels.HasValue)
{
@@ -453,7 +446,7 @@ namespace MediaBrowser.Model.Dlna
return MediaFormatProfile.LPCM16_48_STEREO;
}
- private MediaFormatProfile ResolveAudioMP4Format(int? bitrate)
+ private static MediaFormatProfile ResolveAudioMP4Format(int? bitrate)
{
if (bitrate.HasValue && bitrate.Value <= 320)
{
@@ -463,7 +456,7 @@ namespace MediaBrowser.Model.Dlna
return MediaFormatProfile.AAC_ISO;
}
- private MediaFormatProfile ResolveAudioADTSFormat(int? bitrate)
+ private static MediaFormatProfile ResolveAudioADTSFormat(int? bitrate)
{
if (bitrate.HasValue && bitrate.Value <= 320)
{
@@ -473,7 +466,7 @@ namespace MediaBrowser.Model.Dlna
return MediaFormatProfile.AAC_ADTS;
}
- public MediaFormatProfile? ResolveImageFormat(string container, int? width, int? height)
+ public static MediaFormatProfile? ResolveImageFormat(string container, int? width, int? height)
{
if (string.Equals(container, "jpeg", StringComparison.OrdinalIgnoreCase) ||
string.Equals(container, "jpg", StringComparison.OrdinalIgnoreCase))
@@ -499,7 +492,7 @@ namespace MediaBrowser.Model.Dlna
return null;
}
- private MediaFormatProfile ResolveImageJPGFormat(int? width, int? height)
+ private static MediaFormatProfile ResolveImageJPGFormat(int? width, int? height)
{
if (width.HasValue && height.HasValue)
{
@@ -524,7 +517,7 @@ namespace MediaBrowser.Model.Dlna
return MediaFormatProfile.JPEG_SM;
}
- private MediaFormatProfile ResolveImagePNGFormat(int? width, int? height)
+ private static MediaFormatProfile ResolveImagePNGFormat(int? width, int? height)
{
if (width.HasValue && height.HasValue)
{
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index bf33691c7..f4c69fe8f 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -297,7 +297,7 @@ namespace MediaBrowser.Model.Dlna
int? inputAudioSampleRate = audioStream?.SampleRate;
int? inputAudioBitDepth = audioStream?.BitDepth;
- if (directPlayMethods.Count() > 0)
+ if (directPlayMethods.Any())
{
string audioCodec = audioStream?.Codec;
@@ -514,6 +514,8 @@ namespace MediaBrowser.Model.Dlna
private static List<TranscodeReason> GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable<DirectPlayProfile> directPlayProfiles)
{
+ var mediaType = videoStream == null ? DlnaProfileType.Audio : DlnaProfileType.Video;
+
var containerSupported = false;
var audioSupported = false;
var videoSupported = false;
@@ -521,7 +523,7 @@ namespace MediaBrowser.Model.Dlna
foreach (var profile in directPlayProfiles)
{
// Check container type
- if (profile.SupportsContainer(item.Container))
+ if (profile.Type == mediaType && profile.SupportsContainer(item.Container))
{
containerSupported = true;
@@ -674,7 +676,7 @@ namespace MediaBrowser.Model.Dlna
var videoStream = item.VideoStream;
- // TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough
+ // TODO: This doesn't account for situations where the device is able to handle the media's bitrate, but the connection isn't fast enough
var directPlayEligibilityResult = IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true) ?? 0, subtitleStream, options, PlayMethod.DirectPlay);
var directStreamEligibilityResult = IsEligibleForDirectPlay(item, options.GetMaxBitrate(false) ?? 0, subtitleStream, options, PlayMethod.DirectStream);
bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || directPlayEligibilityResult.Item1);
@@ -1017,14 +1019,15 @@ namespace MediaBrowser.Model.Dlna
}
DeviceProfile profile = options.Profile;
+ string container = mediaSource.Container;
// See if it can be direct played
DirectPlayProfile directPlay = null;
- foreach (var i in profile.DirectPlayProfiles)
+ foreach (var p in profile.DirectPlayProfiles)
{
- if (i.Type == DlnaProfileType.Video && IsVideoDirectPlaySupported(i, mediaSource, videoStream, audioStream))
+ if (p.Type == DlnaProfileType.Video && IsVideoDirectPlaySupported(p, container, videoStream, audioStream))
{
- directPlay = i;
+ directPlay = p;
break;
}
}
@@ -1032,23 +1035,23 @@ namespace MediaBrowser.Model.Dlna
if (directPlay == null)
{
_logger.LogInformation(
- "Profile: {0}, No video direct play profiles found for {1} with codec {2}",
- profile?.Name ?? "Unknown Profile",
- mediaSource?.Path ?? "Unknown path",
- videoStream?.Codec ?? "Unknown codec");
+ "Container: {Container}, Video: {Video}, Audio: {Audio} cannot be direct played by profile: {Profile} for path: {Path}",
+ container,
+ videoStream?.Codec ?? "no video",
+ audioStream?.Codec ?? "no audio",
+ profile.Name ?? "unknown profile",
+ mediaSource.Path ?? "unknown path");
return (null, GetTranscodeReasonsFromDirectPlayProfile(mediaSource, videoStream, audioStream, profile.DirectPlayProfiles));
}
- string container = mediaSource.Container;
-
var conditions = new List<ProfileCondition>();
- foreach (var i in profile.ContainerProfiles)
+ foreach (var p in profile.ContainerProfiles)
{
- if (i.Type == DlnaProfileType.Video
- && i.ContainsContainer(container))
+ if (p.Type == DlnaProfileType.Video
+ && p.ContainsContainer(container))
{
- foreach (var c in i.Conditions)
+ foreach (var c in p.Conditions)
{
conditions.Add(c);
}
@@ -1896,10 +1899,10 @@ namespace MediaBrowser.Model.Dlna
return true;
}
- private bool IsVideoDirectPlaySupported(DirectPlayProfile profile, MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream)
+ private bool IsVideoDirectPlaySupported(DirectPlayProfile profile, string container, MediaStream videoStream, MediaStream audioStream)
{
// Check container type
- if (!profile.SupportsContainer(item.Container))
+ if (!profile.SupportsContainer(container))
{
return false;
}
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 29da5d9e7..252872847 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -630,10 +630,8 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- // Be careful, IsDirectStream==true by default (Static != false or not in query).
- // See initialization of StreamingRequestDto in AudioController.GetAudioStream() method : Static = @static ?? true.
if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase) &&
- string.Equals(pair.Value, "true", StringComparison.OrdinalIgnoreCase))
+ string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase))
{
continue;
}
diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
index f05e31047..214578a85 100644
--- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs
+++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
@@ -1,6 +1,7 @@
-#nullable disable
#pragma warning disable CS1591
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
using System.Xml.Serialization;
namespace MediaBrowser.Model.Dlna
@@ -8,47 +9,56 @@ namespace MediaBrowser.Model.Dlna
public class TranscodingProfile
{
[XmlAttribute("container")]
- public string Container { get; set; }
+ public string Container { get; set; } = string.Empty;
[XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
[XmlAttribute("videoCodec")]
- public string VideoCodec { get; set; }
+ public string VideoCodec { get; set; } = string.Empty;
[XmlAttribute("audioCodec")]
- public string AudioCodec { get; set; }
+ public string AudioCodec { get; set; } = string.Empty;
[XmlAttribute("protocol")]
- public string Protocol { get; set; }
+ public string Protocol { get; set; } = string.Empty;
+ [DefaultValue(false)]
[XmlAttribute("estimateContentLength")]
public bool EstimateContentLength { get; set; }
+ [DefaultValue(false)]
[XmlAttribute("enableMpegtsM2TsMode")]
public bool EnableMpegtsM2TsMode { get; set; }
+ [DefaultValue(TranscodeSeekInfo.Auto)]
[XmlAttribute("transcodeSeekInfo")]
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
+ [DefaultValue(false)]
[XmlAttribute("copyTimestamps")]
public bool CopyTimestamps { get; set; }
+ [DefaultValue(EncodingContext.Streaming)]
[XmlAttribute("context")]
public EncodingContext Context { get; set; }
+ [DefaultValue(false)]
[XmlAttribute("enableSubtitlesInManifest")]
public bool EnableSubtitlesInManifest { get; set; }
[XmlAttribute("maxAudioChannels")]
- public string MaxAudioChannels { get; set; }
+ public string? MaxAudioChannels { get; set; }
+ [DefaultValue(0)]
[XmlAttribute("minSegments")]
public int MinSegments { get; set; }
+ [DefaultValue(0)]
[XmlAttribute("segmentLength")]
public int SegmentLength { get; set; }
+ [DefaultValue(false)]
[XmlAttribute("breakOnNonKeyFrames")]
public bool BreakOnNonKeyFrames { get; set; }
diff --git a/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs b/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs
index d71013f01..987a3a908 100644
--- a/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs
+++ b/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs
@@ -16,5 +16,7 @@ namespace MediaBrowser.Model.Dlna
public IPAddress LocalIpAddress { get; set; }
public int LocalPort { get; set; }
+
+ public IPAddress RemoteIpAddress { get; set; }
}
}
diff --git a/MediaBrowser.Model/Drawing/DrawingUtils.cs b/MediaBrowser.Model/Drawing/DrawingUtils.cs
index 1512c5233..556792768 100644
--- a/MediaBrowser.Model/Drawing/DrawingUtils.cs
+++ b/MediaBrowser.Model/Drawing/DrawingUtils.cs
@@ -58,6 +58,52 @@ namespace MediaBrowser.Model.Drawing
}
/// <summary>
+ /// Scale down to fill box.
+ /// Returns original size if both width and height are null or zero.
+ /// </summary>
+ /// <param name="size">The original size object.</param>
+ /// <param name="fillWidth">A new fixed width, if desired.</param>
+ /// <param name="fillHeight">A new fixed height, if desired.</param>
+ /// <returns>A new size object or size.</returns>
+ public static ImageDimensions ResizeFill(
+ ImageDimensions size,
+ int? fillWidth,
+ int? fillHeight)
+ {
+ // Return original size if input is invalid.
+ if ((fillWidth == null || fillWidth == 0)
+ && (fillHeight == null || fillHeight == 0))
+ {
+ return size;
+ }
+
+ if (fillWidth == null || fillWidth == 0)
+ {
+ fillWidth = 1;
+ }
+
+ if (fillHeight == null || fillHeight == 0)
+ {
+ fillHeight = 1;
+ }
+
+ double widthRatio = size.Width / (double)fillWidth;
+ double heightRatio = size.Height / (double)fillHeight;
+ double scaleRatio = Math.Min(widthRatio, heightRatio);
+
+ // Clamp to current size.
+ if (scaleRatio < 1)
+ {
+ return size;
+ }
+
+ int newWidth = Convert.ToInt32(Math.Ceiling(size.Width / scaleRatio));
+ int newHeight = Convert.ToInt32(Math.Ceiling(size.Height / scaleRatio));
+
+ return new ImageDimensions(newWidth, newHeight);
+ }
+
+ /// <summary>
/// Gets the new width.
/// </summary>
/// <param name="currentHeight">Height of the current.</param>
diff --git a/MediaBrowser.Model/Dto/NameIdPair.cs b/MediaBrowser.Model/Dto/NameIdPair.cs
index 7f18b4502..31516947f 100644
--- a/MediaBrowser.Model/Dto/NameIdPair.cs
+++ b/MediaBrowser.Model/Dto/NameIdPair.cs
@@ -1,8 +1,6 @@
#nullable disable
#pragma warning disable CS1591
-using System;
-
namespace MediaBrowser.Model.Dto
{
public class NameIdPair
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index ade9d7e8d..c67f30d04 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -104,6 +104,19 @@ namespace MediaBrowser.Model.Entities
return "HDR";
}
+ // For some Dolby Vision files, no color transfer is provided, so check the codec
+
+ var codecTag = CodecTag;
+
+ 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))
+ {
+ return "HDR";
+ }
+
return "SDR";
}
}
@@ -163,7 +176,7 @@ namespace MediaBrowser.Model.Entities
foreach (var tag in attributes)
{
// Keep Tags that are not already in Title.
- if (Title.IndexOf(tag, StringComparison.OrdinalIgnoreCase) == -1)
+ if (!Title.Contains(tag, StringComparison.OrdinalIgnoreCase))
{
result.Append(" - ").Append(tag);
}
@@ -202,7 +215,7 @@ namespace MediaBrowser.Model.Entities
foreach (var tag in attributes)
{
// Keep Tags that are not already in Title.
- if (Title.IndexOf(tag, StringComparison.OrdinalIgnoreCase) == -1)
+ if (!Title.Contains(tag, StringComparison.OrdinalIgnoreCase))
{
result.Append(" - ").Append(tag);
}
@@ -522,9 +535,9 @@ namespace MediaBrowser.Model.Entities
// sub = external .sub file
- return codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) == -1 &&
- codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) == -1 &&
- codec.IndexOf("dvbsub", StringComparison.OrdinalIgnoreCase) == -1 &&
+ return !codec.Contains("pgs", StringComparison.OrdinalIgnoreCase) &&
+ !codec.Contains("dvd", StringComparison.OrdinalIgnoreCase) &&
+ !codec.Contains("dvbsub", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(codec, "sub", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(codec, "dvb_subtitle", StringComparison.OrdinalIgnoreCase);
}
diff --git a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs
index 09d14dc6a..ce4b0ec92 100644
--- a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs
+++ b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs
@@ -123,10 +123,7 @@ namespace MediaBrowser.Model.Entities
else
{
// Ensure it exists
- if (instance.ProviderIds == null)
- {
- instance.ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- }
+ instance.ProviderIds ??= new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
instance.ProviderIds[name] = value;
}
diff --git a/MediaBrowser.Model/IO/FileSystemMetadata.cs b/MediaBrowser.Model/IO/FileSystemMetadata.cs
index 118c78e80..fb74886bf 100644
--- a/MediaBrowser.Model/IO/FileSystemMetadata.cs
+++ b/MediaBrowser.Model/IO/FileSystemMetadata.cs
@@ -38,12 +38,6 @@ namespace MediaBrowser.Model.IO
public long Length { get; set; }
/// <summary>
- /// Gets or sets the name of the directory.
- /// </summary>
- /// <value>The name of the directory.</value>
- public string DirectoryName { get; set; }
-
- /// <summary>
/// Gets or sets the last write time UTC.
/// </summary>
/// <value>The last write time UTC.</value>
diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs
index ef08ecec6..be4f1e16b 100644
--- a/MediaBrowser.Model/IO/IFileSystem.cs
+++ b/MediaBrowser.Model/IO/IFileSystem.cs
@@ -1,4 +1,3 @@
-#nullable disable
#pragma warning disable CS1591
using System;
@@ -25,7 +24,7 @@ namespace MediaBrowser.Model.IO
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>System.String.</returns>
- string ResolveShortcut(string filename);
+ string? ResolveShortcut(string filename);
/// <summary>
/// Creates the shortcut.
@@ -118,13 +117,6 @@ namespace MediaBrowser.Model.IO
bool ContainsSubPath(string parentPath, string path);
/// <summary>
- /// Determines whether [is root path] [the specified path].
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns><c>true</c> if [is root path] [the specified path]; otherwise, <c>false</c>.</returns>
- bool IsRootPath(string path);
-
- /// <summary>
/// Normalizes the path.
/// </summary>
/// <param name="path">The path.</param>
@@ -167,7 +159,7 @@ namespace MediaBrowser.Model.IO
/// <returns>All found files.</returns>
IEnumerable<FileSystemMetadata> GetFiles(string path, bool recursive = false);
- IEnumerable<FileSystemMetadata> GetFiles(string path, IReadOnlyList<string> extensions, bool enableCaseSensitiveExtensions, bool recursive);
+ IEnumerable<FileSystemMetadata> GetFiles(string path, IReadOnlyList<string>? extensions, bool enableCaseSensitiveExtensions, bool recursive);
/// <summary>
/// Gets the file system entries.
@@ -193,7 +185,7 @@ namespace MediaBrowser.Model.IO
/// <returns>IEnumerable&lt;System.String&gt;.</returns>
IEnumerable<string> GetFilePaths(string path, bool recursive = false);
- IEnumerable<string> GetFilePaths(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive);
+ IEnumerable<string> GetFilePaths(string path, string[]? extensions, bool enableCaseSensitiveExtensions, bool recursive);
/// <summary>
/// Gets the file system entry paths.
diff --git a/MediaBrowser.Model/IO/IShortcutHandler.cs b/MediaBrowser.Model/IO/IShortcutHandler.cs
index 14d5c4b62..2c364a962 100644
--- a/MediaBrowser.Model/IO/IShortcutHandler.cs
+++ b/MediaBrowser.Model/IO/IShortcutHandler.cs
@@ -15,7 +15,7 @@ namespace MediaBrowser.Model.IO
/// </summary>
/// <param name="shortcutPath">The shortcut path.</param>
/// <returns>System.String.</returns>
- string Resolve(string shortcutPath);
+ string? Resolve(string shortcutPath);
/// <summary>
/// Creates the specified shortcut path.
diff --git a/MediaBrowser.Model/IO/IStreamHelper.cs b/MediaBrowser.Model/IO/IStreamHelper.cs
index 0e09db16e..f900da556 100644
--- a/MediaBrowser.Model/IO/IStreamHelper.cs
+++ b/MediaBrowser.Model/IO/IStreamHelper.cs
@@ -9,7 +9,7 @@ namespace MediaBrowser.Model.IO
{
public interface IStreamHelper
{
- Task CopyToAsync(Stream source, Stream destination, int bufferSize, Action onStarted, CancellationToken cancellationToken);
+ Task CopyToAsync(Stream source, Stream destination, int bufferSize, Action? onStarted, CancellationToken cancellationToken);
Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken);
diff --git a/MediaBrowser.Model/LiveTv/TunerHostInfo.cs b/MediaBrowser.Model/LiveTv/TunerHostInfo.cs
index 7d4bbb2d0..05576a0f8 100644
--- a/MediaBrowser.Model/LiveTv/TunerHostInfo.cs
+++ b/MediaBrowser.Model/LiveTv/TunerHostInfo.cs
@@ -1,9 +1,6 @@
#nullable disable
#pragma warning disable CS1591
-using System;
-using MediaBrowser.Model.Dto;
-
namespace MediaBrowser.Model.LiveTv
{
public class TunerHostInfo
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index f622a042a..4db99f0b0 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -36,7 +36,7 @@
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="System.Globalization" Version="4.3.0" />
- <PackageReference Include="System.Text.Json" Version="5.0.1" />
+ <PackageReference Include="System.Text.Json" Version="5.0.2" />
</ItemGroup>
<ItemGroup>
diff --git a/MediaBrowser.Model/Notifications/NotificationOptions.cs b/MediaBrowser.Model/Notifications/NotificationOptions.cs
index 94bb5d6e3..09beb2ef7 100644
--- a/MediaBrowser.Model/Notifications/NotificationOptions.cs
+++ b/MediaBrowser.Model/Notifications/NotificationOptions.cs
@@ -5,8 +5,6 @@ using System;
using System.Linq;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
-using MediaBrowser.Model.Extensions;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.Model.Notifications
{
@@ -95,16 +93,17 @@ namespace MediaBrowser.Model.Notifications
{
NotificationOption opt = GetOptions(notificationType);
- return opt == null ||
- !opt.DisabledServices.Contains(service, StringComparer.OrdinalIgnoreCase);
+ return opt == null
+ || !opt.DisabledServices.Contains(service, StringComparer.OrdinalIgnoreCase);
}
public bool IsEnabledToMonitorUser(string type, Guid userId)
{
NotificationOption opt = GetOptions(type);
- return opt != null && opt.Enabled &&
- !opt.DisabledMonitorUsers.Contains(userId.ToString(string.Empty), StringComparer.OrdinalIgnoreCase);
+ return opt != null
+ && opt.Enabled
+ && !opt.DisabledMonitorUsers.Contains(userId.ToString("N"), StringComparer.OrdinalIgnoreCase);
}
public bool IsEnabledToSendToUser(string type, string userId, User user)
diff --git a/MediaBrowser.Model/Querying/EpisodeQuery.cs b/MediaBrowser.Model/Querying/EpisodeQuery.cs
deleted file mode 100644
index 56a7f3320..000000000
--- a/MediaBrowser.Model/Querying/EpisodeQuery.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-#nullable disable
-#pragma warning disable CS1591
-
-using System;
-
-namespace MediaBrowser.Model.Querying
-{
- public class EpisodeQuery
- {
- public EpisodeQuery()
- {
- Fields = Array.Empty<ItemFields>();
- }
-
- /// <summary>
- /// Gets or sets the user identifier.
- /// </summary>
- /// <value>The user identifier.</value>
- public string UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the season identifier.
- /// </summary>
- /// <value>The season identifier.</value>
- public string SeasonId { get; set; }
-
- /// <summary>
- /// Gets or sets the series identifier.
- /// </summary>
- /// <value>The series identifier.</value>
- public string SeriesId { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether this instance is missing.
- /// </summary>
- /// <value><c>null</c> if [is missing] contains no value, <c>true</c> if [is missing]; otherwise, <c>false</c>.</value>
- public bool? IsMissing { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether this instance is virtual unaired.
- /// </summary>
- /// <value><c>null</c> if [is virtual unaired] contains no value, <c>true</c> if [is virtual unaired]; otherwise, <c>false</c>.</value>
- public bool? IsVirtualUnaired { get; set; }
-
- /// <summary>
- /// Gets or sets the season number.
- /// </summary>
- /// <value>The season number.</value>
- public int? SeasonNumber { get; set; }
-
- /// <summary>
- /// Gets or sets the fields.
- /// </summary>
- /// <value>The fields.</value>
- public ItemFields[] Fields { get; set; }
-
- /// <summary>
- /// Gets or sets the start index.
- /// </summary>
- /// <value>The start index.</value>
- public int? StartIndex { get; set; }
-
- /// <summary>
- /// Gets or sets the limit.
- /// </summary>
- /// <value>The limit.</value>
- public int? Limit { get; set; }
-
- /// <summary>
- /// Gets or sets the start item identifier.
- /// </summary>
- /// <value>The start item identifier.</value>
- public string StartItemId { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs b/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs
deleted file mode 100644
index b800f5de5..000000000
--- a/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-#nullable disable
-#pragma warning disable CS1591
-
-using System;
-
-namespace MediaBrowser.Model.Querying
-{
- public class MovieRecommendationQuery
- {
- public MovieRecommendationQuery()
- {
- ItemLimit = 10;
- CategoryLimit = 6;
- Fields = Array.Empty<ItemFields>();
- }
-
- /// <summary>
- /// Gets or sets the user identifier.
- /// </summary>
- /// <value>The user identifier.</value>
- public string UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the parent identifier.
- /// </summary>
- /// <value>The parent identifier.</value>
- public string ParentId { get; set; }
-
- /// <summary>
- /// Gets or sets the item limit.
- /// </summary>
- /// <value>The item limit.</value>
- public int ItemLimit { get; set; }
-
- /// <summary>
- /// Gets or sets the category limit.
- /// </summary>
- /// <value>The category limit.</value>
- public int CategoryLimit { get; set; }
-
- /// <summary>
- /// Gets or sets the fields.
- /// </summary>
- /// <value>The fields.</value>
- public ItemFields[] Fields { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
deleted file mode 100644
index 2cf0f0d5f..000000000
--- a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-#nullable disable
-#pragma warning disable CS1591
-
-using System;
-using MediaBrowser.Model.Entities;
-
-namespace MediaBrowser.Model.Querying
-{
- public class UpcomingEpisodesQuery
- {
- public UpcomingEpisodesQuery()
- {
- EnableImageTypes = Array.Empty<ImageType>();
- }
-
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- public string UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the parent identifier.
- /// </summary>
- /// <value>The parent identifier.</value>
- public string ParentId { get; set; }
-
- /// <summary>
- /// Gets or sets the start index. Use for paging.
- /// </summary>
- /// <value>The start index.</value>
- public int? StartIndex { get; set; }
-
- /// <summary>
- /// Gets or sets the maximum number of items to return.
- /// </summary>
- /// <value>The limit.</value>
- public int? Limit { get; set; }
-
- /// <summary>
- /// Gets or sets the fields to return within the items, in addition to basic information.
- /// </summary>
- /// <value>The fields.</value>
- public ItemFields[] Fields { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether [enable images].
- /// </summary>
- /// <value><c>null</c> if [enable images] contains no value, <c>true</c> if [enable images]; otherwise, <c>false</c>.</value>
- public bool? EnableImages { get; set; }
-
- /// <summary>
- /// Gets or sets the image type limit.
- /// </summary>
- /// <value>The image type limit.</value>
- public int? ImageTypeLimit { get; set; }
-
- /// <summary>
- /// Gets or sets the enable image types.
- /// </summary>
- /// <value>The enable image types.</value>
- public ImageType[] EnableImageTypes { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/Session/MessageCommand.cs b/MediaBrowser.Model/Session/MessageCommand.cs
index 09abfbb3f..cc9db8e6c 100644
--- a/MediaBrowser.Model/Session/MessageCommand.cs
+++ b/MediaBrowser.Model/Session/MessageCommand.cs
@@ -1,12 +1,15 @@
#nullable disable
#pragma warning disable CS1591
+using System.ComponentModel.DataAnnotations;
+
namespace MediaBrowser.Model.Session
{
public class MessageCommand
{
public string Header { get; set; }
+ [Required(AllowEmptyStrings = false)]
public string Text { get; set; }
public long? TimeoutMs { get; set; }
diff --git a/MediaBrowser.Model/Sync/SyncCategory.cs b/MediaBrowser.Model/Sync/SyncCategory.cs
deleted file mode 100644
index 1248c2f73..000000000
--- a/MediaBrowser.Model/Sync/SyncCategory.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma warning disable CS1591
-
-namespace MediaBrowser.Model.Sync
-{
- public enum SyncCategory
- {
- /// <summary>
- /// The latest.
- /// </summary>
- Latest = 0,
-
- /// <summary>
- /// The next up.
- /// </summary>
- NextUp = 1,
-
- /// <summary>
- /// The resume.
- /// </summary>
- Resume = 2
- }
-}
diff --git a/MediaBrowser.Model/Sync/SyncJob.cs b/MediaBrowser.Model/Sync/SyncJob.cs
deleted file mode 100644
index 3e396e5d1..000000000
--- a/MediaBrowser.Model/Sync/SyncJob.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-#nullable disable
-#pragma warning disable CS1591
-
-using System;
-
-namespace MediaBrowser.Model.Sync
-{
- public class SyncJob
- {
- public SyncJob()
- {
- RequestedItemIds = Array.Empty<Guid>();
- }
-
- /// <summary>
- /// Gets or sets the identifier.
- /// </summary>
- /// <value>The identifier.</value>
- public string Id { get; set; }
-
- /// <summary>
- /// Gets or sets the device identifier.
- /// </summary>
- /// <value>The device identifier.</value>
- public string TargetId { get; set; }
-
- /// <summary>
- /// Gets or sets the name of the target.
- /// </summary>
- /// <value>The name of the target.</value>
- public string TargetName { get; set; }
-
- /// <summary>
- /// Gets or sets the quality.
- /// </summary>
- /// <value>The quality.</value>
- public string Quality { get; set; }
-
- /// <summary>
- /// Gets or sets the bitrate.
- /// </summary>
- /// <value>The bitrate.</value>
- public int? Bitrate { get; set; }
-
- /// <summary>
- /// Gets or sets the profile.
- /// </summary>
- /// <value>The profile.</value>
- public string Profile { get; set; }
-
- /// <summary>
- /// Gets or sets the category.
- /// </summary>
- /// <value>The category.</value>
- public SyncCategory? Category { get; set; }
-
- /// <summary>
- /// Gets or sets the parent identifier.
- /// </summary>
- /// <value>The parent identifier.</value>
- public string ParentId { get; set; }
-
- /// <summary>
- /// Gets or sets the current progress.
- /// </summary>
- /// <value>The current progress.</value>
- public double? Progress { get; set; }
-
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- public string Name { get; set; }
-
- /// <summary>
- /// Gets or sets the status.
- /// </summary>
- /// <value>The status.</value>
- public SyncJobStatus Status { get; set; }
-
- /// <summary>
- /// Gets or sets the user identifier.
- /// </summary>
- /// <value>The user identifier.</value>
- public string UserId { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether [unwatched only].
- /// </summary>
- /// <value><c>true</c> if [unwatched only]; otherwise, <c>false</c>.</value>
- public bool UnwatchedOnly { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether [synchronize new content].
- /// </summary>
- /// <value><c>true</c> if [synchronize new content]; otherwise, <c>false</c>.</value>
- public bool SyncNewContent { get; set; }
-
- /// <summary>
- /// Gets or sets the item limit.
- /// </summary>
- /// <value>The item limit.</value>
- public int? ItemLimit { get; set; }
-
- /// <summary>
- /// Gets or sets the requested item ids.
- /// </summary>
- /// <value>The requested item ids.</value>
- public Guid[] RequestedItemIds { get; set; }
-
- /// <summary>
- /// Gets or sets the date created.
- /// </summary>
- /// <value>The date created.</value>
- public DateTime DateCreated { get; set; }
-
- /// <summary>
- /// Gets or sets the date last modified.
- /// </summary>
- /// <value>The date last modified.</value>
- public DateTime DateLastModified { get; set; }
-
- /// <summary>
- /// Gets or sets the item count.
- /// </summary>
- /// <value>The item count.</value>
- public int ItemCount { get; set; }
-
- public string ParentName { get; set; }
-
- public string PrimaryImageItemId { get; set; }
-
- public string PrimaryImageTag { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/Sync/SyncJobStatus.cs b/MediaBrowser.Model/Sync/SyncJobStatus.cs
deleted file mode 100644
index 226a47d4c..000000000
--- a/MediaBrowser.Model/Sync/SyncJobStatus.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma warning disable CS1591
-
-namespace MediaBrowser.Model.Sync
-{
- public enum SyncJobStatus
- {
- Queued = 0,
- Converting = 1,
- ReadyToTransfer = 2,
- Transferring = 3,
- Completed = 4,
- CompletedWithError = 5,
- Failed = 6
- }
-}
diff --git a/MediaBrowser.Model/Sync/SyncTarget.cs b/MediaBrowser.Model/Sync/SyncTarget.cs
deleted file mode 100644
index 9e6bbbc00..000000000
--- a/MediaBrowser.Model/Sync/SyncTarget.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-#nullable disable
-#pragma warning disable CS1591
-
-namespace MediaBrowser.Model.Sync
-{
- public class SyncTarget
- {
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- public string Name { get; set; }
-
- /// <summary>
- /// Gets or sets the identifier.
- /// </summary>
- /// <value>The identifier.</value>
- public string Id { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/Tasks/ITaskTrigger.cs b/MediaBrowser.Model/Tasks/ITaskTrigger.cs
index cbd60cca1..db9fba696 100644
--- a/MediaBrowser.Model/Tasks/ITaskTrigger.cs
+++ b/MediaBrowser.Model/Tasks/ITaskTrigger.cs
@@ -11,7 +11,7 @@ namespace MediaBrowser.Model.Tasks
/// <summary>
/// Fires when the trigger condition is satisfied and the task should run.
/// </summary>
- event EventHandler<EventArgs> Triggered;
+ event EventHandler<EventArgs>? Triggered;
/// <summary>
/// Gets or sets the options of this task.
diff --git a/MediaBrowser.Model/Users/UserAction.cs b/MediaBrowser.Model/Users/UserAction.cs
deleted file mode 100644
index 7646db4a8..000000000
--- a/MediaBrowser.Model/Users/UserAction.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-#nullable disable
-#pragma warning disable CS1591
-
-using System;
-
-namespace MediaBrowser.Model.Users
-{
- public class UserAction
- {
- public string Id { get; set; }
-
- public string ServerId { get; set; }
-
- public Guid UserId { get; set; }
-
- public Guid ItemId { get; set; }
-
- public UserActionType Type { get; set; }
-
- public DateTime Date { get; set; }
-
- public long? PositionTicks { get; set; }
- }
-}