Merge remote-tracking branch 'upstream/master' into client-logger

This commit is contained in:
Cody Robibero
2021-10-26 17:43:36 -06:00
1165 changed files with 24439 additions and 15715 deletions

View File

@@ -1,13 +1,26 @@
#nullable disable
#pragma warning disable CS1591
using System;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Model.Activity
{
/// <summary>
/// An activity log entry.
/// </summary>
public class ActivityLogEntry
{
/// <summary>
/// Initializes a new instance of the <see cref="ActivityLogEntry"/> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="type">The type.</param>
/// <param name="userId">The user id.</param>
public ActivityLogEntry(string name, string type, Guid userId)
{
Name = name;
Type = type;
UserId = userId;
}
/// <summary>
/// Gets or sets the identifier.
/// </summary>
@@ -24,13 +37,13 @@ namespace MediaBrowser.Model.Activity
/// Gets or sets the overview.
/// </summary>
/// <value>The overview.</value>
public string Overview { get; set; }
public string? Overview { get; set; }
/// <summary>
/// Gets or sets the short overview.
/// </summary>
/// <value>The short overview.</value>
public string ShortOverview { get; set; }
public string? ShortOverview { get; set; }
/// <summary>
/// Gets or sets the type.
@@ -42,7 +55,7 @@ namespace MediaBrowser.Model.Activity
/// Gets or sets the item identifier.
/// </summary>
/// <value>The item identifier.</value>
public string ItemId { get; set; }
public string? ItemId { get; set; }
/// <summary>
/// Gets or sets the date.
@@ -61,7 +74,7 @@ namespace MediaBrowser.Model.Activity
/// </summary>
/// <value>The user primary image tag.</value>
[Obsolete("UserPrimaryImageTag is not used.")]
public string UserPrimaryImageTag { get; set; }
public string? UserPrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets the log severity.

View File

@@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Branding
@@ -9,12 +8,12 @@ namespace MediaBrowser.Model.Branding
/// Gets or sets the login disclaimer.
/// </summary>
/// <value>The login disclaimer.</value>
public string LoginDisclaimer { get; set; }
public string? LoginDisclaimer { get; set; }
/// <summary>
/// Gets or sets the custom CSS.
/// </summary>
/// <value>The custom CSS.</value>
public string CustomCss { get; set; }
public string? CustomCss { get; set; }
}
}

View File

@@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591
using System;
@@ -7,11 +6,14 @@ namespace MediaBrowser.Model.Channels
{
public class ChannelFeatures
{
public ChannelFeatures()
public ChannelFeatures(string name, Guid id)
{
MediaTypes = Array.Empty<ChannelMediaType>();
ContentTypes = Array.Empty<ChannelMediaContentType>();
DefaultSortFields = Array.Empty<ChannelItemSortField>();
Name = name;
Id = id;
}
/// <summary>
@@ -24,7 +26,7 @@ namespace MediaBrowser.Model.Channels
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
public string Id { get; set; }
public Guid Id { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance can search.

View File

@@ -1,32 +0,0 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Channels
{
public class ChannelInfo
{
/// <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; }
/// <summary>
/// Gets or sets the home page URL.
/// </summary>
/// <value>The home page URL.</value>
public string HomePageUrl { get; set; }
/// <summary>
/// Gets or sets the features.
/// </summary>
/// <value>The features.</value>
public ChannelFeatures Features { get; set; }
}
}

View File

@@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591
using System;
@@ -13,13 +12,13 @@ namespace MediaBrowser.Model.Channels
/// 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; }
public ItemFields[]? Fields { get; set; }
public bool? EnableImages { get; set; }
public int? ImageTypeLimit { get; set; }
public ImageType[] EnableImageTypes { get; set; }
public ImageType[]? EnableImageTypes { get; set; }
/// <summary>
/// Gets or sets the user identifier.

View File

@@ -1,4 +1,3 @@
#nullable disable
using System;
using System.Xml.Serialization;
@@ -35,21 +34,21 @@ namespace MediaBrowser.Model.Configuration
/// Gets or sets the cache path.
/// </summary>
/// <value>The cache path.</value>
public string CachePath { get; set; }
public string? CachePath { get; set; }
/// <summary>
/// Gets or sets the last known version that was ran using the configuration.
/// </summary>
/// <value>The version from previous run.</value>
[XmlIgnore]
public Version PreviousVersion { get; set; }
public Version? PreviousVersion { get; set; }
/// <summary>
/// Gets or sets the stringified PreviousVersion to be stored/loaded,
/// because System.Version itself isn't xml-serializable.
/// </summary>
/// <value>String value of PreviousVersion.</value>
public string PreviousVersionStr
public string? PreviousVersionStr
{
get => PreviousVersion?.ToString();
set

View File

@@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591
using System;
@@ -52,21 +51,21 @@ namespace MediaBrowser.Model.Configuration
/// Gets or sets the preferred metadata language.
/// </summary>
/// <value>The preferred metadata language.</value>
public string PreferredMetadataLanguage { get; set; }
public string? PreferredMetadataLanguage { get; set; }
/// <summary>
/// Gets or sets the metadata country code.
/// </summary>
/// <value>The metadata country code.</value>
public string MetadataCountryCode { get; set; }
public string? MetadataCountryCode { get; set; }
public string SeasonZeroDisplayName { get; set; }
public string[] MetadataSavers { get; set; }
public string[]? MetadataSavers { get; set; }
public string[] DisabledLocalMetadataReaders { get; set; }
public string[] LocalMetadataReaderOrder { get; set; }
public string[]? LocalMetadataReaderOrder { get; set; }
public string[] DisabledSubtitleFetchers { get; set; }
@@ -76,7 +75,7 @@ namespace MediaBrowser.Model.Configuration
public bool SkipSubtitlesIfAudioTrackMatches { get; set; }
public string[] SubtitleDownloadLanguages { get; set; }
public string[]? SubtitleDownloadLanguages { get; set; }
public bool RequirePerfectSubtitleMatch { get; set; }
@@ -84,7 +83,7 @@ namespace MediaBrowser.Model.Configuration
public TypeOptions[] TypeOptions { get; set; }
public TypeOptions GetTypeOptions(string type)
public TypeOptions? GetTypeOptions(string type)
{
foreach (var options in TypeOptions)
{

View File

@@ -1,12 +1,22 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Configuration
{
public class MediaPathInfo
{
public MediaPathInfo(string path)
{
Path = path;
}
// Needed for xml serialization
public MediaPathInfo()
{
Path = string.Empty;
}
public string Path { get; set; }
public string NetworkPath { get; set; }
public string? NetworkPath { get; set; }
}
}

View File

@@ -1,5 +1,5 @@
#nullable disable
#pragma warning disable CS1591
#pragma warning disable CS1591, CA1819
using System;

View File

@@ -1,5 +1,3 @@
#nullable enable
namespace MediaBrowser.Model.Configuration
{
/// <summary>

View File

@@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591
using System;
@@ -33,7 +32,7 @@ namespace MediaBrowser.Model.Configuration
/// Gets or sets the audio language preference.
/// </summary>
/// <value>The audio language preference.</value>
public string AudioLanguagePreference { get; set; }
public string? AudioLanguagePreference { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [play default audio track].
@@ -45,7 +44,7 @@ namespace MediaBrowser.Model.Configuration
/// Gets or sets the subtitle language preference.
/// </summary>
/// <value>The subtitle language preference.</value>
public string SubtitleLanguagePreference { get; set; }
public string? SubtitleLanguagePreference { get; set; }
public bool DisplayMissingEpisodes { get; set; }

View File

@@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Configuration
@@ -13,7 +12,7 @@ namespace MediaBrowser.Model.Configuration
EnablePathSubstitution = true;
}
public string UserId { get; set; }
public string? UserId { get; set; }
public string ReleaseDateFormat { get; set; }

View File

@@ -15,6 +15,11 @@ namespace MediaBrowser.Model.Devices
public string Name { get; set; }
/// <summary>
/// Gets or sets the access token.
/// </summary>
public string AccessToken { get; set; }
/// <summary>
/// Gets or sets the identifier.
/// </summary>

View File

@@ -1,9 +0,0 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Devices
{
public class DeviceOptions
{
public string? CustomName { get; set; }
}
}

View File

@@ -1,21 +0,0 @@
#pragma warning disable CS1591
using System;
namespace MediaBrowser.Model.Devices
{
public class DeviceQuery
{
/// <summary>
/// Gets or sets a value indicating whether [supports synchronize].
/// </summary>
/// <value><c>null</c> if [supports synchronize] contains no value, <c>true</c> if [supports synchronize]; otherwise, <c>false</c>.</value>
public bool? SupportsSync { get; set; }
/// <summary>
/// Gets or sets the user identifier.
/// </summary>
/// <value>The user identifier.</value>
public Guid UserId { get; set; }
}
}

View File

@@ -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 Container { get; set; } = string.Empty;
public string[] GetContainers()
{
return SplitValue(Container);
}
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);
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 false;
}
return !isNegativeList;
}
return true;
}
else
{
var allInputContainers = SplitValue(inputContainer);
foreach (var container in allInputContainers)
{
if (profileContainers.Contains(container, StringComparer.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
return isNegativeList;
}
}
}

View File

@@ -208,7 +208,6 @@ namespace MediaBrowser.Model.Dlna
if (string.IsNullOrEmpty(orgPn))
{
contentFeatureList.Add(orgOp.TrimStart(';') + orgCi + dlnaflags);
continue;
}
else
{

View File

@@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@@ -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,

View File

@@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591
using System.Xml.Serialization;
@@ -8,13 +7,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; }

View File

@@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna

View File

@@ -1,4 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable CS1591, CA1707
namespace MediaBrowser.Model.Dlna
{

View File

@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Model.Dlna

View File

@@ -5,7 +5,7 @@ using System;
namespace MediaBrowser.Model.Dlna
{
public class ResolutionNormalizer
public static class ResolutionNormalizer
{
private static readonly ResolutionConfiguration[] Configurations =
new[]
@@ -21,11 +21,7 @@ namespace MediaBrowser.Model.Dlna
public static ResolutionOptions Normalize(
int? inputBitrate,
int? unused1,
int? unused2,
int outputBitrate,
string inputCodec,
string outputCodec,
int? maxWidth,
int? maxHeight)
{

View File

@@ -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;
@@ -694,7 +694,7 @@ namespace MediaBrowser.Model.Dlna
if (isEligibleForDirectPlay || isEligibleForDirectStream)
{
// See if it can be direct played
var directPlayInfo = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
var directPlayInfo = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectStream);
var directPlay = directPlayInfo.Item1;
if (directPlay != null)
@@ -810,7 +810,7 @@ namespace MediaBrowser.Model.Dlna
// Honor requested max channels
playlistItem.GlobalMaxAudioChannels = options.MaxAudioChannels;
int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(false) ?? 0, playlistItem.TargetAudioCodec, audioStream, playlistItem);
int audioBitrate = GetAudioBitrate(options.GetMaxBitrate(false) ?? 0, playlistItem.TargetAudioCodec, audioStream, playlistItem);
playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate);
isFirstAppliedCodecProfile = true;
@@ -907,7 +907,7 @@ namespace MediaBrowser.Model.Dlna
return 192000;
}
private static int GetAudioBitrate(string subProtocol, long maxTotalBitrate, string[] targetAudioCodecs, MediaStream audioStream, StreamInfo item)
private static int GetAudioBitrate(long maxTotalBitrate, string[] targetAudioCodecs, MediaStream audioStream, StreamInfo item)
{
string targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
@@ -1005,7 +1005,6 @@ namespace MediaBrowser.Model.Dlna
MediaSourceInfo mediaSource,
MediaStream videoStream,
MediaStream audioStream,
bool isEligibleForDirectPlay,
bool isEligibleForDirectStream)
{
if (options.ForceDirectPlay)
@@ -1146,7 +1145,7 @@ namespace MediaBrowser.Model.Dlna
{
string audioCodec = audioStream.Codec;
conditions = new List<ProfileCondition>();
bool? isSecondaryAudio = audioStream == null ? null : mediaSource.IsSecondaryAudio(audioStream);
bool? isSecondaryAudio = mediaSource.IsSecondaryAudio(audioStream);
foreach (var i in profile.CodecProfiles)
{
@@ -1230,7 +1229,7 @@ namespace MediaBrowser.Model.Dlna
bool result = IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod);
return (result, result ? (TranscodeReason?)null : TranscodeReason.ContainerBitrateExceedsLimit);
return (result, result ? null : TranscodeReason.ContainerBitrateExceedsLimit);
}
public static SubtitleProfile GetSubtitleProfile(
@@ -1262,7 +1261,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(subtitleStream, profile, transcodingSubProtocol, outputContainer))
if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(outputContainer))
{
continue;
}
@@ -1291,7 +1290,7 @@ namespace MediaBrowser.Model.Dlna
continue;
}
if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(subtitleStream, profile, transcodingSubProtocol, outputContainer))
if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(outputContainer))
{
continue;
}
@@ -1313,7 +1312,7 @@ namespace MediaBrowser.Model.Dlna
};
}
private static bool IsSubtitleEmbedSupported(MediaStream subtitleStream, SubtitleProfile subtitleProfile, string transcodingSubProtocol, string transcodingContainer)
private static bool IsSubtitleEmbedSupported(string transcodingContainer)
{
if (!string.IsNullOrEmpty(transcodingContainer))
{
@@ -1728,18 +1727,14 @@ namespace MediaBrowser.Model.Dlna
continue;
}
if (!string.IsNullOrEmpty(value))
// change from split by | to comma
// strip spaces to avoid having to encode
var values = value
.Split('|', StringSplitOptions.RemoveEmptyEntries);
if (condition.Condition == ProfileConditionType.Equals || condition.Condition == ProfileConditionType.EqualsAny)
{
// change from split by | to comma
// strip spaces to avoid having to encode
var values = value
.Split('|', StringSplitOptions.RemoveEmptyEntries);
if (condition.Condition == ProfileConditionType.Equals || condition.Condition == ProfileConditionType.EqualsAny)
{
item.SetOption(qualifier, "profile", string.Join(',', values));
}
item.SetOption(qualifier, "profile", string.Join(',', values));
}
break;

View File

@@ -133,7 +133,7 @@ namespace MediaBrowser.Model.Dlna
var stream = TargetAudioStream;
return AudioSampleRate.HasValue && !IsDirectStream
? AudioSampleRate
: stream == null ? null : stream.SampleRate;
: stream?.SampleRate;
}
}
@@ -146,7 +146,7 @@ namespace MediaBrowser.Model.Dlna
{
if (IsDirectStream)
{
return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth;
return TargetAudioStream?.BitDepth;
}
var targetAudioCodecs = TargetAudioCodec;
@@ -156,7 +156,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetAudioBitDepth(audioCodec);
}
return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth;
return TargetAudioStream?.BitDepth;
}
}
@@ -169,7 +169,7 @@ namespace MediaBrowser.Model.Dlna
{
if (IsDirectStream)
{
return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth;
return TargetVideoStream?.BitDepth;
}
var targetVideoCodecs = TargetVideoCodec;
@@ -179,7 +179,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetVideoBitDepth(videoCodec);
}
return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth;
return TargetVideoStream?.BitDepth;
}
}
@@ -193,7 +193,7 @@ namespace MediaBrowser.Model.Dlna
{
if (IsDirectStream)
{
return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
return TargetVideoStream?.RefFrames;
}
var targetVideoCodecs = TargetVideoCodec;
@@ -203,7 +203,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetRefFrames(videoCodec);
}
return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
return TargetVideoStream?.RefFrames;
}
}
@@ -230,7 +230,7 @@ namespace MediaBrowser.Model.Dlna
{
if (IsDirectStream)
{
return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
return TargetVideoStream?.Level;
}
var targetVideoCodecs = TargetVideoCodec;
@@ -240,7 +240,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetVideoLevel(videoCodec);
}
return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
return TargetVideoStream?.Level;
}
}
@@ -254,7 +254,7 @@ namespace MediaBrowser.Model.Dlna
var stream = TargetVideoStream;
return !IsDirectStream
? null
: stream == null ? null : stream.PacketLength;
: stream?.PacketLength;
}
}
@@ -267,7 +267,7 @@ namespace MediaBrowser.Model.Dlna
{
if (IsDirectStream)
{
return TargetVideoStream == null ? null : TargetVideoStream.Profile;
return TargetVideoStream?.Profile;
}
var targetVideoCodecs = TargetVideoCodec;
@@ -277,7 +277,7 @@ namespace MediaBrowser.Model.Dlna
return GetOption(videoCodec, "profile");
}
return TargetVideoStream == null ? null : TargetVideoStream.Profile;
return TargetVideoStream?.Profile;
}
}
@@ -292,7 +292,7 @@ namespace MediaBrowser.Model.Dlna
var stream = TargetVideoStream;
return !IsDirectStream
? null
: stream == null ? null : stream.CodecTag;
: stream?.CodecTag;
}
}
@@ -306,7 +306,7 @@ namespace MediaBrowser.Model.Dlna
var stream = TargetAudioStream;
return AudioBitrate.HasValue && !IsDirectStream
? AudioBitrate
: stream == null ? null : stream.BitRate;
: stream?.BitRate;
}
}
@@ -319,7 +319,7 @@ namespace MediaBrowser.Model.Dlna
{
if (IsDirectStream)
{
return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels;
return TargetAudioStream?.Channels;
}
var targetAudioCodecs = TargetAudioCodec;
@@ -329,7 +329,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetRefFrames(codec);
}
return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels;
return TargetAudioStream?.Channels;
}
}
@@ -425,7 +425,7 @@ namespace MediaBrowser.Model.Dlna
return VideoBitrate.HasValue && !IsDirectStream
? VideoBitrate
: stream == null ? null : stream.BitRate;
: stream?.BitRate;
}
}
@@ -451,7 +451,7 @@ namespace MediaBrowser.Model.Dlna
{
if (IsDirectStream)
{
return TargetVideoStream == null ? null : TargetVideoStream.IsAnamorphic;
return TargetVideoStream?.IsAnamorphic;
}
return false;
@@ -464,7 +464,7 @@ namespace MediaBrowser.Model.Dlna
{
if (IsDirectStream)
{
return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced;
return TargetVideoStream?.IsInterlaced;
}
var targetVideoCodecs = TargetVideoCodec;
@@ -477,7 +477,7 @@ namespace MediaBrowser.Model.Dlna
}
}
return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced;
return TargetVideoStream?.IsInterlaced;
}
}
@@ -487,7 +487,7 @@ namespace MediaBrowser.Model.Dlna
{
if (IsDirectStream)
{
return TargetVideoStream == null ? null : TargetVideoStream.IsAVC;
return TargetVideoStream?.IsAVC;
}
return true;
@@ -618,30 +618,30 @@ namespace MediaBrowser.Model.Dlna
}
// Try to keep the url clean by omitting defaults
if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase) &&
string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase))
if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase)
&& string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase) &&
string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase))
if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase)
&& string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase) &&
string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase))
if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase)
&& string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase))
{
continue;
}
var encodedValue = pair.Value.Replace(" ", "%20");
var encodedValue = pair.Value.Replace(" ", "%20", StringComparison.Ordinal);
list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue));
}
string queryString = string.Join("&", list.ToArray());
string queryString = string.Join('&', list);
return GetUrl(baseUrl, queryString);
}
@@ -681,11 +681,11 @@ namespace MediaBrowser.Model.Dlna
string audioCodecs = item.AudioCodecs.Length == 0 ?
string.Empty :
string.Join(",", item.AudioCodecs);
string.Join(',', item.AudioCodecs);
string videoCodecs = item.VideoCodecs.Length == 0 ?
string.Empty :
string.Join(",", item.VideoCodecs);
string.Join(',', item.VideoCodecs);
list.Add(new NameValuePair("DeviceProfileId", item.DeviceProfileId ?? string.Empty));
list.Add(new NameValuePair("DeviceId", item.DeviceId ?? string.Empty));
@@ -1024,30 +1024,5 @@ namespace MediaBrowser.Model.Dlna
return count;
}
public List<MediaStream> GetSelectableAudioStreams()
{
return GetSelectableStreams(MediaStreamType.Audio);
}
public List<MediaStream> GetSelectableSubtitleStreams()
{
return GetSelectableStreams(MediaStreamType.Subtitle);
}
public List<MediaStream> GetSelectableStreams(MediaStreamType type)
{
var list = new List<MediaStream>();
foreach (var stream in MediaSource.MediaStreams)
{
if (type == stream.Type)
{
list.Add(stream);
}
}
return list;
}
}
}

View File

@@ -2,25 +2,28 @@
namespace MediaBrowser.Model.Dlna
{
/// <summary>
/// Delivery method to use during playback of a specific subtitle format.
/// </summary>
public enum SubtitleDeliveryMethod
{
/// <summary>
/// The encode.
/// Burn the subtitles in the video track.
/// </summary>
Encode = 0,
/// <summary>
/// The embed.
/// Embed the subtitles in the file or stream.
/// </summary>
Embed = 1,
/// <summary>
/// The external.
/// Serve the subtitles as an external file.
/// </summary>
External = 2,
/// <summary>
/// The HLS.
/// Serve the subtitles as a separate HLS stream.
/// </summary>
Hls = 3
}

View File

@@ -1,6 +1,6 @@
#nullable disable
#pragma warning disable CS1591
using System.ComponentModel;
using System.Xml.Serialization;
namespace MediaBrowser.Model.Dlna
@@ -8,47 +8,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; }

View File

@@ -1,29 +0,0 @@
#nullable disable
// THIS IS A HACK
// TODO: @bond Move to separate project
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace MediaBrowser.Model.Entities
{
/// <summary>
/// Converts an object to a lowercase string.
/// </summary>
/// <typeparam name="T">The object type.</typeparam>
public class JsonLowerCaseConverter<T> : JsonConverter<T>
{
/// <inheritdoc />
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<T>(ref reader, options);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
writer.WriteStringValue(value?.ToString().ToLowerInvariant());
}
}
}

View File

@@ -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);
}
@@ -242,13 +255,18 @@ namespace MediaBrowser.Model.Entities
attributes.Add(string.IsNullOrEmpty(LocalizedForced) ? "Forced" : LocalizedForced);
}
if (!string.IsNullOrEmpty(Codec))
{
attributes.Add(Codec.ToUpperInvariant());
}
if (!string.IsNullOrEmpty(Title))
{
var result = new StringBuilder(Title);
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);
}
@@ -456,64 +474,30 @@ namespace MediaBrowser.Model.Entities
/// <value><c>true</c> if this instance is anamorphic; otherwise, <c>false</c>.</value>
public bool? IsAnamorphic { get; set; }
private string GetResolutionText()
internal string GetResolutionText()
{
var i = this;
if (i.Width.HasValue && i.Height.HasValue)
if (!Width.HasValue || !Height.HasValue)
{
var width = i.Width.Value;
var height = i.Height.Value;
if (width >= 3800 || height >= 2000)
{
return "4K";
}
if (width >= 2500)
{
if (i.IsInterlaced)
{
return "1440i";
}
return "1440p";
}
if (width >= 1900 || height >= 1000)
{
if (i.IsInterlaced)
{
return "1080i";
}
return "1080p";
}
if (width >= 1260 || height >= 700)
{
if (i.IsInterlaced)
{
return "720i";
}
return "720p";
}
if (width >= 700 || height >= 440)
{
if (i.IsInterlaced)
{
return "480i";
}
return "480p";
}
return "SD";
return null;
}
return null;
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)
<= 960 when Height <= 544 => IsInterlaced ? "540i" : "540p",
// 1280x720
<= 1280 when Height <= 962 => IsInterlaced ? "720i" : "720p",
// 1920x1080
<= 1920 when Height <= 1440 => IsInterlaced ? "1080i" : "1080p",
// 4K
<= 4096 when Height <= 3072 => "4K",
// 8K
<= 8192 when Height <= 6144 => "8K",
_ => null
};
}
public static bool IsTextFormat(string format)
@@ -522,9 +506,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);
}

View File

@@ -1,48 +1,68 @@
namespace MediaBrowser.Model.Entities
{
/// <summary>
/// Struct PersonType.
/// Types of persons.
/// </summary>
public class PersonType
public static class PersonType
{
/// <summary>
/// The actor.
/// A person whose profession is acting on the stage, in films, or on television.
/// </summary>
public const string Actor = "Actor";
/// <summary>
/// The director.
/// A person who supervises the actors and other staff in a film, play, or similar production.
/// </summary>
public const string Director = "Director";
/// <summary>
/// The composer.
/// A person who writes music, especially as a professional occupation.
/// </summary>
public const string Composer = "Composer";
/// <summary>
/// The writer.
/// A writer of a book, article, or document. Can also be used as a generic term for music writer if there is a lack of specificity.
/// </summary>
public const string Writer = "Writer";
/// <summary>
/// The guest star.
/// A well-known actor or other performer who appears in a work in which they do not have a regular role.
/// </summary>
public const string GuestStar = "GuestStar";
/// <summary>
/// The producer.
/// A person responsible for the financial and managerial aspects of the making of a film or broadcast or for staging a play, opera, etc.
/// </summary>
public const string Producer = "Producer";
/// <summary>
/// The conductor.
/// A person who directs the performance of an orchestra or choir.
/// </summary>
public const string Conductor = "Conductor";
/// <summary>
/// The lyricist.
/// A person who writes the words to a song or musical.
/// </summary>
public const string Lyricist = "Lyricist";
/// <summary>
/// A person who adapts a musical composition for performance.
/// </summary>
public const string Arranger = "Arranger";
/// <summary>
/// An audio engineer who performed a general engineering role.
/// </summary>
public const string Engineer = "Engineer";
/// <summary>
/// An engineer responsible for using a mixing console to mix a recorded track into a single piece of music suitable for release.
/// </summary>
public const string Mixer = "Mixer";
/// <summary>
/// A person who remixed a recording by taking one or more other tracks, substantially altering them and mixing them together with other material.
/// </summary>
public const string Remixer = "Remixer";
}
}

View File

@@ -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;
}

View File

@@ -3,6 +3,7 @@
using System;
using System.Text.Json.Serialization;
using Jellyfin.Extensions.Json.Converters;
using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Model.Entities

View File

@@ -18,6 +18,12 @@ namespace MediaBrowser.Model.Extensions
/// <returns>The ordered remote image infos.</returns>
public static IEnumerable<RemoteImageInfo> OrderByLanguageDescending(this IEnumerable<RemoteImageInfo> remoteImageInfos, string requestedLanguage)
{
if (string.IsNullOrWhiteSpace(requestedLanguage))
{
// Default to English if no requested language is specified.
requestedLanguage = "en";
}
var isRequestedLanguageEn = string.Equals(requestedLanguage, "en", StringComparison.OrdinalIgnoreCase);
return remoteImageInfos.OrderByDescending(i =>
@@ -27,16 +33,18 @@ namespace MediaBrowser.Model.Extensions
return 3;
}
if (!isRequestedLanguageEn && string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
{
return 2;
}
if (string.IsNullOrEmpty(i.Language))
{
// Assume empty image language is likely to be English.
return isRequestedLanguageEn ? 3 : 2;
}
if (!isRequestedLanguageEn && string.Equals(i.Language, "en", StringComparison.OrdinalIgnoreCase))
{
// Prioritize English over non-requested languages.
return 2;
}
return 0;
})
.ThenByDescending(i => i.CommunityRating ?? 0)

View File

@@ -17,7 +17,8 @@ namespace MediaBrowser.Model.Extensions
return str;
}
if (char.IsUpper(str[0]))
// We check IsLower instead of IsUpper because both return false for non-letters
if (!char.IsLower(str[0]))
{
return str;
}

View File

@@ -1,6 +1,4 @@
#nullable disable
using System.Collections.Generic;
using System.Globalization;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Globalization
@@ -57,18 +55,10 @@ namespace MediaBrowser.Model.Globalization
IEnumerable<LocalizationOption> GetLocalizationOptions();
/// <summary>
/// Checks if the string contains a character with the specified unicode category.
/// </summary>
/// <param name="value">The string.</param>
/// <param name="category">The unicode category.</param>
/// <returns>Wether or not the string contains a character with the specified unicode category.</returns>
bool HasUnicodeCategory(string value, UnicodeCategory category);
/// <summary>
/// Returns the correct <see cref="CultureInfo" /> for the given language.
/// Returns the correct <see cref="CultureDto" /> for the given language.
/// </summary>
/// <param name="language">The language.</param>
/// <returns>The correct <see cref="CultureInfo" /> for the given language.</returns>
CultureDto FindLanguageInfo(string language);
/// <returns>The correct <see cref="CultureDto" /> for the given language.</returns>
CultureDto? FindLanguageInfo(string language);
}
}

View File

@@ -0,0 +1,45 @@
using System.IO;
namespace MediaBrowser.Model.IO
{
/// <summary>
/// Helper class to create async <see cref="FileStream" />s.
/// </summary>
public static class AsyncFile
{
/// <summary>
/// Gets the default <see cref="FileStreamOptions"/> for reading files async.
/// </summary>
public static FileStreamOptions ReadOptions => new FileStreamOptions()
{
Options = FileOptions.Asynchronous
};
/// <summary>
/// Gets the default <see cref="FileStreamOptions"/> for writing files async.
/// </summary>
public static FileStreamOptions WriteOptions => new FileStreamOptions()
{
Mode = FileMode.OpenOrCreate,
Access = FileAccess.Write,
Share = FileShare.None,
Options = FileOptions.Asynchronous
};
/// <summary>
/// Opens an existing file for reading.
/// </summary>
/// <param name="path">The file to be opened for reading.</param>
/// <returns>A read-only <see cref="FileStream" /> on the specified path.</returns>
public static FileStream OpenRead(string path)
=> new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
/// <summary>
/// Opens an existing file for writing.
/// </summary>
/// <param name="path">The file to be opened for writing.</param>
/// <returns>An unshared <see cref="FileStream" /> object on the specified path with Write access.</returns>
public static FileStream OpenWrite(string path)
=> new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
}
}

View File

@@ -37,12 +37,6 @@ namespace MediaBrowser.Model.IO
/// <value>The length.</value>
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>

View File

@@ -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.
@@ -52,7 +51,7 @@ namespace MediaBrowser.Model.IO
/// <returns>A <see cref="FileSystemMetadata" /> object.</returns>
/// <remarks><para>If the specified path points to a directory, the returned <see cref="FileSystemMetadata" /> object's
/// <see cref="FileSystemMetadata.IsDirectory" /> property and the <see cref="FileSystemMetadata.Exists" /> property will both be set to false.</para>
/// <para>For automatic handling of files <b>and</b> directories, use <see cref="M:IFileSystem.GetFileSystemInfo(System.String)" />.</para></remarks>
/// <para>For automatic handling of files <b>and</b> directories, use <see cref="GetFileSystemInfo(string)" />.</para></remarks>
FileSystemMetadata GetFileInfo(string path);
/// <summary>
@@ -62,7 +61,7 @@ namespace MediaBrowser.Model.IO
/// <returns>A <see cref="FileSystemMetadata" /> object.</returns>
/// <remarks><para>If the specified path points to a file, the returned <see cref="FileSystemMetadata" /> object's
/// <see cref="FileSystemMetadata.IsDirectory" /> property will be set to true and the <see cref="FileSystemMetadata.Exists" /> property will be set to false.</para>
/// <para>For automatic handling of files <b>and</b> directories, use <see cref="M:IFileSystem.GetFileSystemInfo(System.String)" />.</para></remarks>
/// <para>For automatic handling of files <b>and</b> directories, use <see cref="GetFileSystemInfo(string)" />.</para></remarks>
FileSystemMetadata GetDirectoryInfo(string path);
/// <summary>
@@ -160,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.
@@ -186,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.

View File

@@ -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.

View File

@@ -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);

View File

@@ -14,13 +14,9 @@
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
<!-- <AnalysisMode>AllEnabledByDefault</AnalysisMode> -->
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
@@ -34,9 +30,9 @@
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0-rc.2*" />
<PackageReference Include="System.Globalization" Version="4.3.0" />
<PackageReference Include="System.Text.Json" Version="5.0.2" />
<PackageReference Include="System.Text.Json" Version="6.0.0-rc.2*" />
</ItemGroup>
<ItemGroup>
@@ -50,7 +46,8 @@
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Jellyfin.Data\Jellyfin.Data.csproj" />
<ProjectReference Include="../Jellyfin.Data/Jellyfin.Data.csproj" />
<ProjectReference Include="../src/Jellyfin.Extensions/Jellyfin.Extensions.csproj" />
</ItemGroup>
</Project>

View File

@@ -51,6 +51,8 @@ namespace MediaBrowser.Model.MediaInfo
public string ShowName { get; set; }
public string ForcedSortName { get; set; }
public int? IndexNumber { get; set; }
public int? ParentIndexNumber { get; set; }

View File

@@ -1,4 +1,3 @@
#nullable enable
#pragma warning disable CS1591
using System;

View File

@@ -2,8 +2,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using Jellyfin.Extensions;
namespace MediaBrowser.Model.Net
{
@@ -163,15 +165,16 @@ namespace MediaBrowser.Model.Net
return dict;
}
public static string? GetMimeType(string path) => GetMimeType(path, true);
public static string GetMimeType(string path) => GetMimeType(path, "application/octet-stream");
/// <summary>
/// Gets the type of the MIME.
/// </summary>
/// <param name="filename">The filename to find the MIME type of.</param>
/// <param name="enableStreamDefault">Whether of not to return a default value if no fitting MIME type is found.</param>
/// <returns>The worrect MIME type for the given filename, or `null` if it wasn't found and <paramref name="enableStreamDefault"/> is false.</returns>
public static string? GetMimeType(string filename, bool enableStreamDefault)
/// <param name="defaultValue">The default value to return if no fitting MIME type is found.</param>
/// <returns>The correct MIME type for the given filename, or <paramref name="defaultValue"/> if it wasn't found.</returns>
[return: NotNullIfNotNullAttribute("defaultValue")]
public static string? GetMimeType(string filename, string? defaultValue = null)
{
if (filename.Length == 0)
{
@@ -210,7 +213,7 @@ namespace MediaBrowser.Model.Net
return "application/octet-stream";
}
return enableStreamDefault ? "application/octet-stream" : null;
return defaultValue;
}
public static string? ToExtension(string mimeType)
@@ -221,7 +224,7 @@ namespace MediaBrowser.Model.Net
}
// handle text/html; charset=UTF-8
mimeType = mimeType.Split(';')[0];
mimeType = mimeType.AsSpan().LeftPart(';').ToString();
if (_extensionLookup.TryGetValue(mimeType, out string? result))
{

View File

@@ -1,5 +1,3 @@
#nullable enable
using System;
namespace MediaBrowser.Model.Plugins

View File

@@ -1,5 +1,3 @@
#nullable enable
namespace MediaBrowser.Model.Plugins
{
/// <summary>

View File

@@ -1,5 +1,6 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@@ -14,6 +15,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: InternalsVisibleTo("Jellyfin.Model.Tests")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -13,6 +13,7 @@ namespace MediaBrowser.Model.Querying
EnableImageTypes = Array.Empty<ImageType>();
EnableTotalRecordCount = true;
DisableFirstEpisode = false;
NextUpDateCutoff = DateTime.MinValue;
}
/// <summary>
@@ -75,5 +76,10 @@ namespace MediaBrowser.Model.Querying
/// Gets or sets a value indicating whether do disable sending first episode as next up.
/// </summary>
public bool DisableFirstEpisode { get; set; }
/// <summary>
/// Gets or sets a value indicating the oldest date for a show to appear in Next Up.
/// </summary>
public DateTime NextUpDateCutoff { get; set; }
}
}

View File

@@ -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; }
}
}

View File

@@ -3,38 +3,76 @@ using System;
namespace MediaBrowser.Model.QuickConnect
{
/// <summary>
/// Stores the result of an incoming quick connect request.
/// Stores the state of an quick connect request.
/// </summary>
public class QuickConnectResult
{
/// <summary>
/// Gets a value indicating whether this request is authorized.
/// Initializes a new instance of the <see cref="QuickConnectResult"/> class.
/// </summary>
public bool Authenticated => !string.IsNullOrEmpty(Authentication);
/// <param name="secret">The secret used to query the request state.</param>
/// <param name="code">The code used to allow the request.</param>
/// <param name="dateAdded">The time when the request was created.</param>
/// <param name="deviceId">The requesting device id.</param>
/// <param name="deviceName">The requesting device name.</param>
/// <param name="appName">The requesting app name.</param>
/// <param name="appVersion">The requesting app version.</param>
public QuickConnectResult(
string secret,
string code,
DateTime dateAdded,
string deviceId,
string deviceName,
string appName,
string appVersion)
{
Secret = secret;
Code = code;
DateAdded = dateAdded;
DeviceId = deviceId;
DeviceName = deviceName;
AppName = appName;
AppVersion = appVersion;
}
/// <summary>
/// Gets or sets the secret value used to uniquely identify this request. Can be used to retrieve authentication information.
/// Gets or sets a value indicating whether this request is authorized.
/// </summary>
public string? Secret { get; set; }
public bool Authenticated { get; set; }
/// <summary>
/// Gets or sets the user facing code used so the user can quickly differentiate this request from others.
/// Gets the secret value used to uniquely identify this request. Can be used to retrieve authentication information.
/// </summary>
public string? Code { get; set; }
public string Secret { get; }
/// <summary>
/// Gets or sets the private access token.
/// Gets the user facing code used so the user can quickly differentiate this request from others.
/// </summary>
public string? Authentication { get; set; }
public string Code { get; }
/// <summary>
/// Gets or sets an error message.
/// Gets the requesting device id.
/// </summary>
public string? Error { get; set; }
public string DeviceId { get; }
/// <summary>
/// Gets the requesting device name.
/// </summary>
public string DeviceName { get; }
/// <summary>
/// Gets the requesting app name.
/// </summary>
public string AppName { get; }
/// <summary>
/// Gets the requesting app version.
/// </summary>
public string AppVersion { get; }
/// <summary>
/// Gets or sets the DateTime that this request was created.
/// </summary>
public DateTime? DateAdded { get; set; }
public DateTime DateAdded { get; set; }
}
}

View File

@@ -1,23 +0,0 @@
namespace MediaBrowser.Model.QuickConnect
{
/// <summary>
/// Quick connect state.
/// </summary>
public enum QuickConnectState
{
/// <summary>
/// This feature has not been opted into and is unavailable until the server administrator chooses to opt-in.
/// </summary>
Unavailable = 0,
/// <summary>
/// The feature is enabled for use on the server but is not currently accepting connection requests.
/// </summary>
Available = 1,
/// <summary>
/// The feature is actively accepting connection requests.
/// </summary>
Active = 2
}
}

View File

@@ -0,0 +1,48 @@
namespace MediaBrowser.Model.Session
{
/// <summary>
/// Enum HardwareEncodingType.
/// </summary>
public enum HardwareEncodingType
{
/// <summary>
/// AMD AMF
/// </summary>
AMF = 0,
/// <summary>
/// Intel Quick Sync Video
/// </summary>
QSV = 1,
/// <summary>
/// NVIDIA NVENC
/// </summary>
NVENC = 2,
/// <summary>
/// OpenMax OMX
/// </summary>
OMX = 3,
/// <summary>
/// Exynos V4L2 MFC
/// </summary>
V4L2M2M = 4,
/// <summary>
/// MediaCodec Android
/// </summary>
MediaCodec = 5,
/// <summary>
/// Video Acceleration API (VAAPI)
/// </summary>
VAAPI = 6,
/// <summary>
/// Video ToolBox
/// </summary>
VideoToolBox = 7
}
}

View File

@@ -34,6 +34,8 @@ namespace MediaBrowser.Model.Session
public int? AudioChannels { get; set; }
public HardwareEncodingType? HardwareAccelerationType { get; set; }
public TranscodeReason[] TranscodeReasons { get; set; }
}
}

View File

@@ -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
}
}

View File

@@ -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; }
}
}

View File

@@ -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
}
}

View File

@@ -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; }
}
}

View File

@@ -16,15 +16,17 @@ namespace MediaBrowser.Model.SyncPlay
/// <param name="playlist">The playlist.</param>
/// <param name="playingItemIndex">The playing item index in the playlist.</param>
/// <param name="startPositionTicks">The start position ticks.</param>
/// <param name="isPlaying">The playing item status.</param>
/// <param name="shuffleMode">The shuffle mode.</param>
/// <param name="repeatMode">The repeat mode.</param>
public PlayQueueUpdate(PlayQueueUpdateReason reason, DateTime lastUpdate, IReadOnlyList<QueueItem> playlist, int playingItemIndex, long startPositionTicks, GroupShuffleMode shuffleMode, GroupRepeatMode repeatMode)
public PlayQueueUpdate(PlayQueueUpdateReason reason, DateTime lastUpdate, IReadOnlyList<QueueItem> playlist, int playingItemIndex, long startPositionTicks, bool isPlaying, GroupShuffleMode shuffleMode, GroupRepeatMode repeatMode)
{
Reason = reason;
LastUpdate = lastUpdate;
Playlist = playlist;
PlayingItemIndex = playingItemIndex;
StartPositionTicks = startPositionTicks;
IsPlaying = isPlaying;
ShuffleMode = shuffleMode;
RepeatMode = repeatMode;
}
@@ -59,6 +61,12 @@ namespace MediaBrowser.Model.SyncPlay
/// <value>The start position ticks.</value>
public long StartPositionTicks { get; }
/// <summary>
/// Gets a value indicating whether the current item is playing.
/// </summary>
/// <value>The playing item status.</value>
public bool IsPlaying { get; }
/// <summary>
/// Gets the shuffle mode.
/// </summary>

View File

@@ -130,8 +130,10 @@ namespace MediaBrowser.Model.System
/// Gets or sets a value indicating whether this instance has update available.
/// </summary>
/// <value><c>true</c> if this instance has update available; otherwise, <c>false</c>.</value>
[Obsolete("This should be handled by the package manager")]
public bool HasUpdateAvailable { get; set; }
[Obsolete("This isn't set correctly anymore")]
public FFmpegLocation EncoderLocation { get; set; }
public Architecture SystemArchitecture { get; set; }

View File

@@ -11,12 +11,12 @@ 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.
/// Gets the options of this task.
/// </summary>
TaskOptions TaskOptions { get; set; }
TaskOptions TaskOptions { get; }
/// <summary>
/// Stars waiting for the trigger action.

View File

@@ -1,4 +1,3 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
@@ -16,7 +15,6 @@ namespace MediaBrowser.Model.Updates
public PackageInfo()
{
Versions = Array.Empty<VersionInfo>();
Id = string.Empty;
Category = string.Empty;
Name = string.Empty;
Overview = string.Empty;
@@ -65,7 +63,7 @@ namespace MediaBrowser.Model.Updates
/// </summary>
/// <value>The name.</value>
[JsonPropertyName("guid")]
public string Id { get; set; }
public Guid Id { get; set; }
/// <summary>
/// Gets or sets the versions.

View File

@@ -1,5 +1,3 @@
#nullable enable
using System.Text.Json.Serialization;
using SysVersion = System.Version;

View File

@@ -1,6 +1,7 @@
#nullable disable
#pragma warning disable CS1591
using System;
namespace MediaBrowser.Model.Users
{
public class PinRedeemResult
@@ -15,6 +16,6 @@ namespace MediaBrowser.Model.Users
/// Gets or sets the users reset.
/// </summary>
/// <value>The users reset.</value>
public string[] UsersReset { get; set; }
public string[] UsersReset { get; set; } = Array.Empty<string>();
}
}

View File

@@ -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; }
}
}

View File

@@ -1,9 +0,0 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Users
{
public enum UserActionType
{
PlayedItem = 0
}
}

View File

@@ -1,5 +1,5 @@
#nullable disable
#pragma warning disable CS1591
#pragma warning disable CS1591, CA1819
using System;
using System.Xml.Serialization;