diff options
Diffstat (limited to 'MediaBrowser.Model')
27 files changed, 499 insertions, 483 deletions
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index 3f0e98ec8..84c735f9c 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -50,6 +50,7 @@ public class EncodingOptions EnableHardwareEncoding = true; AllowHevcEncoding = false; AllowAv1Encoding = false; + AllowMjpegEncoding = false; EnableSubtitleExtraction = true; AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = new[] { "mkv" }; HardwareDecodingCodecs = new string[] { "h264", "vc1" }; @@ -256,6 +257,11 @@ public class EncodingOptions public bool AllowAv1Encoding { get; set; } /// <summary> + /// Gets or sets a value indicating whether MJPEG encoding is enabled. + /// </summary> + public bool AllowMjpegEncoding { get; set; } + + /// <summary> /// Gets or sets a value indicating whether subtitle extraction is enabled. /// </summary> public bool EnableSubtitleExtraction { get; set; } diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs index 9743edb1c..fbad29143 100644 --- a/MediaBrowser.Model/Configuration/LibraryOptions.cs +++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs @@ -35,6 +35,10 @@ namespace MediaBrowser.Model.Configuration public bool ExtractChapterImagesDuringLibraryScan { get; set; } + public bool EnableTrickplayImageExtraction { get; set; } + + public bool ExtractTrickplayImagesDuringLibraryScan { get; set; } + public MediaPathInfo[] PathInfos { get; set; } public bool SaveLocalMetadata { get; set; } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 78a310f0b..fe92251e9 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -4,265 +4,283 @@ using System; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.System; using MediaBrowser.Model.Updates; -namespace MediaBrowser.Model.Configuration +namespace MediaBrowser.Model.Configuration; + +/// <summary> +/// Represents the server configuration. +/// </summary> +public class ServerConfiguration : BaseApplicationConfiguration { /// <summary> - /// Represents the server configuration. + /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. /// </summary> - public class ServerConfiguration : BaseApplicationConfiguration + public ServerConfiguration() { - /// <summary> - /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. - /// </summary> - public ServerConfiguration() + MetadataOptions = new[] { - MetadataOptions = new[] + new MetadataOptions() + { + ItemType = "Book" + }, + new MetadataOptions() + { + ItemType = "Movie" + }, + new MetadataOptions + { + ItemType = "MusicVideo", + DisabledMetadataFetchers = new[] { "The Open Movie Database" }, + DisabledImageFetchers = new[] { "The Open Movie Database" } + }, + new MetadataOptions + { + ItemType = "Series", + }, + new MetadataOptions + { + ItemType = "MusicAlbum", + DisabledMetadataFetchers = new[] { "TheAudioDB" } + }, + new MetadataOptions + { + ItemType = "MusicArtist", + DisabledMetadataFetchers = new[] { "TheAudioDB" } + }, + new MetadataOptions + { + ItemType = "BoxSet" + }, + new MetadataOptions { - new MetadataOptions() - { - ItemType = "Book" - }, - new MetadataOptions() - { - ItemType = "Movie" - }, - new MetadataOptions - { - ItemType = "MusicVideo", - DisabledMetadataFetchers = new[] { "The Open Movie Database" }, - DisabledImageFetchers = new[] { "The Open Movie Database" } - }, - new MetadataOptions - { - ItemType = "Series", - }, - new MetadataOptions - { - ItemType = "MusicAlbum", - DisabledMetadataFetchers = new[] { "TheAudioDB" } - }, - new MetadataOptions - { - ItemType = "MusicArtist", - DisabledMetadataFetchers = new[] { "TheAudioDB" } - }, - new MetadataOptions - { - ItemType = "BoxSet" - }, - new MetadataOptions - { - ItemType = "Season", - }, - new MetadataOptions - { - ItemType = "Episode", - } - }; - } - - /// <summary> - /// Gets or sets a value indicating whether to enable prometheus metrics exporting. - /// </summary> - public bool EnableMetrics { get; set; } = false; - - public bool EnableNormalizedItemByNameIds { get; set; } = true; - - /// <summary> - /// Gets or sets a value indicating whether this instance is port authorized. - /// </summary> - /// <value><c>true</c> if this instance is port authorized; otherwise, <c>false</c>.</value> - public bool IsPortAuthorized { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether quick connect is available for use on this server. - /// </summary> - public bool QuickConnectAvailable { get; set; } = true; - - /// <summary> - /// Gets or sets a value indicating whether [enable case sensitive item ids]. - /// </summary> - /// <value><c>true</c> if [enable case sensitive item ids]; otherwise, <c>false</c>.</value> - public bool EnableCaseSensitiveItemIds { get; set; } = true; - - public bool DisableLiveTvChannelUserDataName { get; set; } = true; - - /// <summary> - /// Gets or sets the metadata path. - /// </summary> - /// <value>The metadata path.</value> - public string MetadataPath { get; set; } = string.Empty; - - public string MetadataNetworkPath { get; set; } = string.Empty; - - /// <summary> - /// Gets or sets the preferred metadata language. - /// </summary> - /// <value>The preferred metadata language.</value> - public string PreferredMetadataLanguage { get; set; } = "en"; - - /// <summary> - /// Gets or sets the metadata country code. - /// </summary> - /// <value>The metadata country code.</value> - public string MetadataCountryCode { get; set; } = "US"; - - /// <summary> - /// Gets or sets characters to be replaced with a ' ' in strings to create a sort name. - /// </summary> - /// <value>The sort replace characters.</value> - public string[] SortReplaceCharacters { get; set; } = new[] { ".", "+", "%" }; - - /// <summary> - /// Gets or sets characters to be removed from strings to create a sort name. - /// </summary> - /// <value>The sort remove characters.</value> - public string[] SortRemoveCharacters { get; set; } = new[] { ",", "&", "-", "{", "}", "'" }; - - /// <summary> - /// Gets or sets words to be removed from strings to create a sort name. - /// </summary> - /// <value>The sort remove words.</value> - public string[] SortRemoveWords { get; set; } = new[] { "the", "a", "an" }; - - /// <summary> - /// Gets or sets the minimum percentage of an item that must be played in order for playstate to be updated. - /// </summary> - /// <value>The min resume PCT.</value> - public int MinResumePct { get; set; } = 5; - - /// <summary> - /// Gets or sets the maximum percentage of an item that can be played while still saving playstate. If this percentage is crossed playstate will be reset to the beginning and the item will be marked watched. - /// </summary> - /// <value>The max resume PCT.</value> - public int MaxResumePct { get; set; } = 90; - - /// <summary> - /// Gets or sets the minimum duration that an item must have in order to be eligible for playstate updates.. - /// </summary> - /// <value>The min resume duration seconds.</value> - public int MinResumeDurationSeconds { get; set; } = 300; - - /// <summary> - /// Gets or sets the minimum minutes of a book that must be played in order for playstate to be updated. - /// </summary> - /// <value>The min resume in minutes.</value> - public int MinAudiobookResume { get; set; } = 5; - - /// <summary> - /// Gets or sets the remaining minutes of a book that can be played while still saving playstate. If this percentage is crossed playstate will be reset to the beginning and the item will be marked watched. - /// </summary> - /// <value>The remaining time in minutes.</value> - public int MaxAudiobookResume { get; set; } = 5; - - /// <summary> - /// Gets or sets the delay in seconds that we will wait after a file system change to try and discover what has been added/removed - /// Some delay is necessary with some items because their creation is not atomic. It involves the creation of several - /// different directories and files. - /// </summary> - /// <value>The file watcher delay.</value> - public int LibraryMonitorDelay { get; set; } = 60; - - /// <summary> - /// Gets or sets the duration in seconds that we will wait after a library updated event before executing the library changed notification. - /// </summary> - /// <value>The library update duration.</value> - public int LibraryUpdateDuration { get; set; } = 30; - - /// <summary> - /// Gets or sets the image saving convention. - /// </summary> - /// <value>The image saving convention.</value> - public ImageSavingConvention ImageSavingConvention { get; set; } - - public MetadataOptions[] MetadataOptions { get; set; } - - public bool SkipDeserializationForBasicTypes { get; set; } = true; - - public string ServerName { get; set; } = string.Empty; - - public string UICulture { get; set; } = "en-US"; - - public bool SaveMetadataHidden { get; set; } = false; - - public NameValuePair[] ContentTypes { get; set; } = Array.Empty<NameValuePair>(); - - public int RemoteClientBitrateLimit { get; set; } - - public bool EnableFolderView { get; set; } = false; - - public bool EnableGroupingIntoCollections { get; set; } = false; - - public bool DisplaySpecialsWithinSeasons { get; set; } = true; - - public string[] CodecsUsed { get; set; } = Array.Empty<string>(); - - public RepositoryInfo[] PluginRepositories { get; set; } = Array.Empty<RepositoryInfo>(); - - public bool EnableExternalContentInSuggestions { get; set; } = true; - - public int ImageExtractionTimeoutMs { get; set; } - - public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty<PathSubstitution>(); - - /// <summary> - /// Gets or sets a value indicating whether slow server responses should be logged as a warning. - /// </summary> - public bool EnableSlowResponseWarning { get; set; } = true; - - /// <summary> - /// Gets or sets the threshold for the slow response time warning in ms. - /// </summary> - public long SlowResponseThresholdMs { get; set; } = 500; - - /// <summary> - /// Gets or sets the cors hosts. - /// </summary> - public string[] CorsHosts { get; set; } = new[] { "*" }; - - /// <summary> - /// Gets or sets the number of days we should retain activity logs. - /// </summary> - public int? ActivityLogRetentionDays { get; set; } = 30; + ItemType = "Season", + }, + new MetadataOptions + { + ItemType = "Episode", + } + }; + } + + /// <summary> + /// Gets or sets a value indicating whether to enable prometheus metrics exporting. + /// </summary> + public bool EnableMetrics { get; set; } = false; + + public bool EnableNormalizedItemByNameIds { get; set; } = true; + + /// <summary> + /// Gets or sets a value indicating whether this instance is port authorized. + /// </summary> + /// <value><c>true</c> if this instance is port authorized; otherwise, <c>false</c>.</value> + public bool IsPortAuthorized { get; set; } - /// <summary> - /// Gets or sets the how the library scan fans out. - /// </summary> - public int LibraryScanFanoutConcurrency { get; set; } + /// <summary> + /// Gets or sets a value indicating whether quick connect is available for use on this server. + /// </summary> + public bool QuickConnectAvailable { get; set; } = true; - /// <summary> - /// Gets or sets the how many metadata refreshes can run concurrently. - /// </summary> - public int LibraryMetadataRefreshConcurrency { get; set; } + /// <summary> + /// Gets or sets a value indicating whether [enable case sensitive item ids]. + /// </summary> + /// <value><c>true</c> if [enable case sensitive item ids]; otherwise, <c>false</c>.</value> + public bool EnableCaseSensitiveItemIds { get; set; } = true; - /// <summary> - /// Gets or sets a value indicating whether older plugins should automatically be deleted from the plugin folder. - /// </summary> - public bool RemoveOldPlugins { get; set; } + public bool DisableLiveTvChannelUserDataName { get; set; } = true; - /// <summary> - /// Gets or sets a value indicating whether clients should be allowed to upload logs. - /// </summary> - public bool AllowClientLogUpload { get; set; } = true; + /// <summary> + /// Gets or sets the metadata path. + /// </summary> + /// <value>The metadata path.</value> + public string MetadataPath { get; set; } = string.Empty; - /// <summary> - /// Gets or sets the dummy chapter duration in seconds, use 0 (zero) or less to disable generation alltogether. - /// </summary> - /// <value>The dummy chapters duration.</value> - public int DummyChapterDuration { get; set; } + public string MetadataNetworkPath { get; set; } = string.Empty; - /// <summary> - /// Gets or sets the chapter image resolution. - /// </summary> - /// <value>The chapter image resolution.</value> - public ImageResolution ChapterImageResolution { get; set; } = ImageResolution.MatchSource; + /// <summary> + /// Gets or sets the preferred metadata language. + /// </summary> + /// <value>The preferred metadata language.</value> + public string PreferredMetadataLanguage { get; set; } = "en"; - /// <summary> - /// Gets or sets the limit for parallel image encoding. - /// </summary> - /// <value>The limit for parallel image encoding.</value> - public int ParallelImageEncodingLimit { get; set; } - } + /// <summary> + /// Gets or sets the metadata country code. + /// </summary> + /// <value>The metadata country code.</value> + public string MetadataCountryCode { get; set; } = "US"; + + /// <summary> + /// Gets or sets characters to be replaced with a ' ' in strings to create a sort name. + /// </summary> + /// <value>The sort replace characters.</value> + public string[] SortReplaceCharacters { get; set; } = new[] { ".", "+", "%" }; + + /// <summary> + /// Gets or sets characters to be removed from strings to create a sort name. + /// </summary> + /// <value>The sort remove characters.</value> + public string[] SortRemoveCharacters { get; set; } = new[] { ",", "&", "-", "{", "}", "'" }; + + /// <summary> + /// Gets or sets words to be removed from strings to create a sort name. + /// </summary> + /// <value>The sort remove words.</value> + public string[] SortRemoveWords { get; set; } = new[] { "the", "a", "an" }; + + /// <summary> + /// Gets or sets the minimum percentage of an item that must be played in order for playstate to be updated. + /// </summary> + /// <value>The min resume PCT.</value> + public int MinResumePct { get; set; } = 5; + + /// <summary> + /// Gets or sets the maximum percentage of an item that can be played while still saving playstate. If this percentage is crossed playstate will be reset to the beginning and the item will be marked watched. + /// </summary> + /// <value>The max resume PCT.</value> + public int MaxResumePct { get; set; } = 90; + + /// <summary> + /// Gets or sets the minimum duration that an item must have in order to be eligible for playstate updates.. + /// </summary> + /// <value>The min resume duration seconds.</value> + public int MinResumeDurationSeconds { get; set; } = 300; + + /// <summary> + /// Gets or sets the minimum minutes of a book that must be played in order for playstate to be updated. + /// </summary> + /// <value>The min resume in minutes.</value> + public int MinAudiobookResume { get; set; } = 5; + + /// <summary> + /// Gets or sets the remaining minutes of a book that can be played while still saving playstate. If this percentage is crossed playstate will be reset to the beginning and the item will be marked watched. + /// </summary> + /// <value>The remaining time in minutes.</value> + public int MaxAudiobookResume { get; set; } = 5; + + /// <summary> + /// Gets or sets the threshold in minutes after a inactive session gets closed automatically. + /// If set to 0 the check for inactive sessions gets disabled. + /// </summary> + /// <value>The close inactive session threshold in minutes. 0 to disable.</value> + public int InactiveSessionThreshold { get; set; } = 10; + + /// <summary> + /// Gets or sets the delay in seconds that we will wait after a file system change to try and discover what has been added/removed + /// Some delay is necessary with some items because their creation is not atomic. It involves the creation of several + /// different directories and files. + /// </summary> + /// <value>The file watcher delay.</value> + public int LibraryMonitorDelay { get; set; } = 60; + + /// <summary> + /// Gets or sets the duration in seconds that we will wait after a library updated event before executing the library changed notification. + /// </summary> + /// <value>The library update duration.</value> + public int LibraryUpdateDuration { get; set; } = 30; + + /// <summary> + /// Gets or sets the image saving convention. + /// </summary> + /// <value>The image saving convention.</value> + public ImageSavingConvention ImageSavingConvention { get; set; } + + public MetadataOptions[] MetadataOptions { get; set; } + + public bool SkipDeserializationForBasicTypes { get; set; } = true; + + public string ServerName { get; set; } = string.Empty; + + public string UICulture { get; set; } = "en-US"; + + public bool SaveMetadataHidden { get; set; } = false; + + public NameValuePair[] ContentTypes { get; set; } = Array.Empty<NameValuePair>(); + + public int RemoteClientBitrateLimit { get; set; } + + public bool EnableFolderView { get; set; } = false; + + public bool EnableGroupingIntoCollections { get; set; } = false; + + public bool DisplaySpecialsWithinSeasons { get; set; } = true; + + public string[] CodecsUsed { get; set; } = Array.Empty<string>(); + + public RepositoryInfo[] PluginRepositories { get; set; } = Array.Empty<RepositoryInfo>(); + + public bool EnableExternalContentInSuggestions { get; set; } = true; + + public int ImageExtractionTimeoutMs { get; set; } + + public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty<PathSubstitution>(); + + /// <summary> + /// Gets or sets a value indicating whether slow server responses should be logged as a warning. + /// </summary> + public bool EnableSlowResponseWarning { get; set; } = true; + + /// <summary> + /// Gets or sets the threshold for the slow response time warning in ms. + /// </summary> + public long SlowResponseThresholdMs { get; set; } = 500; + + /// <summary> + /// Gets or sets the cors hosts. + /// </summary> + public string[] CorsHosts { get; set; } = new[] { "*" }; + + /// <summary> + /// Gets or sets the number of days we should retain activity logs. + /// </summary> + public int? ActivityLogRetentionDays { get; set; } = 30; + + /// <summary> + /// Gets or sets the how the library scan fans out. + /// </summary> + public int LibraryScanFanoutConcurrency { get; set; } + + /// <summary> + /// Gets or sets the how many metadata refreshes can run concurrently. + /// </summary> + public int LibraryMetadataRefreshConcurrency { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether older plugins should automatically be deleted from the plugin folder. + /// </summary> + public bool RemoveOldPlugins { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether clients should be allowed to upload logs. + /// </summary> + public bool AllowClientLogUpload { get; set; } = true; + + /// <summary> + /// Gets or sets the dummy chapter duration in seconds, use 0 (zero) or less to disable generation alltogether. + /// </summary> + /// <value>The dummy chapters duration.</value> + public int DummyChapterDuration { get; set; } + + /// <summary> + /// Gets or sets the chapter image resolution. + /// </summary> + /// <value>The chapter image resolution.</value> + public ImageResolution ChapterImageResolution { get; set; } = ImageResolution.MatchSource; + + /// <summary> + /// Gets or sets the limit for parallel image encoding. + /// </summary> + /// <value>The limit for parallel image encoding.</value> + public int ParallelImageEncodingLimit { get; set; } + + /// <summary> + /// Gets or sets the list of cast receiver applications. + /// </summary> + public CastReceiverApplication[] CastReceiverApplications { get; set; } = Array.Empty<CastReceiverApplication>(); + + /// <summary> + /// Gets or sets the trickplay options. + /// </summary> + /// <value>The trickplay options.</value> + public TrickplayOptions TrickplayOptions { get; set; } = new TrickplayOptions(); } diff --git a/MediaBrowser.Model/Configuration/TrickplayOptions.cs b/MediaBrowser.Model/Configuration/TrickplayOptions.cs new file mode 100644 index 000000000..92c16ee84 --- /dev/null +++ b/MediaBrowser.Model/Configuration/TrickplayOptions.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using System.Diagnostics; + +namespace MediaBrowser.Model.Configuration; + +/// <summary> +/// Class TrickplayOptions. +/// </summary> +public class TrickplayOptions +{ + /// <summary> + /// Gets or sets a value indicating whether or not to use HW acceleration. + /// </summary> + public bool EnableHwAcceleration { get; set; } = false; + + /// <summary> + /// Gets or sets the behavior used by trickplay provider on library scan/update. + /// </summary> + public TrickplayScanBehavior ScanBehavior { get; set; } = TrickplayScanBehavior.NonBlocking; + + /// <summary> + /// Gets or sets the process priority for the ffmpeg process. + /// </summary> + public ProcessPriorityClass ProcessPriority { get; set; } = ProcessPriorityClass.BelowNormal; + + /// <summary> + /// Gets or sets the interval, in ms, between each new trickplay image. + /// </summary> + public int Interval { get; set; } = 10000; + + /// <summary> + /// Gets or sets the target width resolutions, in px, to generates preview images for. + /// </summary> + public int[] WidthResolutions { get; set; } = new[] { 320 }; + + /// <summary> + /// Gets or sets number of tile images to allow in X dimension. + /// </summary> + public int TileWidth { get; set; } = 10; + + /// <summary> + /// Gets or sets number of tile images to allow in Y dimension. + /// </summary> + public int TileHeight { get; set; } = 10; + + /// <summary> + /// Gets or sets the ffmpeg output quality level. + /// </summary> + public int Qscale { get; set; } = 4; + + /// <summary> + /// Gets or sets the jpeg quality to use for image tiles. + /// </summary> + public int JpegQuality { get; set; } = 90; + + /// <summary> + /// Gets or sets the number of threads to be used by ffmpeg. + /// </summary> + public int ProcessThreads { get; set; } = 1; +} diff --git a/MediaBrowser.Model/Configuration/TrickplayScanBehavior.cs b/MediaBrowser.Model/Configuration/TrickplayScanBehavior.cs new file mode 100644 index 000000000..d0db53218 --- /dev/null +++ b/MediaBrowser.Model/Configuration/TrickplayScanBehavior.cs @@ -0,0 +1,17 @@ +namespace MediaBrowser.Model.Configuration; + +/// <summary> +/// Enum TrickplayScanBehavior. +/// </summary> +public enum TrickplayScanBehavior +{ + /// <summary> + /// Starts generation, only return once complete. + /// </summary> + Blocking, + + /// <summary> + /// Start generation, return immediately. + /// </summary> + NonBlocking +} diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index 94f354660..b477f2593 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -69,5 +69,10 @@ namespace MediaBrowser.Model.Configuration public bool RememberSubtitleSelections { get; set; } public bool EnableNextEpisodeAutoPlay { get; set; } + + /// <summary> + /// Gets or sets the id of the selected cast receiver. + /// </summary> + public string? CastReceiverId { get; set; } } } diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 07bb002ea..71d0896a7 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -1,6 +1,7 @@ #pragma warning disable CA1819 // Properties should not return arrays using System; using System.ComponentModel; +using System.Linq; using System.Xml.Serialization; using Jellyfin.Data.Enums; using Jellyfin.Extensions; @@ -227,9 +228,12 @@ namespace MediaBrowser.Model.Dlna /// The GetSupportedMediaTypes. /// </summary> /// <returns>The .</returns> - public string[] GetSupportedMediaTypes() + public MediaType[] GetSupportedMediaTypes() { - return ContainerProfile.SplitValue(SupportedMediaTypes); + return ContainerProfile.SplitValue(SupportedMediaTypes) + .Select(m => Enum.TryParse<MediaType>(m, out var parsed) ? parsed : MediaType.Unknown) + .Where(m => m != MediaType.Unknown) + .ToArray(); } /// <summary> diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 889e2494a..666e78795 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -1313,7 +1313,7 @@ namespace MediaBrowser.Model.Dlna var audioFailureConditions = GetProfileConditionsForVideoAudio(profile.CodecProfiles, container, audioStream.Codec, audioStream.Channels, audioStream.BitRate, audioStream.SampleRate, audioStream.BitDepth, audioStream.Profile, mediaSource.IsSecondaryAudio(audioStream)); var audioStreamFailureReasons = AggregateFailureConditions(mediaSource, profile, "VideoAudioCodecProfile", audioFailureConditions); - if (audioStream?.IsExternal == true) + if (audioStream.IsExternal == true) { audioStreamFailureReasons |= TranscodeReason.AudioIsExternal; } diff --git a/MediaBrowser.Model/Drawing/ImageFormatExtensions.cs b/MediaBrowser.Model/Drawing/ImageFormatExtensions.cs index 68a5c2534..1bb24112e 100644 --- a/MediaBrowser.Model/Drawing/ImageFormatExtensions.cs +++ b/MediaBrowser.Model/Drawing/ImageFormatExtensions.cs @@ -24,4 +24,21 @@ public static class ImageFormatExtensions ImageFormat.Webp => "image/webp", _ => throw new InvalidEnumArgumentException(nameof(format), (int)format, typeof(ImageFormat)) }; + + /// <summary> + /// Returns the correct extension for this <see cref="ImageFormat" />. + /// </summary> + /// <param name="format">This <see cref="ImageFormat" />.</param> + /// <exception cref="InvalidEnumArgumentException">The <paramref name="format"/> is an invalid enumeration value.</exception> + /// <returns>The correct extension for this <see cref="ImageFormat" />.</returns> + public static string GetExtension(this ImageFormat format) + => format switch + { + ImageFormat.Bmp => ".bmp", + ImageFormat.Gif => ".gif", + ImageFormat.Jpg => ".jpg", + ImageFormat.Png => ".png", + ImageFormat.Webp => ".webp", + _ => throw new InvalidEnumArgumentException(nameof(format), (int)format, typeof(ImageFormat)) + }; } diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 8fab1ca6d..d257eab92 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using Jellyfin.Data.Entities; using Jellyfin.Data.Enums; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; @@ -419,7 +420,7 @@ namespace MediaBrowser.Model.Dto /// Gets or sets the type of the collection. /// </summary> /// <value>The type of the collection.</value> - public string CollectionType { get; set; } + public CollectionType? CollectionType { get; set; } /// <summary> /// Gets or sets the display order. @@ -569,6 +570,12 @@ namespace MediaBrowser.Model.Dto public List<ChapterInfo> Chapters { get; set; } /// <summary> + /// Gets or sets the trickplay manifest. + /// </summary> + /// <value>The trickplay manifest.</value> + public Dictionary<string, Dictionary<int, TrickplayInfo>> Trickplay { get; set; } + + /// <summary> /// Gets or sets the type of the location. /// </summary> /// <value>The type of the location.</value> @@ -584,7 +591,7 @@ namespace MediaBrowser.Model.Dto /// Gets or sets the type of the media. /// </summary> /// <value>The type of the media.</value> - public string MediaType { get; set; } + public MediaType MediaType { get; set; } /// <summary> /// Gets or sets the end date. diff --git a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs index d098669ba..a3035bf61 100644 --- a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs +++ b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using Jellyfin.Data.Enums; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Providers; @@ -27,7 +28,7 @@ namespace MediaBrowser.Model.Dto public IReadOnlyList<ExternalIdInfo> ExternalIdInfos { get; set; } - public string? ContentType { get; set; } + public CollectionType? ContentType { get; set; } public IReadOnlyList<NameValuePair> ContentTypeOptions { get; set; } } diff --git a/MediaBrowser.Model/Entities/CollectionType.cs b/MediaBrowser.Model/Entities/CollectionType.cs deleted file mode 100644 index 60b69d4b0..000000000 --- a/MediaBrowser.Model/Entities/CollectionType.cs +++ /dev/null @@ -1,27 +0,0 @@ -#pragma warning disable CS1591 - -namespace MediaBrowser.Model.Entities -{ - public static class CollectionType - { - public const string Movies = "movies"; - - public const string TvShows = "tvshows"; - - public const string Music = "music"; - - public const string MusicVideos = "musicvideos"; - - public const string Trailers = "trailers"; - - public const string HomeVideos = "homevideos"; - - public const string BoxSets = "boxsets"; - - public const string Books = "books"; - public const string Photos = "photos"; - public const string LiveTv = "livetv"; - public const string Playlists = "playlists"; - public const string Folders = "folders"; - } -} diff --git a/MediaBrowser.Model/Entities/MediaType.cs b/MediaBrowser.Model/Entities/MediaType.cs deleted file mode 100644 index dd2ae810b..000000000 --- a/MediaBrowser.Model/Entities/MediaType.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace MediaBrowser.Model.Entities -{ - /// <summary> - /// Class MediaType. - /// </summary> - public static class MediaType - { - /// <summary> - /// The video. - /// </summary> - public const string Video = "Video"; - - /// <summary> - /// The audio. - /// </summary> - public const string Audio = "Audio"; - - /// <summary> - /// The photo. - /// </summary> - public const string Photo = "Photo"; - - /// <summary> - /// The book. - /// </summary> - public const string Book = "Book"; - } -} diff --git a/MediaBrowser.Model/Library/UserViewQuery.cs b/MediaBrowser.Model/Library/UserViewQuery.cs index 8a49b6863..e20d6af49 100644 --- a/MediaBrowser.Model/Library/UserViewQuery.cs +++ b/MediaBrowser.Model/Library/UserViewQuery.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System; +using Jellyfin.Data.Enums; namespace MediaBrowser.Model.Library { @@ -9,7 +10,7 @@ namespace MediaBrowser.Model.Library public UserViewQuery() { IncludeExternalContent = true; - PresetViews = Array.Empty<string>(); + PresetViews = Array.Empty<CollectionType?>(); } /// <summary> @@ -30,6 +31,6 @@ namespace MediaBrowser.Model.Library /// <value><c>true</c> if [include hidden]; otherwise, <c>false</c>.</value> public bool IncludeHidden { get; set; } - public string[] PresetViews { get; set; } + public CollectionType?[] PresetViews { get; set; } } } diff --git a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs index 673d97a9e..d872572b7 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Model.LiveTv public LiveTvChannelQuery() { EnableUserData = true; - SortBy = Array.Empty<string>(); + SortBy = Array.Empty<ItemSortBy>(); } /// <summary> @@ -99,7 +99,7 @@ namespace MediaBrowser.Model.LiveTv public bool? IsSeries { get; set; } - public string[] SortBy { get; set; } + public ItemSortBy[] SortBy { get; set; } /// <summary> /// Gets or sets the sort order to return results with. diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 58ba83a35..75c5bc6f0 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -48,8 +48,12 @@ <Compile Include="..\SharedVersion.cs" /> </ItemGroup> - <!-- Code Analyzers--> + <!-- Code Analyzers --> <ItemGroup Condition=" '$(Configuration)' == 'Debug' "> + <PackageReference Include="IDisposableAnalyzers"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> + </PackageReference> <PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> @@ -58,6 +62,7 @@ <PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" /> <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" PrivateAssets="All" /> </ItemGroup> + <ItemGroup> <ProjectReference Include="../Jellyfin.Data/Jellyfin.Data.csproj" /> <ProjectReference Include="../src/Jellyfin.Extensions/Jellyfin.Extensions.csproj" /> diff --git a/MediaBrowser.Model/Net/IPData.cs b/MediaBrowser.Model/Net/IPData.cs index 985b16c6e..e9fcd6797 100644 --- a/MediaBrowser.Model/Net/IPData.cs +++ b/MediaBrowser.Model/Net/IPData.cs @@ -48,6 +48,11 @@ public class IPData public int Index { get; set; } /// <summary> + /// Gets or sets a value indicating whether the network supports multicast. + /// </summary> + public bool SupportsMulticast { get; set; } = false; + + /// <summary> /// Gets or sets the interface name. /// </summary> public string Name { get; set; } diff --git a/MediaBrowser.Model/Net/PublishedServerUriOverride.cs b/MediaBrowser.Model/Net/PublishedServerUriOverride.cs new file mode 100644 index 000000000..476d1ba38 --- /dev/null +++ b/MediaBrowser.Model/Net/PublishedServerUriOverride.cs @@ -0,0 +1,42 @@ +namespace MediaBrowser.Model.Net; + +/// <summary> +/// Class holding information for a published server URI override. +/// </summary> +public class PublishedServerUriOverride +{ + /// <summary> + /// Initializes a new instance of the <see cref="PublishedServerUriOverride"/> class. + /// </summary> + /// <param name="data">The <see cref="IPData"/>.</param> + /// <param name="overrideUri">The override.</param> + /// <param name="internalOverride">A value indicating whether the override is for internal requests.</param> + /// <param name="externalOverride">A value indicating whether the override is for external requests.</param> + public PublishedServerUriOverride(IPData data, string overrideUri, bool internalOverride, bool externalOverride) + { + Data = data; + OverrideUri = overrideUri; + IsInternalOverride = internalOverride; + IsExternalOverride = externalOverride; + } + + /// <summary> + /// Gets or sets the object's IP address. + /// </summary> + public IPData Data { get; set; } + + /// <summary> + /// Gets or sets the override URI. + /// </summary> + public string OverrideUri { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the override should be applied to internal requests. + /// </summary> + public bool IsInternalOverride { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the override should be applied to external requests. + /// </summary> + public bool IsExternalOverride { get; set; } +} diff --git a/MediaBrowser.Model/Playlists/PlaylistCreationRequest.cs b/MediaBrowser.Model/Playlists/PlaylistCreationRequest.cs index 847269716..62d496d04 100644 --- a/MediaBrowser.Model/Playlists/PlaylistCreationRequest.cs +++ b/MediaBrowser.Model/Playlists/PlaylistCreationRequest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Jellyfin.Data.Enums; using MediaBrowser.Model.Entities; namespace MediaBrowser.Model.Playlists; @@ -22,7 +23,7 @@ public class PlaylistCreationRequest /// <summary> /// Gets or sets the media type. /// </summary> - public string? MediaType { get; set; } + public MediaType? MediaType { get; set; } /// <summary> /// Gets or sets the user id. diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 6fa1d778a..242a1c6e9 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -34,6 +34,11 @@ namespace MediaBrowser.Model.Querying /// </summary> Chapters, + /// <summary> + /// The trickplay manifest. + /// </summary> + Trickplay, + ChildCount, /// <summary> diff --git a/MediaBrowser.Model/Querying/ItemSortBy.cs b/MediaBrowser.Model/Querying/ItemSortBy.cs deleted file mode 100644 index 1a7c9a63b..000000000 --- a/MediaBrowser.Model/Querying/ItemSortBy.cs +++ /dev/null @@ -1,163 +0,0 @@ -namespace MediaBrowser.Model.Querying -{ - /// <summary> - /// These represent sort orders that are known by the core. - /// </summary> - public static class ItemSortBy - { - /// <summary> - /// The aired episode order. - /// </summary> - public const string AiredEpisodeOrder = "AiredEpisodeOrder"; - - /// <summary> - /// The album. - /// </summary> - public const string Album = "Album"; - - /// <summary> - /// The album artist. - /// </summary> - public const string AlbumArtist = "AlbumArtist"; - - /// <summary> - /// The artist. - /// </summary> - public const string Artist = "Artist"; - - /// <summary> - /// The date created. - /// </summary> - public const string DateCreated = "DateCreated"; - - /// <summary> - /// The official rating. - /// </summary> - public const string OfficialRating = "OfficialRating"; - - /// <summary> - /// The date played. - /// </summary> - public const string DatePlayed = "DatePlayed"; - - /// <summary> - /// The premiere date. - /// </summary> - public const string PremiereDate = "PremiereDate"; - - /// <summary> - /// The start date. - /// </summary> - public const string StartDate = "StartDate"; - - /// <summary> - /// The sort name. - /// </summary> - public const string SortName = "SortName"; - - /// <summary> - /// The name. - /// </summary> - public const string Name = "Name"; - - /// <summary> - /// The random. - /// </summary> - public const string Random = "Random"; - - /// <summary> - /// The runtime. - /// </summary> - public const string Runtime = "Runtime"; - - /// <summary> - /// The community rating. - /// </summary> - public const string CommunityRating = "CommunityRating"; - - /// <summary> - /// The production year. - /// </summary> - public const string ProductionYear = "ProductionYear"; - - /// <summary> - /// The play count. - /// </summary> - public const string PlayCount = "PlayCount"; - - /// <summary> - /// The critic rating. - /// </summary> - public const string CriticRating = "CriticRating"; - - /// <summary> - /// The IsFolder boolean. - /// </summary> - public const string IsFolder = "IsFolder"; - - /// <summary> - /// The IsUnplayed boolean. - /// </summary> - public const string IsUnplayed = "IsUnplayed"; - - /// <summary> - /// The IsPlayed boolean. - /// </summary> - public const string IsPlayed = "IsPlayed"; - - /// <summary> - /// The series sort. - /// </summary> - public const string SeriesSortName = "SeriesSortName"; - - /// <summary> - /// The video bitrate. - /// </summary> - public const string VideoBitRate = "VideoBitRate"; - - /// <summary> - /// The air time. - /// </summary> - public const string AirTime = "AirTime"; - - /// <summary> - /// The studio. - /// </summary> - public const string Studio = "Studio"; - - /// <summary> - /// The IsFavouriteOrLiked boolean. - /// </summary> - public const string IsFavoriteOrLiked = "IsFavoriteOrLiked"; - - /// <summary> - /// The last content added date. - /// </summary> - public const string DateLastContentAdded = "DateLastContentAdded"; - - /// <summary> - /// The series last played date. - /// </summary> - public const string SeriesDatePlayed = "SeriesDatePlayed"; - - /// <summary> - /// The parent index number. - /// </summary> - public const string ParentIndexNumber = "ParentIndexNumber"; - - /// <summary> - /// The index number. - /// </summary> - public const string IndexNumber = "IndexNumber"; - - /// <summary> - /// The similarity score. - /// </summary> - public const string SimilarityScore = "SimilarityScore"; - - /// <summary> - /// The search score. - /// </summary> - public const string SearchScore = "SearchScore"; - } -} diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs index 3fa7f3d56..fd911dbed 100644 --- a/MediaBrowser.Model/Search/SearchHint.cs +++ b/MediaBrowser.Model/Search/SearchHint.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Model.Search { Name = string.Empty; MatchedTerm = string.Empty; - MediaType = string.Empty; + MediaType = Jellyfin.Data.Enums.MediaType.Unknown; Artists = Array.Empty<string>(); } @@ -115,7 +115,7 @@ namespace MediaBrowser.Model.Search /// Gets or sets the type of the media. /// </summary> /// <value>The type of the media.</value> - public string MediaType { get; set; } + public MediaType MediaType { get; set; } /// <summary> /// Gets or sets the start date. diff --git a/MediaBrowser.Model/Search/SearchQuery.cs b/MediaBrowser.Model/Search/SearchQuery.cs index 1caed827f..b91fd8657 100644 --- a/MediaBrowser.Model/Search/SearchQuery.cs +++ b/MediaBrowser.Model/Search/SearchQuery.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Model.Search IncludePeople = true; IncludeStudios = true; - MediaTypes = Array.Empty<string>(); + MediaTypes = Array.Empty<MediaType>(); IncludeItemTypes = Array.Empty<BaseItemKind>(); ExcludeItemTypes = Array.Empty<BaseItemKind>(); } @@ -55,7 +55,7 @@ namespace MediaBrowser.Model.Search public bool IncludeArtists { get; set; } - public string[] MediaTypes { get; set; } + public MediaType[] MediaTypes { get; set; } public BaseItemKind[] IncludeItemTypes { get; set; } diff --git a/MediaBrowser.Model/Session/ClientCapabilities.cs b/MediaBrowser.Model/Session/ClientCapabilities.cs index d692906c6..7fefce9cd 100644 --- a/MediaBrowser.Model/Session/ClientCapabilities.cs +++ b/MediaBrowser.Model/Session/ClientCapabilities.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using Jellyfin.Data.Enums; using MediaBrowser.Model.Dlna; namespace MediaBrowser.Model.Session @@ -11,12 +12,12 @@ namespace MediaBrowser.Model.Session { public ClientCapabilities() { - PlayableMediaTypes = Array.Empty<string>(); + PlayableMediaTypes = Array.Empty<MediaType>(); SupportedCommands = Array.Empty<GeneralCommandType>(); SupportsPersistentIdentifier = true; } - public IReadOnlyList<string> PlayableMediaTypes { get; set; } + public IReadOnlyList<MediaType> PlayableMediaTypes { get; set; } public IReadOnlyList<GeneralCommandType> SupportedCommands { get; set; } diff --git a/MediaBrowser.Model/System/CastReceiverApplication.cs b/MediaBrowser.Model/System/CastReceiverApplication.cs new file mode 100644 index 000000000..6a49a5cac --- /dev/null +++ b/MediaBrowser.Model/System/CastReceiverApplication.cs @@ -0,0 +1,17 @@ +namespace MediaBrowser.Model.System; + +/// <summary> +/// The cast receiver application model. +/// </summary> +public class CastReceiverApplication +{ + /// <summary> + /// Gets or sets the cast receiver application id. + /// </summary> + public required string Id { get; set; } + + /// <summary> + /// Gets or sets the cast receiver application name. + /// </summary> + public required string Name { get; set; } +} diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index bd0099af7..aa7c03ebd 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -2,6 +2,7 @@ #pragma warning disable CS1591 using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using MediaBrowser.Model.Updates; @@ -84,7 +85,8 @@ namespace MediaBrowser.Model.System [Obsolete("This is always true")] public bool CanSelfRestart { get; set; } = true; - public bool CanLaunchWebBrowser { get; set; } + [Obsolete("This is always false")] + public bool CanLaunchWebBrowser { get; set; } = false; /// <summary> /// Gets or sets the program data path. @@ -129,6 +131,11 @@ namespace MediaBrowser.Model.System public string TranscodingTempPath { get; set; } /// <summary> + /// Gets or sets the list of cast receiver applications. + /// </summary> + public IReadOnlyList<CastReceiverApplication> CastReceiverApplications { get; set; } + + /// <summary> /// 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> diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 8354c60ef..219ed5d5f 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -3,6 +3,7 @@ using System; using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.Xml.Serialization; using Jellyfin.Data.Enums; using AccessSchedule = Jellyfin.Data.Entities.AccessSchedule; @@ -15,6 +16,7 @@ namespace MediaBrowser.Model.Users { IsHidden = true; EnableCollectionManagement = false; + EnableSubtitleManagement = false; EnableContentDeletion = false; EnableContentDeletionFromFolders = Array.Empty<string>(); @@ -84,6 +86,13 @@ namespace MediaBrowser.Model.Users public bool EnableCollectionManagement { get; set; } /// <summary> + /// Gets or sets a value indicating whether this instance can manage subtitles. + /// </summary> + /// <value><c>true</c> if this instance is allowed; otherwise, <c>false</c>.</value> + [DefaultValue(false)] + public bool EnableSubtitleManagement { get; set; } + + /// <summary> /// Gets or sets a value indicating whether this instance is disabled. /// </summary> /// <value><c>true</c> if this instance is disabled; otherwise, <c>false</c>.</value> @@ -166,8 +175,10 @@ namespace MediaBrowser.Model.Users public int RemoteClientBitrateLimit { get; set; } [XmlElement(ElementName = "AuthenticationProviderId")] + [Required(AllowEmptyStrings = false)] public string AuthenticationProviderId { get; set; } + [Required(AllowEmptyStrings= false)] public string PasswordResetProviderId { get; set; } /// <summary> |
