diff --git a/Emby.Dlna/ContentDirectory/StubType.cs b/Emby.Dlna/ContentDirectory/StubType.cs
index 982ae5d68e..a5116055d1 100644
--- a/Emby.Dlna/ContentDirectory/StubType.cs
+++ b/Emby.Dlna/ContentDirectory/StubType.cs
@@ -1,5 +1,5 @@
#pragma warning disable CS1591
-#pragma warning disable SA1602
+
namespace Emby.Dlna.ContentDirectory
{
diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs
index 21ba1c7552..9ab3240388 100644
--- a/Emby.Dlna/DlnaManager.cs
+++ b/Emby.Dlna/DlnaManager.cs
@@ -553,7 +553,7 @@ namespace Emby.Dlna
private void DumpProfiles()
{
- DeviceProfile[] list = new []
+ DeviceProfile[] list = new[]
{
new SamsungSmartTvProfile(),
new XboxOneProfile(),
diff --git a/Emby.Dlna/PlayTo/TransportState.cs b/Emby.Dlna/PlayTo/TransportState.cs
index 7068a5d24d..1ca71283a8 100644
--- a/Emby.Dlna/PlayTo/TransportState.cs
+++ b/Emby.Dlna/PlayTo/TransportState.cs
@@ -1,5 +1,5 @@
#pragma warning disable CS1591
-#pragma warning disable SA1602
+
namespace Emby.Dlna.PlayTo
{
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index dad8bec7b0..d78b93bd78 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -6207,9 +6207,9 @@ AND Type = @InternalPersonType)");
if (item.Type == MediaStreamType.Subtitle)
{
- item.localizedUndefined = _localization.GetLocalizedString("Undefined");
- item.localizedDefault = _localization.GetLocalizedString("Default");
- item.localizedForced = _localization.GetLocalizedString("Forced");
+ item.LocalizedUndefined = _localization.GetLocalizedString("Undefined");
+ item.LocalizedDefault = _localization.GetLocalizedString("Default");
+ item.LocalizedForced = _localization.GetLocalizedString("Forced");
}
return item;
diff --git a/Jellyfin.Api/Helpers/MediaInfoHelper.cs b/Jellyfin.Api/Helpers/MediaInfoHelper.cs
index 0d8315dee1..ce6740fc99 100644
--- a/Jellyfin.Api/Helpers/MediaInfoHelper.cs
+++ b/Jellyfin.Api/Helpers/MediaInfoHelper.cs
@@ -523,7 +523,7 @@ namespace Jellyfin.Api.Helpers
/// Dlna profile type.
public void NormalizeMediaSourceContainer(MediaSourceInfo mediaSource, DeviceProfile profile, DlnaProfileType type)
{
- mediaSource.Container = StreamBuilder.NormalizeMediaSourceFormatIntoSingleContainer(mediaSource.Container, mediaSource.Path, profile, type);
+ mediaSource.Container = StreamBuilder.NormalizeMediaSourceFormatIntoSingleContainer(mediaSource.Container, profile, type);
}
private void SetDeviceSpecificSubtitleInfo(StreamInfo info, MediaSourceInfo mediaSource, string accessToken)
diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs
index 4957ee8b8d..8df1f5c272 100644
--- a/Jellyfin.Api/Helpers/StreamingHelpers.cs
+++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs
@@ -183,7 +183,7 @@ namespace Jellyfin.Api.Helpers
if (string.IsNullOrEmpty(containerInternal))
{
containerInternal = streamingRequest.Static ?
- StreamBuilder.NormalizeMediaSourceFormatIntoSingleContainer(state.InputContainer, state.MediaPath, null, DlnaProfileType.Audio)
+ StreamBuilder.NormalizeMediaSourceFormatIntoSingleContainer(state.InputContainer, null, DlnaProfileType.Audio)
: GetOutputFileExtension(state);
}
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index b5291b5609..b9cb49cf2f 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -681,9 +681,9 @@ namespace MediaBrowser.MediaEncoding.Probing
{
stream.Type = MediaStreamType.Subtitle;
stream.Codec = NormalizeSubtitleCodec(stream.Codec);
- stream.localizedUndefined = _localization.GetLocalizedString("Undefined");
- stream.localizedDefault = _localization.GetLocalizedString("Default");
- stream.localizedForced = _localization.GetLocalizedString("Forced");
+ stream.LocalizedUndefined = _localization.GetLocalizedString("Undefined");
+ stream.LocalizedDefault = _localization.GetLocalizedString("Default");
+ stream.LocalizedForced = _localization.GetLocalizedString("Forced");
}
else if (string.Equals(streamInfo.CodecType, "video", StringComparison.OrdinalIgnoreCase))
{
diff --git a/MediaBrowser.Model/Channels/ChannelFeatures.cs b/MediaBrowser.Model/Channels/ChannelFeatures.cs
index a55754eddc..d925b78b6d 100644
--- a/MediaBrowser.Model/Channels/ChannelFeatures.cs
+++ b/MediaBrowser.Model/Channels/ChannelFeatures.cs
@@ -7,6 +7,13 @@ namespace MediaBrowser.Model.Channels
{
public class ChannelFeatures
{
+ public ChannelFeatures()
+ {
+ MediaTypes = Array.Empty();
+ ContentTypes = Array.Empty();
+ DefaultSortFields = Array.Empty();
+ }
+
///
/// Gets or sets the name.
///
@@ -38,7 +45,7 @@ namespace MediaBrowser.Model.Channels
public ChannelMediaContentType[] ContentTypes { get; set; }
///
- /// Represents the maximum number of records the channel allows retrieving at a time.
+ /// Gets or sets the maximum number of records the channel allows retrieving at a time.
///
public int? MaxPageSize { get; set; }
@@ -55,7 +62,7 @@ namespace MediaBrowser.Model.Channels
public ChannelItemSortField[] DefaultSortFields { get; set; }
///
- /// Indicates if a sort ascending/descending toggle is supported or not.
+ /// Gets or sets a value indicating whether a sort ascending/descending toggle is supported.
///
public bool SupportsSortOrderToggle { get; set; }
@@ -76,12 +83,5 @@ namespace MediaBrowser.Model.Channels
///
/// true if [supports content downloading]; otherwise, false.
public bool SupportsContentDownloading { get; set; }
-
- public ChannelFeatures()
- {
- MediaTypes = Array.Empty();
- ContentTypes = Array.Empty();
- DefaultSortFields = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Channels/ChannelQuery.cs b/MediaBrowser.Model/Channels/ChannelQuery.cs
index fd90e7f062..59966127fb 100644
--- a/MediaBrowser.Model/Channels/ChannelQuery.cs
+++ b/MediaBrowser.Model/Channels/ChannelQuery.cs
@@ -10,7 +10,7 @@ namespace MediaBrowser.Model.Channels
public class ChannelQuery
{
///
- /// Fields to return within the items, in addition to basic information.
+ /// Gets or sets the fields to return within the items, in addition to basic information.
///
/// The fields.
public ItemFields[] Fields { get; set; }
@@ -28,13 +28,13 @@ namespace MediaBrowser.Model.Channels
public Guid UserId { get; set; }
///
- /// Skips over a given number of items within the results. Use for paging.
+ /// Gets or sets the start index. Use for paging.
///
/// The start index.
public int? StartIndex { get; set; }
///
- /// The maximum number of items to return.
+ /// Gets or sets the maximum number of items to return.
///
/// The limit.
public int? Limit { get; set; }
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs
index da467e133f..a9b2803017 100644
--- a/MediaBrowser.Model/Configuration/EncodingOptions.cs
+++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs
@@ -5,6 +5,41 @@ namespace MediaBrowser.Model.Configuration
{
public class EncodingOptions
{
+ public EncodingOptions()
+ {
+ EnableFallbackFont = false;
+ DownMixAudioBoost = 2;
+ MaxMuxingQueueSize = 2048;
+ EnableThrottling = false;
+ ThrottleDelaySeconds = 180;
+ EncodingThreadCount = -1;
+ // This is a DRM device that is almost guaranteed to be there on every intel platform,
+ // plus it's the default one in ffmpeg if you don't specify anything
+ VaapiDevice = "/dev/dri/renderD128";
+ // This is the OpenCL device that is used for tonemapping.
+ // The left side of the dot is the platform number, and the right side is the device number on the platform.
+ OpenclDevice = "0.0";
+ EnableTonemapping = false;
+ EnableVppTonemapping = false;
+ TonemappingAlgorithm = "hable";
+ TonemappingRange = "auto";
+ TonemappingDesat = 0;
+ TonemappingThreshold = 0.8;
+ TonemappingPeak = 100;
+ TonemappingParam = 0;
+ H264Crf = 23;
+ H265Crf = 28;
+ DeinterlaceDoubleRate = false;
+ DeinterlaceMethod = "yadif";
+ EnableDecodingColorDepth10Hevc = true;
+ EnableDecodingColorDepth10Vp9 = true;
+ EnableEnhancedNvdecDecoder = true;
+ EnableHardwareEncoding = true;
+ AllowHevcEncoding = true;
+ EnableSubtitleExtraction = true;
+ HardwareDecodingCodecs = new string[] { "h264", "vc1" };
+ }
+
public int EncodingThreadCount { get; set; }
public string TranscodingTempPath { get; set; }
@@ -24,12 +59,12 @@ namespace MediaBrowser.Model.Configuration
public string HardwareAccelerationType { get; set; }
///
- /// FFmpeg path as set by the user via the UI.
+ /// Gets or sets the FFmpeg path as set by the user via the UI.
///
public string EncoderAppPath { get; set; }
///
- /// The current FFmpeg path being used by the system and displayed on the transcode page.
+ /// Gets or sets the current FFmpeg path being used by the system and displayed on the transcode page.
///
public string EncoderAppPathDisplay { get; set; }
@@ -76,40 +111,5 @@ namespace MediaBrowser.Model.Configuration
public bool EnableSubtitleExtraction { get; set; }
public string[] HardwareDecodingCodecs { get; set; }
-
- public EncodingOptions()
- {
- EnableFallbackFont = false;
- DownMixAudioBoost = 2;
- MaxMuxingQueueSize = 2048;
- EnableThrottling = false;
- ThrottleDelaySeconds = 180;
- EncodingThreadCount = -1;
- // This is a DRM device that is almost guaranteed to be there on every intel platform,
- // plus it's the default one in ffmpeg if you don't specify anything
- VaapiDevice = "/dev/dri/renderD128";
- // This is the OpenCL device that is used for tonemapping.
- // The left side of the dot is the platform number, and the right side is the device number on the platform.
- OpenclDevice = "0.0";
- EnableTonemapping = false;
- EnableVppTonemapping = false;
- TonemappingAlgorithm = "hable";
- TonemappingRange = "auto";
- TonemappingDesat = 0;
- TonemappingThreshold = 0.8;
- TonemappingPeak = 100;
- TonemappingParam = 0;
- H264Crf = 23;
- H265Crf = 28;
- DeinterlaceDoubleRate = false;
- DeinterlaceMethod = "yadif";
- EnableDecodingColorDepth10Hevc = true;
- EnableDecodingColorDepth10Vp9 = true;
- EnableEnhancedNvdecDecoder = true;
- EnableHardwareEncoding = true;
- AllowHevcEncoding = true;
- EnableSubtitleExtraction = true;
- HardwareDecodingCodecs = new string[] { "h264", "vc1" };
- }
}
}
diff --git a/MediaBrowser.Model/Configuration/ImageOption.cs b/MediaBrowser.Model/Configuration/ImageOption.cs
index 2b1268c743..0af7b7e146 100644
--- a/MediaBrowser.Model/Configuration/ImageOption.cs
+++ b/MediaBrowser.Model/Configuration/ImageOption.cs
@@ -6,6 +6,11 @@ namespace MediaBrowser.Model.Configuration
{
public class ImageOption
{
+ public ImageOption()
+ {
+ Limit = 1;
+ }
+
///
/// Gets or sets the type.
///
@@ -23,10 +28,5 @@ namespace MediaBrowser.Model.Configuration
///
/// The minimum width.
public int MinWidth { get; set; }
-
- public ImageOption()
- {
- Limit = 1;
- }
}
}
diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs
index 77ac11d69f..24698360ec 100644
--- a/MediaBrowser.Model/Configuration/LibraryOptions.cs
+++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs
@@ -2,13 +2,30 @@
#pragma warning disable CS1591
using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Configuration
{
public class LibraryOptions
{
+ public LibraryOptions()
+ {
+ TypeOptions = Array.Empty();
+ DisabledSubtitleFetchers = Array.Empty();
+ SubtitleFetcherOrder = Array.Empty();
+ DisabledLocalMetadataReaders = Array.Empty();
+
+ SkipSubtitlesIfAudioTrackMatches = true;
+ RequirePerfectSubtitleMatch = true;
+
+ EnablePhotos = true;
+ SaveSubtitlesWithMedia = true;
+ EnableRealtimeMonitor = true;
+ PathInfos = Array.Empty();
+ EnableInternetProviders = true;
+ EnableAutomaticSeriesGrouping = true;
+ SeasonZeroDisplayName = "Specials";
+ }
+
public bool EnablePhotos { get; set; }
public bool EnableRealtimeMonitor { get; set; }
@@ -79,387 +96,5 @@ namespace MediaBrowser.Model.Configuration
return null;
}
-
- public LibraryOptions()
- {
- TypeOptions = Array.Empty();
- DisabledSubtitleFetchers = Array.Empty();
- SubtitleFetcherOrder = Array.Empty();
- DisabledLocalMetadataReaders = Array.Empty();
-
- SkipSubtitlesIfAudioTrackMatches = true;
- RequirePerfectSubtitleMatch = true;
-
- EnablePhotos = true;
- SaveSubtitlesWithMedia = true;
- EnableRealtimeMonitor = true;
- PathInfos = Array.Empty();
- EnableInternetProviders = true;
- EnableAutomaticSeriesGrouping = true;
- SeasonZeroDisplayName = "Specials";
- }
- }
-
- public class MediaPathInfo
- {
- public string Path { get; set; }
-
- public string NetworkPath { get; set; }
- }
-
- public class TypeOptions
- {
- public string Type { get; set; }
-
- public string[] MetadataFetchers { get; set; }
-
- public string[] MetadataFetcherOrder { get; set; }
-
- public string[] ImageFetchers { get; set; }
-
- public string[] ImageFetcherOrder { get; set; }
-
- public ImageOption[] ImageOptions { get; set; }
-
- public ImageOption GetImageOptions(ImageType type)
- {
- foreach (var i in ImageOptions)
- {
- if (i.Type == type)
- {
- return i;
- }
- }
-
- if (DefaultImageOptions.TryGetValue(Type, out ImageOption[] options))
- {
- foreach (var i in options)
- {
- if (i.Type == type)
- {
- return i;
- }
- }
- }
-
- return DefaultInstance;
- }
-
- public int GetLimit(ImageType type)
- {
- return GetImageOptions(type).Limit;
- }
-
- public int GetMinWidth(ImageType type)
- {
- return GetImageOptions(type).MinWidth;
- }
-
- public bool IsEnabled(ImageType type)
- {
- return GetLimit(type) > 0;
- }
-
- public TypeOptions()
- {
- MetadataFetchers = Array.Empty();
- MetadataFetcherOrder = Array.Empty();
- ImageFetchers = Array.Empty();
- ImageFetcherOrder = Array.Empty();
- ImageOptions = Array.Empty();
- }
-
- public static Dictionary DefaultImageOptions = new Dictionary
- {
- {
- "Movie", new []
- {
- new ImageOption
- {
- Limit = 1,
- MinWidth = 1280,
- Type = ImageType.Backdrop
- },
-
- // Don't download this by default as it's rarely used.
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Art
- },
-
- // Don't download this by default as it's rarely used.
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Disc
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Primary
- },
-
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Banner
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Thumb
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Logo
- }
- }
- },
- {
- "MusicVideo", new []
- {
- new ImageOption
- {
- Limit = 1,
- MinWidth = 1280,
- Type = ImageType.Backdrop
- },
-
- // Don't download this by default as it's rarely used.
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Art
- },
-
- // Don't download this by default as it's rarely used.
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Disc
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Primary
- },
-
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Banner
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Thumb
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Logo
- }
- }
- },
- {
- "Series", new []
- {
- new ImageOption
- {
- Limit = 1,
- MinWidth = 1280,
- Type = ImageType.Backdrop
- },
-
- // Don't download this by default as it's rarely used.
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Art
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Primary
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Banner
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Thumb
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Logo
- }
- }
- },
- {
- "MusicAlbum", new []
- {
- new ImageOption
- {
- Limit = 0,
- MinWidth = 1280,
- Type = ImageType.Backdrop
- },
-
- // Don't download this by default as it's rarely used.
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Disc
- }
- }
- },
- {
- "MusicArtist", new []
- {
- new ImageOption
- {
- Limit = 1,
- MinWidth = 1280,
- Type = ImageType.Backdrop
- },
-
- // Don't download this by default
- // They do look great, but most artists won't have them, which means a banner view isn't really possible
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Banner
- },
-
- // Don't download this by default
- // Generally not used
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Art
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Logo
- }
- }
- },
- {
- "BoxSet", new []
- {
- new ImageOption
- {
- Limit = 1,
- MinWidth = 1280,
- Type = ImageType.Backdrop
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Primary
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Thumb
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Logo
- },
-
- // Don't download this by default as it's rarely used.
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Art
- },
-
- // Don't download this by default as it's rarely used.
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Disc
- },
-
- // Don't download this by default as it's rarely used.
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Banner
- }
- }
- },
- {
- "Season", new []
- {
- new ImageOption
- {
- Limit = 0,
- MinWidth = 1280,
- Type = ImageType.Backdrop
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Primary
- },
-
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Banner
- },
-
- new ImageOption
- {
- Limit = 0,
- Type = ImageType.Thumb
- }
- }
- },
- {
- "Episode", new []
- {
- new ImageOption
- {
- Limit = 0,
- MinWidth = 1280,
- Type = ImageType.Backdrop
- },
-
- new ImageOption
- {
- Limit = 1,
- Type = ImageType.Primary
- }
- }
- }
- };
-
- public static ImageOption DefaultInstance = new ImageOption();
}
}
diff --git a/MediaBrowser.Model/Configuration/MediaPathInfo.cs b/MediaBrowser.Model/Configuration/MediaPathInfo.cs
new file mode 100644
index 0000000000..4f311c58f0
--- /dev/null
+++ b/MediaBrowser.Model/Configuration/MediaPathInfo.cs
@@ -0,0 +1,12 @@
+#nullable disable
+#pragma warning disable CS1591
+
+namespace MediaBrowser.Model.Configuration
+{
+ public class MediaPathInfo
+ {
+ public string Path { get; set; }
+
+ public string NetworkPath { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Configuration/MetadataConfiguration.cs b/MediaBrowser.Model/Configuration/MetadataConfiguration.cs
index 706831bddc..be044243dd 100644
--- a/MediaBrowser.Model/Configuration/MetadataConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/MetadataConfiguration.cs
@@ -4,11 +4,11 @@ namespace MediaBrowser.Model.Configuration
{
public class MetadataConfiguration
{
- public bool UseFileCreationTimeForDateAdded { get; set; }
-
public MetadataConfiguration()
{
UseFileCreationTimeForDateAdded = true;
}
+
+ public bool UseFileCreationTimeForDateAdded { get; set; }
}
}
diff --git a/MediaBrowser.Model/Configuration/MetadataOptions.cs b/MediaBrowser.Model/Configuration/MetadataOptions.cs
index e7dc3da3cb..76b72bd08e 100644
--- a/MediaBrowser.Model/Configuration/MetadataOptions.cs
+++ b/MediaBrowser.Model/Configuration/MetadataOptions.cs
@@ -10,6 +10,16 @@ namespace MediaBrowser.Model.Configuration
///
public class MetadataOptions
{
+ public MetadataOptions()
+ {
+ DisabledMetadataSavers = Array.Empty();
+ LocalMetadataReaderOrder = Array.Empty();
+ DisabledMetadataFetchers = Array.Empty();
+ MetadataFetcherOrder = Array.Empty();
+ DisabledImageFetchers = Array.Empty();
+ ImageFetcherOrder = Array.Empty();
+ }
+
public string ItemType { get; set; }
public string[] DisabledMetadataSavers { get; set; }
@@ -23,15 +33,5 @@ namespace MediaBrowser.Model.Configuration
public string[] DisabledImageFetchers { get; set; }
public string[] ImageFetcherOrder { get; set; }
-
- public MetadataOptions()
- {
- DisabledMetadataSavers = Array.Empty();
- LocalMetadataReaderOrder = Array.Empty();
- DisabledMetadataFetchers = Array.Empty();
- MetadataFetcherOrder = Array.Empty();
- DisabledImageFetchers = Array.Empty();
- ImageFetcherOrder = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Configuration/MetadataPluginSummary.cs b/MediaBrowser.Model/Configuration/MetadataPluginSummary.cs
index 0c197ee021..aa07d66237 100644
--- a/MediaBrowser.Model/Configuration/MetadataPluginSummary.cs
+++ b/MediaBrowser.Model/Configuration/MetadataPluginSummary.cs
@@ -8,6 +8,12 @@ namespace MediaBrowser.Model.Configuration
{
public class MetadataPluginSummary
{
+ public MetadataPluginSummary()
+ {
+ SupportedImageTypes = Array.Empty();
+ Plugins = Array.Empty();
+ }
+
///
/// Gets or sets the type of the item.
///
@@ -25,11 +31,5 @@ namespace MediaBrowser.Model.Configuration
///
/// The supported image types.
public ImageType[] SupportedImageTypes { get; set; }
-
- public MetadataPluginSummary()
- {
- SupportedImageTypes = Array.Empty();
- Plugins = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Configuration/TypeOptions.cs b/MediaBrowser.Model/Configuration/TypeOptions.cs
new file mode 100644
index 0000000000..d0179e5aab
--- /dev/null
+++ b/MediaBrowser.Model/Configuration/TypeOptions.cs
@@ -0,0 +1,365 @@
+#nullable disable
+#pragma warning disable CS1591
+
+using System;
+using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
+
+namespace MediaBrowser.Model.Configuration
+{
+ public class TypeOptions
+ {
+ public static readonly ImageOption DefaultInstance = new ImageOption();
+
+ public static readonly Dictionary DefaultImageOptions = new Dictionary
+ {
+ {
+ "Movie", new[]
+ {
+ new ImageOption
+ {
+ Limit = 1,
+ MinWidth = 1280,
+ Type = ImageType.Backdrop
+ },
+
+ // Don't download this by default as it's rarely used.
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Art
+ },
+
+ // Don't download this by default as it's rarely used.
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Disc
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Primary
+ },
+
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Banner
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Thumb
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Logo
+ }
+ }
+ },
+ {
+ "MusicVideo", new[]
+ {
+ new ImageOption
+ {
+ Limit = 1,
+ MinWidth = 1280,
+ Type = ImageType.Backdrop
+ },
+
+ // Don't download this by default as it's rarely used.
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Art
+ },
+
+ // Don't download this by default as it's rarely used.
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Disc
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Primary
+ },
+
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Banner
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Thumb
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Logo
+ }
+ }
+ },
+ {
+ "Series", new[]
+ {
+ new ImageOption
+ {
+ Limit = 1,
+ MinWidth = 1280,
+ Type = ImageType.Backdrop
+ },
+
+ // Don't download this by default as it's rarely used.
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Art
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Primary
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Banner
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Thumb
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Logo
+ }
+ }
+ },
+ {
+ "MusicAlbum", new[]
+ {
+ new ImageOption
+ {
+ Limit = 0,
+ MinWidth = 1280,
+ Type = ImageType.Backdrop
+ },
+
+ // Don't download this by default as it's rarely used.
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Disc
+ }
+ }
+ },
+ {
+ "MusicArtist", new[]
+ {
+ new ImageOption
+ {
+ Limit = 1,
+ MinWidth = 1280,
+ Type = ImageType.Backdrop
+ },
+
+ // Don't download this by default
+ // They do look great, but most artists won't have them, which means a banner view isn't really possible
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Banner
+ },
+
+ // Don't download this by default
+ // Generally not used
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Art
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Logo
+ }
+ }
+ },
+ {
+ "BoxSet", new[]
+ {
+ new ImageOption
+ {
+ Limit = 1,
+ MinWidth = 1280,
+ Type = ImageType.Backdrop
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Primary
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Thumb
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Logo
+ },
+
+ // Don't download this by default as it's rarely used.
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Art
+ },
+
+ // Don't download this by default as it's rarely used.
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Disc
+ },
+
+ // Don't download this by default as it's rarely used.
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Banner
+ }
+ }
+ },
+ {
+ "Season", new[]
+ {
+ new ImageOption
+ {
+ Limit = 0,
+ MinWidth = 1280,
+ Type = ImageType.Backdrop
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Primary
+ },
+
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Banner
+ },
+
+ new ImageOption
+ {
+ Limit = 0,
+ Type = ImageType.Thumb
+ }
+ }
+ },
+ {
+ "Episode", new[]
+ {
+ new ImageOption
+ {
+ Limit = 0,
+ MinWidth = 1280,
+ Type = ImageType.Backdrop
+ },
+
+ new ImageOption
+ {
+ Limit = 1,
+ Type = ImageType.Primary
+ }
+ }
+ }
+ };
+
+ public TypeOptions()
+ {
+ MetadataFetchers = Array.Empty();
+ MetadataFetcherOrder = Array.Empty();
+ ImageFetchers = Array.Empty();
+ ImageFetcherOrder = Array.Empty();
+ ImageOptions = Array.Empty();
+ }
+
+ public string Type { get; set; }
+
+ public string[] MetadataFetchers { get; set; }
+
+ public string[] MetadataFetcherOrder { get; set; }
+
+ public string[] ImageFetchers { get; set; }
+
+ public string[] ImageFetcherOrder { get; set; }
+
+ public ImageOption[] ImageOptions { get; set; }
+
+ public ImageOption GetImageOptions(ImageType type)
+ {
+ foreach (var i in ImageOptions)
+ {
+ if (i.Type == type)
+ {
+ return i;
+ }
+ }
+
+ if (DefaultImageOptions.TryGetValue(Type, out ImageOption[] options))
+ {
+ foreach (var i in options)
+ {
+ if (i.Type == type)
+ {
+ return i;
+ }
+ }
+ }
+
+ return DefaultInstance;
+ }
+
+ public int GetLimit(ImageType type)
+ {
+ return GetImageOptions(type).Limit;
+ }
+
+ public int GetMinWidth(ImageType type)
+ {
+ return GetImageOptions(type).MinWidth;
+ }
+
+ public bool IsEnabled(ImageType type)
+ {
+ return GetLimit(type) > 0;
+ }
+ }
+}
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index cc0e0c4681..935e6cbe10 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -11,6 +11,24 @@ namespace MediaBrowser.Model.Configuration
///
public class UserConfiguration
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public UserConfiguration()
+ {
+ EnableNextEpisodeAutoPlay = true;
+ RememberAudioSelections = true;
+ RememberSubtitleSelections = true;
+
+ HidePlayedInLatest = true;
+ PlayDefaultAudioTrack = true;
+
+ LatestItemsExcludes = Array.Empty();
+ OrderedViews = Array.Empty();
+ MyMediaExcludes = Array.Empty();
+ GroupedFolders = Array.Empty();
+ }
+
///
/// Gets or sets the audio language preference.
///
@@ -52,23 +70,5 @@ namespace MediaBrowser.Model.Configuration
public bool RememberSubtitleSelections { get; set; }
public bool EnableNextEpisodeAutoPlay { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public UserConfiguration()
- {
- EnableNextEpisodeAutoPlay = true;
- RememberAudioSelections = true;
- RememberSubtitleSelections = true;
-
- HidePlayedInLatest = true;
- PlayDefaultAudioTrack = true;
-
- LatestItemsExcludes = Array.Empty();
- OrderedViews = Array.Empty();
- MyMediaExcludes = Array.Empty();
- GroupedFolders = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs b/MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs
index 4d5f996f84..8ad070dcbf 100644
--- a/MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs
+++ b/MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs
@@ -5,6 +5,14 @@ namespace MediaBrowser.Model.Configuration
{
public class XbmcMetadataOptions
{
+ public XbmcMetadataOptions()
+ {
+ ReleaseDateFormat = "yyyy-MM-dd";
+
+ SaveImagePathsInNfo = true;
+ EnablePathSubstitution = true;
+ }
+
public string UserId { get; set; }
public string ReleaseDateFormat { get; set; }
@@ -14,13 +22,5 @@ namespace MediaBrowser.Model.Configuration
public bool EnablePathSubstitution { get; set; }
public bool EnableExtraThumbsDuplication { get; set; }
-
- public XbmcMetadataOptions()
- {
- ReleaseDateFormat = "yyyy-MM-dd";
-
- SaveImagePathsInNfo = true;
- EnablePathSubstitution = true;
- }
}
}
diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs
index bbb8bf4263..4d4d8d78cb 100644
--- a/MediaBrowser.Model/Dlna/AudioOptions.cs
+++ b/MediaBrowser.Model/Dlna/AudioOptions.cs
@@ -34,20 +34,20 @@ namespace MediaBrowser.Model.Dlna
public DeviceProfile Profile { get; set; }
///
- /// Optional. Only needed if a specific AudioStreamIndex or SubtitleStreamIndex are requested.
+ /// Gets or sets a media source id. Optional. Only needed if a specific AudioStreamIndex or SubtitleStreamIndex are requested.
///
public string MediaSourceId { get; set; }
public string DeviceId { get; set; }
///
- /// Allows an override of supported number of audio channels
- /// Example: DeviceProfile supports five channel, but user only has stereo speakers
+ /// Gets or sets an override of supported number of audio channels
+ /// Example: DeviceProfile supports five channel, but user only has stereo speakers.
///
public int? MaxAudioChannels { get; set; }
///
- /// The application's configured quality setting.
+ /// Gets or sets the application's configured quality setting.
///
public int? MaxBitrate { get; set; }
@@ -66,6 +66,7 @@ namespace MediaBrowser.Model.Dlna
///
/// Gets the maximum bitrate.
///
+ /// Whether or not this is audio.
/// System.Nullable<System.Int32>.
public int? GetMaxBitrate(bool isAudio)
{
diff --git a/MediaBrowser.Model/Dlna/CodecProfile.cs b/MediaBrowser.Model/Dlna/CodecProfile.cs
index d4fd3e6730..8343cf028b 100644
--- a/MediaBrowser.Model/Dlna/CodecProfile.cs
+++ b/MediaBrowser.Model/Dlna/CodecProfile.cs
@@ -9,6 +9,12 @@ namespace MediaBrowser.Model.Dlna
{
public class CodecProfile
{
+ public CodecProfile()
+ {
+ Conditions = Array.Empty();
+ ApplyConditions = Array.Empty();
+ }
+
[XmlAttribute("type")]
public CodecType Type { get; set; }
@@ -22,12 +28,6 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("container")]
public string Container { get; set; }
- public CodecProfile()
- {
- Conditions = Array.Empty();
- ApplyConditions = Array.Empty();
- }
-
public string[] GetCodecs()
{
return ContainerProfile.SplitValue(Codec);
diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs
index faf1ee41be..55c4dd0742 100644
--- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs
+++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs
@@ -1,8 +1,8 @@
#pragma warning disable CS1591
using System;
-using System.Linq;
using System.Globalization;
+using System.Linq;
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Model.Dlna
diff --git a/MediaBrowser.Model/Dlna/ContainerProfile.cs b/MediaBrowser.Model/Dlna/ContainerProfile.cs
index 56c89d854f..d83c8f2f3c 100644
--- a/MediaBrowser.Model/Dlna/ContainerProfile.cs
+++ b/MediaBrowser.Model/Dlna/ContainerProfile.cs
@@ -9,6 +9,11 @@ namespace MediaBrowser.Model.Dlna
{
public class ContainerProfile
{
+ public ContainerProfile()
+ {
+ Conditions = Array.Empty();
+ }
+
[XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
@@ -17,11 +22,6 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("container")]
public string Container { get; set; }
- public ContainerProfile()
- {
- Conditions = Array.Empty();
- }
-
public string[] GetContainers()
{
return SplitValue(Container);
diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
index 50e3374f77..ec106f1054 100644
--- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
+++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
@@ -81,13 +81,13 @@ namespace MediaBrowser.Model.Dlna
DlnaFlags.DlnaV15;
// if (isDirectStream)
- //{
- // flagValue = flagValue | DlnaFlags.ByteBasedSeek;
- //}
- // else if (runtimeTicks.HasValue)
- //{
- // flagValue = flagValue | DlnaFlags.TimeBasedSeek;
- //}
+ // {
+ // flagValue = flagValue | DlnaFlags.ByteBasedSeek;
+ // }
+ // else if (runtimeTicks.HasValue)
+ // {
+ // flagValue = flagValue | DlnaFlags.TimeBasedSeek;
+ // }
string dlnaflags = string.Format(
CultureInfo.InvariantCulture,
@@ -150,16 +150,18 @@ namespace MediaBrowser.Model.Dlna
DlnaFlags.DlnaV15;
// if (isDirectStream)
- //{
- // flagValue = flagValue | DlnaFlags.ByteBasedSeek;
- //}
- // else if (runtimeTicks.HasValue)
- //{
- // flagValue = flagValue | DlnaFlags.TimeBasedSeek;
- //}
-
- string dlnaflags = string.Format(CultureInfo.InvariantCulture, ";DLNA.ORG_FLAGS={0}",
- DlnaMaps.FlagsToString(flagValue));
+ // {
+ // flagValue = flagValue | DlnaFlags.ByteBasedSeek;
+ // }
+ // else if (runtimeTicks.HasValue)
+ // {
+ // flagValue = flagValue | DlnaFlags.TimeBasedSeek;
+ // }
+
+ string dlnaflags = string.Format(
+ CultureInfo.InvariantCulture,
+ ";DLNA.ORG_FLAGS={0}",
+ DlnaMaps.FlagsToString(flagValue));
ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(
container,
diff --git a/MediaBrowser.Model/Dlna/IDeviceDiscovery.cs b/MediaBrowser.Model/Dlna/IDeviceDiscovery.cs
index 05209e53d0..086088deae 100644
--- a/MediaBrowser.Model/Dlna/IDeviceDiscovery.cs
+++ b/MediaBrowser.Model/Dlna/IDeviceDiscovery.cs
@@ -8,6 +8,7 @@ namespace MediaBrowser.Model.Dlna
public interface IDeviceDiscovery
{
event EventHandler> DeviceDiscovered;
+
event EventHandler> DeviceLeft;
}
}
diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
index 3c955989a1..f61b8d59e8 100644
--- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
+++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
@@ -57,7 +57,6 @@ namespace MediaBrowser.Model.Dlna
string.Equals(container, "mpegts", StringComparison.OrdinalIgnoreCase) ||
string.Equals(container, "m2ts", StringComparison.OrdinalIgnoreCase))
{
-
return ResolveVideoMPEG2TSFormat(videoCodec, audioCodec, width, height, timestampType);
}
@@ -323,7 +322,6 @@ namespace MediaBrowser.Model.Dlna
if (string.Equals(videoCodec, "wmv", StringComparison.OrdinalIgnoreCase) &&
(string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "wma", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "wmapro", StringComparison.OrdinalIgnoreCase)))
{
-
if (width.HasValue && height.HasValue)
{
if ((width.Value <= 720) && (height.Value <= 576))
@@ -479,7 +477,9 @@ namespace MediaBrowser.Model.Dlna
{
if (string.Equals(container, "jpeg", StringComparison.OrdinalIgnoreCase) ||
string.Equals(container, "jpg", StringComparison.OrdinalIgnoreCase))
+ {
return ResolveImageJPGFormat(width, height);
+ }
if (string.Equals(container, "png", StringComparison.OrdinalIgnoreCase))
{
diff --git a/MediaBrowser.Model/Dlna/ResolutionConfiguration.cs b/MediaBrowser.Model/Dlna/ResolutionConfiguration.cs
index 30c44fbe0e..f8f76c69d8 100644
--- a/MediaBrowser.Model/Dlna/ResolutionConfiguration.cs
+++ b/MediaBrowser.Model/Dlna/ResolutionConfiguration.cs
@@ -4,14 +4,14 @@ namespace MediaBrowser.Model.Dlna
{
public class ResolutionConfiguration
{
- public int MaxWidth { get; set; }
-
- public int MaxBitrate { get; set; }
-
public ResolutionConfiguration(int maxWidth, int maxBitrate)
{
MaxWidth = maxWidth;
MaxBitrate = maxBitrate;
}
+
+ public int MaxWidth { get; set; }
+
+ public int MaxBitrate { get; set; }
}
}
diff --git a/MediaBrowser.Model/Dlna/ResponseProfile.cs b/MediaBrowser.Model/Dlna/ResponseProfile.cs
index 48f53f06c2..bf9661f7f3 100644
--- a/MediaBrowser.Model/Dlna/ResponseProfile.cs
+++ b/MediaBrowser.Model/Dlna/ResponseProfile.cs
@@ -8,6 +8,11 @@ namespace MediaBrowser.Model.Dlna
{
public class ResponseProfile
{
+ public ResponseProfile()
+ {
+ Conditions = Array.Empty();
+ }
+
[XmlAttribute("container")]
public string Container { get; set; }
@@ -28,11 +33,6 @@ namespace MediaBrowser.Model.Dlna
public ProfileCondition[] Conditions { get; set; }
- public ResponseProfile()
- {
- Conditions = Array.Empty();
- }
-
public string[] GetContainers()
{
return ContainerProfile.SplitValue(Container);
diff --git a/MediaBrowser.Model/Dlna/SearchCriteria.cs b/MediaBrowser.Model/Dlna/SearchCriteria.cs
index 94f5bd3dbe..b1fc48c087 100644
--- a/MediaBrowser.Model/Dlna/SearchCriteria.cs
+++ b/MediaBrowser.Model/Dlna/SearchCriteria.cs
@@ -7,31 +7,6 @@ namespace MediaBrowser.Model.Dlna
{
public class SearchCriteria
{
- public SearchType SearchType { get; set; }
-
- ///
- /// Splits the specified string.
- ///
- /// The string.
- /// The term.
- /// The limit.
- /// System.String[].
- private static string[] RegexSplit(string str, string term, int limit)
- {
- return new Regex(term).Split(str, limit);
- }
-
- ///
- /// Splits the specified string.
- ///
- /// The string.
- /// The term.
- /// System.String[].
- private static string[] RegexSplit(string str, string term)
- {
- return Regex.Split(str, term, RegexOptions.IgnoreCase);
- }
-
public SearchCriteria(string search)
{
if (search.Length == 0)
@@ -48,8 +23,8 @@ namespace MediaBrowser.Model.Dlna
if (subFactors.Length == 3)
{
- if (string.Equals("upnp:class", subFactors[0], StringComparison.OrdinalIgnoreCase) &&
- (string.Equals("=", subFactors[1], StringComparison.Ordinal) || string.Equals("derivedfrom", subFactors[1], StringComparison.OrdinalIgnoreCase)))
+ if (string.Equals("upnp:class", subFactors[0], StringComparison.OrdinalIgnoreCase)
+ && (string.Equals("=", subFactors[1], StringComparison.Ordinal) || string.Equals("derivedfrom", subFactors[1], StringComparison.OrdinalIgnoreCase)))
{
if (string.Equals("\"object.item.imageItem\"", subFactors[2], StringComparison.Ordinal) || string.Equals("\"object.item.imageItem.photo\"", subFactors[2], StringComparison.OrdinalIgnoreCase))
{
@@ -71,5 +46,30 @@ namespace MediaBrowser.Model.Dlna
}
}
}
+
+ public SearchType SearchType { get; set; }
+
+ ///
+ /// Splits the specified string.
+ ///
+ /// The string.
+ /// The term.
+ /// The limit.
+ /// System.String[].
+ private static string[] RegexSplit(string str, string term, int limit)
+ {
+ return new Regex(term).Split(str, limit);
+ }
+
+ ///
+ /// Splits the specified string.
+ ///
+ /// The string.
+ /// The term.
+ /// System.String[].
+ private static string[] RegexSplit(string str, string term)
+ {
+ return Regex.Split(str, term, RegexOptions.IgnoreCase);
+ }
}
}
diff --git a/MediaBrowser.Model/Dlna/SortCriteria.cs b/MediaBrowser.Model/Dlna/SortCriteria.cs
index 53e4540cbb..7769d0bd3e 100644
--- a/MediaBrowser.Model/Dlna/SortCriteria.cs
+++ b/MediaBrowser.Model/Dlna/SortCriteria.cs
@@ -6,10 +6,10 @@ namespace MediaBrowser.Model.Dlna
{
public class SortCriteria
{
- public SortOrder SortOrder => SortOrder.Ascending;
-
public SortCriteria(string value)
{
}
+
+ public SortOrder SortOrder => SortOrder.Ascending;
}
}
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index a3983afe5f..bf33691c77 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -227,7 +227,7 @@ namespace MediaBrowser.Model.Dlna
}
}
- public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, string _, DeviceProfile profile, DlnaProfileType type)
+ public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, DeviceProfile profile, DlnaProfileType type)
{
if (string.IsNullOrEmpty(inputContainer))
{
@@ -274,14 +274,14 @@ namespace MediaBrowser.Model.Dlna
if (options.ForceDirectPlay)
{
playlistItem.PlayMethod = PlayMethod.DirectPlay;
- playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, item.Path, options.Profile, DlnaProfileType.Audio);
+ playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Audio);
return playlistItem;
}
if (options.ForceDirectStream)
{
playlistItem.PlayMethod = PlayMethod.DirectStream;
- playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, item.Path, options.Profile, DlnaProfileType.Audio);
+ playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Audio);
return playlistItem;
}
@@ -349,7 +349,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.PlayMethod = PlayMethod.DirectStream;
}
- playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, item.Path, options.Profile, DlnaProfileType.Audio);
+ playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Audio);
return playlistItem;
}
@@ -698,7 +698,7 @@ namespace MediaBrowser.Model.Dlna
if (directPlay != null)
{
playlistItem.PlayMethod = directPlay.Value;
- playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, item.Path, options.Profile, DlnaProfileType.Video);
+ playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Video);
if (subtitleStream != null)
{
@@ -1404,7 +1404,9 @@ namespace MediaBrowser.Model.Dlna
{
_logger.LogInformation(
"Bitrate exceeds {PlayBackMethod} limit: media bitrate: {MediaBitrate}, max bitrate: {MaxBitrate}",
- playMethod, itemBitrate, requestedMaxBitrate);
+ playMethod,
+ itemBitrate,
+ requestedMaxBitrate);
return false;
}
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 4765052d59..f7010dcd0f 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -27,45 +27,6 @@ namespace MediaBrowser.Model.Dlna
StreamOptions = new Dictionary(StringComparer.OrdinalIgnoreCase);
}
- public void SetOption(string qualifier, string name, string value)
- {
- if (string.IsNullOrEmpty(qualifier))
- {
- SetOption(name, value);
- }
- else
- {
- SetOption(qualifier + "-" + name, value);
- }
- }
-
- public void SetOption(string name, string value)
- {
- StreamOptions[name] = value;
- }
-
- public string GetOption(string qualifier, string name)
- {
- var value = GetOption(qualifier + "-" + name);
-
- if (string.IsNullOrEmpty(value))
- {
- value = GetOption(name);
- }
-
- return value;
- }
-
- public string GetOption(string name)
- {
- if (StreamOptions.TryGetValue(name, out var value))
- {
- return value;
- }
-
- return null;
- }
-
public Guid ItemId { get; set; }
public PlayMethod PlayMethod { get; set; }
@@ -152,887 +113,928 @@ namespace MediaBrowser.Model.Dlna
PlayMethod == PlayMethod.DirectStream ||
PlayMethod == PlayMethod.DirectPlay;
- public string ToUrl(string baseUrl, string accessToken)
+ ///
+ /// Gets the audio stream that will be used.
+ ///
+ public MediaStream TargetAudioStream
{
- if (PlayMethod == PlayMethod.DirectPlay)
+ get
{
- return MediaSource.Path;
+ if (MediaSource != null)
+ {
+ return MediaSource.GetDefaultAudioStream(AudioStreamIndex);
+ }
+
+ return null;
}
+ }
- if (string.IsNullOrEmpty(baseUrl))
+ ///
+ /// Gets the video stream that will be used.
+ ///
+ public MediaStream TargetVideoStream
+ {
+ get
{
- throw new ArgumentNullException(nameof(baseUrl));
+ if (MediaSource != null)
+ {
+ return MediaSource.VideoStream;
+ }
+
+ return null;
}
+ }
- var list = new List();
- foreach (NameValuePair pair in BuildParams(this, accessToken))
+ ///
+ /// Gets the audio sample rate that will be in the output stream.
+ ///
+ public int? TargetAudioSampleRate
+ {
+ get
{
- if (string.IsNullOrEmpty(pair.Value))
+ var stream = TargetAudioStream;
+ return AudioSampleRate.HasValue && !IsDirectStream
+ ? AudioSampleRate
+ : stream == null ? null : stream.SampleRate;
+ }
+ }
+
+ ///
+ /// Gets the audio sample rate that will be in the output stream.
+ ///
+ public int? TargetAudioBitDepth
+ {
+ get
+ {
+ if (IsDirectStream)
{
- continue;
+ return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth;
}
- // Try to keep the url clean by omitting defaults
- if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase) &&
- string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase))
+ var targetAudioCodecs = TargetAudioCodec;
+ var audioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
+ if (!string.IsNullOrEmpty(audioCodec))
{
- continue;
+ return GetTargetAudioBitDepth(audioCodec);
}
- if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase) &&
- string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase))
+ return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth;
+ }
+ }
+
+ ///
+ /// Gets the audio sample rate that will be in the output stream.
+ ///
+ public int? TargetVideoBitDepth
+ {
+ get
+ {
+ if (IsDirectStream)
{
- continue;
+ return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth;
}
- // Be careful, IsDirectStream==true by default (Static != false or not in query).
- // See initialization of StreamingRequestDto in AudioController.GetAudioStream() method : Static = @static ?? true.
- if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase) &&
- string.Equals(pair.Value, "true", StringComparison.OrdinalIgnoreCase))
+ var targetVideoCodecs = TargetVideoCodec;
+ var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
+ if (!string.IsNullOrEmpty(videoCodec))
{
- continue;
+ return GetTargetVideoBitDepth(videoCodec);
}
- var encodedValue = pair.Value.Replace(" ", "%20", StringComparison.Ordinal);
-
- list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue));
+ return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth;
}
-
- string queryString = string.Join('&', list);
-
- return GetUrl(baseUrl, queryString);
}
- private string GetUrl(string baseUrl, string queryString)
+ ///
+ /// Gets the target reference frames.
+ ///
+ /// The target reference frames.
+ public int? TargetRefFrames
{
- if (string.IsNullOrEmpty(baseUrl))
+ get
{
- throw new ArgumentNullException(nameof(baseUrl));
- }
-
- string extension = string.IsNullOrEmpty(Container) ? string.Empty : "." + Container;
-
- baseUrl = baseUrl.TrimEnd('/');
+ if (IsDirectStream)
+ {
+ return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
+ }
- if (MediaType == DlnaProfileType.Audio)
- {
- if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
+ var targetVideoCodecs = TargetVideoCodec;
+ var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
+ if (!string.IsNullOrEmpty(videoCodec))
{
- return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
+ return GetTargetRefFrames(videoCodec);
}
- return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
+ return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
}
+ }
- if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
+ ///
+ /// Gets the audio sample rate that will be in the output stream.
+ ///
+ public float? TargetFramerate
+ {
+ get
{
- return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
+ var stream = TargetVideoStream;
+ return MaxFramerate.HasValue && !IsDirectStream
+ ? MaxFramerate
+ : stream == null ? null : stream.AverageFrameRate ?? stream.RealFrameRate;
}
-
- return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
}
- private static List BuildParams(StreamInfo item, string accessToken)
+ ///
+ /// Gets the audio sample rate that will be in the output stream.
+ ///
+ public double? TargetVideoLevel
{
- var list = new List();
-
- string audioCodecs = item.AudioCodecs.Length == 0 ?
- string.Empty :
- string.Join(',', item.AudioCodecs);
-
- string videoCodecs = item.VideoCodecs.Length == 0 ?
- string.Empty :
- string.Join(',', item.VideoCodecs);
-
- list.Add(new NameValuePair("DeviceProfileId", item.DeviceProfileId ?? string.Empty));
- list.Add(new NameValuePair("DeviceId", item.DeviceId ?? string.Empty));
- list.Add(new NameValuePair("MediaSourceId", item.MediaSourceId ?? string.Empty));
- list.Add(new NameValuePair("Static", item.IsDirectStream.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
- list.Add(new NameValuePair("VideoCodec", videoCodecs));
- list.Add(new NameValuePair("AudioCodec", audioCodecs));
- list.Add(new NameValuePair("AudioStreamIndex", item.AudioStreamIndex.HasValue ? item.AudioStreamIndex.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
- list.Add(new NameValuePair("SubtitleStreamIndex", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleStreamIndex.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
- list.Add(new NameValuePair("VideoBitrate", item.VideoBitrate.HasValue ? item.VideoBitrate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
- list.Add(new NameValuePair("AudioBitrate", item.AudioBitrate.HasValue ? item.AudioBitrate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
- list.Add(new NameValuePair("AudioSampleRate", item.AudioSampleRate.HasValue ? item.AudioSampleRate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
-
- list.Add(new NameValuePair("MaxFramerate", item.MaxFramerate.HasValue ? item.MaxFramerate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
- list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? item.MaxWidth.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
- list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? item.MaxHeight.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
-
- long startPositionTicks = item.StartPositionTicks;
+ get
+ {
+ if (IsDirectStream)
+ {
+ return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
+ }
- var isHls = string.Equals(item.SubProtocol, "hls", StringComparison.OrdinalIgnoreCase);
+ var targetVideoCodecs = TargetVideoCodec;
+ var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
+ if (!string.IsNullOrEmpty(videoCodec))
+ {
+ return GetTargetVideoLevel(videoCodec);
+ }
- if (isHls)
- {
- list.Add(new NameValuePair("StartTimeTicks", string.Empty));
+ return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
}
- else
+ }
+
+ ///
+ /// Gets the audio sample rate that will be in the output stream.
+ ///
+ public int? TargetPacketLength
+ {
+ get
{
- list.Add(new NameValuePair("StartTimeTicks", startPositionTicks.ToString(CultureInfo.InvariantCulture)));
+ var stream = TargetVideoStream;
+ return !IsDirectStream
+ ? null
+ : stream == null ? null : stream.PacketLength;
}
+ }
- list.Add(new NameValuePair("PlaySessionId", item.PlaySessionId ?? string.Empty));
- list.Add(new NameValuePair("api_key", accessToken ?? string.Empty));
-
- string liveStreamId = item.MediaSource?.LiveStreamId;
- list.Add(new NameValuePair("LiveStreamId", liveStreamId ?? string.Empty));
-
- list.Add(new NameValuePair("SubtitleMethod", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleDeliveryMethod.ToString() : string.Empty));
-
- if (!item.IsDirectStream)
+ ///
+ /// Gets the audio sample rate that will be in the output stream.
+ ///
+ public string TargetVideoProfile
+ {
+ get
{
- if (item.RequireNonAnamorphic)
+ if (IsDirectStream)
{
- list.Add(new NameValuePair("RequireNonAnamorphic", item.RequireNonAnamorphic.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
+ return TargetVideoStream == null ? null : TargetVideoStream.Profile;
}
- list.Add(new NameValuePair("TranscodingMaxAudioChannels", item.TranscodingMaxAudioChannels.HasValue ? item.TranscodingMaxAudioChannels.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
-
- if (item.EnableSubtitlesInManifest)
+ var targetVideoCodecs = TargetVideoCodec;
+ var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
+ if (!string.IsNullOrEmpty(videoCodec))
{
- list.Add(new NameValuePair("EnableSubtitlesInManifest", item.EnableSubtitlesInManifest.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
- }
-
- if (item.EnableMpegtsM2TsMode)
- {
- list.Add(new NameValuePair("EnableMpegtsM2TsMode", item.EnableMpegtsM2TsMode.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
- }
-
- if (item.EstimateContentLength)
- {
- list.Add(new NameValuePair("EstimateContentLength", item.EstimateContentLength.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
- }
-
- if (item.TranscodeSeekInfo != TranscodeSeekInfo.Auto)
- {
- list.Add(new NameValuePair("TranscodeSeekInfo", item.TranscodeSeekInfo.ToString().ToLowerInvariant()));
- }
-
- if (item.CopyTimestamps)
- {
- list.Add(new NameValuePair("CopyTimestamps", item.CopyTimestamps.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
- }
-
- list.Add(new NameValuePair("RequireAvc", item.RequireAvc.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
- }
-
- list.Add(new NameValuePair("Tag", item.MediaSource.ETag ?? string.Empty));
-
- string subtitleCodecs = item.SubtitleCodecs.Length == 0 ?
- string.Empty :
- string.Join(',', item.SubtitleCodecs);
-
- list.Add(new NameValuePair("SubtitleCodec", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Embed ? subtitleCodecs : string.Empty));
-
- if (isHls)
- {
- list.Add(new NameValuePair("SegmentContainer", item.Container ?? string.Empty));
-
- if (item.SegmentLength.HasValue)
- {
- list.Add(new NameValuePair("SegmentLength", item.SegmentLength.Value.ToString(CultureInfo.InvariantCulture)));
- }
-
- if (item.MinSegments.HasValue)
- {
- list.Add(new NameValuePair("MinSegments", item.MinSegments.Value.ToString(CultureInfo.InvariantCulture)));
- }
-
- list.Add(new NameValuePair("BreakOnNonKeyFrames", item.BreakOnNonKeyFrames.ToString(CultureInfo.InvariantCulture)));
- }
-
- foreach (var pair in item.StreamOptions)
- {
- if (string.IsNullOrEmpty(pair.Value))
- {
- continue;
+ return GetOption(videoCodec, "profile");
}
- // strip spaces to avoid having to encode h264 profile names
- list.Add(new NameValuePair(pair.Key, pair.Value.Replace(" ", string.Empty, StringComparison.Ordinal)));
+ return TargetVideoStream == null ? null : TargetVideoStream.Profile;
}
+ }
- if (!item.IsDirectStream)
+ ///
+ /// Gets the target video codec tag.
+ ///
+ /// The target video codec tag.
+ public string TargetVideoCodecTag
+ {
+ get
{
- list.Add(new NameValuePair("TranscodeReasons", string.Join(',', item.TranscodeReasons.Distinct().Select(i => i.ToString()))));
+ var stream = TargetVideoStream;
+ return !IsDirectStream
+ ? null
+ : stream == null ? null : stream.CodecTag;
}
-
- return list;
}
- public List GetExternalSubtitles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, string baseUrl, string accessToken)
+ ///
+ /// Gets the audio bitrate that will be in the output stream.
+ ///
+ public int? TargetAudioBitrate
{
- return GetExternalSubtitles(transcoderSupport, includeSelectedTrackOnly, false, baseUrl, accessToken);
+ get
+ {
+ var stream = TargetAudioStream;
+ return AudioBitrate.HasValue && !IsDirectStream
+ ? AudioBitrate
+ : stream == null ? null : stream.BitRate;
+ }
}
- public List GetExternalSubtitles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, bool enableAllProfiles, string baseUrl, string accessToken)
+ ///
+ /// Gets the audio channels that will be in the output stream.
+ ///
+ public int? TargetAudioChannels
{
- var list = GetSubtitleProfiles(transcoderSupport, includeSelectedTrackOnly, enableAllProfiles, baseUrl, accessToken);
- var newList = new List();
-
- // First add the selected track
- foreach (SubtitleStreamInfo stream in list)
+ get
{
- if (stream.DeliveryMethod == SubtitleDeliveryMethod.External)
+ if (IsDirectStream)
{
- newList.Add(stream);
+ return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels;
}
- }
- return newList;
- }
+ var targetAudioCodecs = TargetAudioCodec;
+ var codec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
+ if (!string.IsNullOrEmpty(codec))
+ {
+ return GetTargetRefFrames(codec);
+ }
- public List GetSubtitleProfiles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, string baseUrl, string accessToken)
- {
- return GetSubtitleProfiles(transcoderSupport, includeSelectedTrackOnly, false, baseUrl, accessToken);
+ return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels;
+ }
}
- public List GetSubtitleProfiles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, bool enableAllProfiles, string baseUrl, string accessToken)
+ ///
+ /// Gets the audio codec that will be in the output stream.
+ ///
+ public string[] TargetAudioCodec
{
- var list = new List();
+ get
+ {
+ var stream = TargetAudioStream;
- // HLS will preserve timestamps so we can just grab the full subtitle stream
- long startPositionTicks = string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase)
- ? 0
- : (PlayMethod == PlayMethod.Transcode && !CopyTimestamps ? StartPositionTicks : 0);
+ string inputCodec = stream?.Codec;
- // First add the selected track
- if (SubtitleStreamIndex.HasValue)
- {
- foreach (var stream in MediaSource.MediaStreams)
+ if (IsDirectStream)
{
- if (stream.Type == MediaStreamType.Subtitle && stream.Index == SubtitleStreamIndex.Value)
- {
- AddSubtitleProfiles(list, stream, transcoderSupport, enableAllProfiles, baseUrl, accessToken, startPositionTicks);
- }
+ return string.IsNullOrEmpty(inputCodec) ? Array.Empty() : new[] { inputCodec };
}
- }
- if (!includeSelectedTrackOnly)
- {
- foreach (var stream in MediaSource.MediaStreams)
+ foreach (string codec in AudioCodecs)
{
- if (stream.Type == MediaStreamType.Subtitle && (!SubtitleStreamIndex.HasValue || stream.Index != SubtitleStreamIndex.Value))
+ if (string.Equals(codec, inputCodec, StringComparison.OrdinalIgnoreCase))
{
- AddSubtitleProfiles(list, stream, transcoderSupport, enableAllProfiles, baseUrl, accessToken, startPositionTicks);
+ return string.IsNullOrEmpty(codec) ? Array.Empty() : new[] { codec };
}
}
- }
-
- return list;
- }
-
- private void AddSubtitleProfiles(List list, MediaStream stream, ITranscoderSupport transcoderSupport, bool enableAllProfiles, string baseUrl, string accessToken, long startPositionTicks)
- {
- if (enableAllProfiles)
- {
- foreach (var profile in DeviceProfile.SubtitleProfiles)
- {
- var info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks, new[] { profile }, transcoderSupport);
-
- list.Add(info);
- }
- }
- else
- {
- var info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks, DeviceProfile.SubtitleProfiles, transcoderSupport);
- list.Add(info);
+ return AudioCodecs;
}
}
- private SubtitleStreamInfo GetSubtitleStreamInfo(MediaStream stream, string baseUrl, string accessToken, long startPositionTicks, SubtitleProfile[] subtitleProfiles, ITranscoderSupport transcoderSupport)
+ public string[] TargetVideoCodec
{
- var subtitleProfile = StreamBuilder.GetSubtitleProfile(MediaSource, stream, subtitleProfiles, PlayMethod, transcoderSupport, Container, SubProtocol);
- var info = new SubtitleStreamInfo
+ get
{
- IsForced = stream.IsForced,
- Language = stream.Language,
- Name = stream.Language ?? "Unknown",
- Format = subtitleProfile.Format,
- Index = stream.Index,
- DeliveryMethod = subtitleProfile.Method,
- DisplayTitle = stream.DisplayTitle
- };
+ var stream = TargetVideoStream;
- if (info.DeliveryMethod == SubtitleDeliveryMethod.External)
- {
- if (MediaSource.Protocol == MediaProtocol.File || !string.Equals(stream.Codec, subtitleProfile.Format, StringComparison.OrdinalIgnoreCase) || !stream.IsExternal)
+ string inputCodec = stream?.Codec;
+
+ if (IsDirectStream)
{
- info.Url = string.Format(CultureInfo.InvariantCulture, "{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
- baseUrl,
- ItemId,
- MediaSourceId,
- stream.Index.ToString(CultureInfo.InvariantCulture),
- startPositionTicks.ToString(CultureInfo.InvariantCulture),
- subtitleProfile.Format);
+ return string.IsNullOrEmpty(inputCodec) ? Array.Empty() : new[] { inputCodec };
+ }
- if (!string.IsNullOrEmpty(accessToken))
+ foreach (string codec in VideoCodecs)
+ {
+ if (string.Equals(codec, inputCodec, StringComparison.OrdinalIgnoreCase))
{
- info.Url += "?api_key=" + accessToken;
+ return string.IsNullOrEmpty(codec) ? Array.Empty() : new[] { codec };
}
-
- info.IsExternalUrl = false;
}
- else
- {
- info.Url = stream.Path;
- info.IsExternalUrl = true;
- }
- }
- return info;
+ return VideoCodecs;
+ }
}
///
- /// Returns the audio stream that will be used.
+ /// Gets the audio channels that will be in the output stream.
///
- public MediaStream TargetAudioStream
+ public long? TargetSize
{
get
{
- if (MediaSource != null)
+ if (IsDirectStream)
{
- return MediaSource.GetDefaultAudioStream(AudioStreamIndex);
+ return MediaSource.Size;
+ }
+
+ if (RunTimeTicks.HasValue)
+ {
+ int? totalBitrate = TargetTotalBitrate;
+
+ double totalSeconds = RunTimeTicks.Value;
+ // Convert to ms
+ totalSeconds /= 10000;
+ // Convert to seconds
+ totalSeconds /= 1000;
+
+ return totalBitrate.HasValue ?
+ Convert.ToInt64(totalBitrate.Value * totalSeconds) :
+ (long?)null;
}
return null;
}
}
- ///
- /// Returns the video stream that will be used.
- ///
- public MediaStream TargetVideoStream
+ public int? TargetVideoBitrate
{
get
{
- if (MediaSource != null)
- {
- return MediaSource.VideoStream;
- }
+ var stream = TargetVideoStream;
- return null;
+ return VideoBitrate.HasValue && !IsDirectStream
+ ? VideoBitrate
+ : stream == null ? null : stream.BitRate;
}
}
- ///
- /// Predicts the audio sample rate that will be in the output stream.
- ///
- public int? TargetAudioSampleRate
+ public TransportStreamTimestamp TargetTimestamp
{
get
{
- var stream = TargetAudioStream;
- return AudioSampleRate.HasValue && !IsDirectStream
- ? AudioSampleRate
- : stream == null ? null : stream.SampleRate;
+ var defaultValue = string.Equals(Container, "m2ts", StringComparison.OrdinalIgnoreCase)
+ ? TransportStreamTimestamp.Valid
+ : TransportStreamTimestamp.None;
+
+ return !IsDirectStream
+ ? defaultValue
+ : MediaSource == null ? defaultValue : MediaSource.Timestamp ?? TransportStreamTimestamp.None;
}
}
- ///
- /// Predicts the audio sample rate that will be in the output stream.
- ///
- public int? TargetAudioBitDepth
+ public int? TargetTotalBitrate => (TargetAudioBitrate ?? 0) + (TargetVideoBitrate ?? 0);
+
+ public bool? IsTargetAnamorphic
{
get
{
if (IsDirectStream)
{
- return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth;
- }
-
- var targetAudioCodecs = TargetAudioCodec;
- var audioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
- if (!string.IsNullOrEmpty(audioCodec))
- {
- return GetTargetAudioBitDepth(audioCodec);
+ return TargetVideoStream == null ? null : TargetVideoStream.IsAnamorphic;
}
- return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth;
+ return false;
}
}
- ///
- /// Predicts the audio sample rate that will be in the output stream.
- ///
- public int? TargetVideoBitDepth
+ public bool? IsTargetInterlaced
{
get
{
if (IsDirectStream)
{
- return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth;
+ return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced;
}
var targetVideoCodecs = TargetVideoCodec;
var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
if (!string.IsNullOrEmpty(videoCodec))
{
- return GetTargetVideoBitDepth(videoCodec);
+ if (string.Equals(GetOption(videoCodec, "deinterlace"), "true", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
}
- return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth;
+ return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced;
}
}
- ///
- /// Gets the target reference frames.
- ///
- /// The target reference frames.
- public int? TargetRefFrames
+ public bool? IsTargetAVC
{
get
{
if (IsDirectStream)
{
- return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
- }
-
- var targetVideoCodecs = TargetVideoCodec;
- var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
- if (!string.IsNullOrEmpty(videoCodec))
- {
- return GetTargetRefFrames(videoCodec);
+ return TargetVideoStream == null ? null : TargetVideoStream.IsAVC;
}
- return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
+ return true;
}
}
- ///
- /// Predicts the audio sample rate that will be in the output stream.
- ///
- public float? TargetFramerate
+ public int? TargetWidth
{
get
{
- var stream = TargetVideoStream;
- return MaxFramerate.HasValue && !IsDirectStream
- ? MaxFramerate
- : stream == null ? null : stream.AverageFrameRate ?? stream.RealFrameRate;
+ var videoStream = TargetVideoStream;
+
+ if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue)
+ {
+ ImageDimensions size = new ImageDimensions(videoStream.Width.Value, videoStream.Height.Value);
+
+ size = DrawingUtils.Resize(size, 0, 0, MaxWidth ?? 0, MaxHeight ?? 0);
+
+ return size.Width;
+ }
+
+ return MaxWidth;
}
}
- ///
- /// Predicts the audio sample rate that will be in the output stream.
- ///
- public double? TargetVideoLevel
+ public int? TargetHeight
{
get
{
- if (IsDirectStream)
- {
- return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
- }
+ var videoStream = TargetVideoStream;
- var targetVideoCodecs = TargetVideoCodec;
- var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
- if (!string.IsNullOrEmpty(videoCodec))
+ if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue)
{
- return GetTargetVideoLevel(videoCodec);
+ ImageDimensions size = new ImageDimensions(videoStream.Width.Value, videoStream.Height.Value);
+
+ size = DrawingUtils.Resize(size, 0, 0, MaxWidth ?? 0, MaxHeight ?? 0);
+
+ return size.Height;
}
- return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
+ return MaxHeight;
}
}
- public int? GetTargetVideoBitDepth(string codec)
+ public int? TargetVideoStreamCount
{
- var value = GetOption(codec, "videobitdepth");
- if (string.IsNullOrEmpty(value))
+ get
{
- return null;
- }
+ if (IsDirectStream)
+ {
+ return GetMediaStreamCount(MediaStreamType.Video, int.MaxValue);
+ }
- if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
- {
- return result;
+ return GetMediaStreamCount(MediaStreamType.Video, 1);
}
-
- return null;
}
- public int? GetTargetAudioBitDepth(string codec)
+ public int? TargetAudioStreamCount
{
- var value = GetOption(codec, "audiobitdepth");
- if (string.IsNullOrEmpty(value))
- {
- return null;
- }
-
- if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
+ get
{
- return result;
- }
+ if (IsDirectStream)
+ {
+ return GetMediaStreamCount(MediaStreamType.Audio, int.MaxValue);
+ }
- return null;
+ return GetMediaStreamCount(MediaStreamType.Audio, 1);
+ }
}
- public double? GetTargetVideoLevel(string codec)
+ public void SetOption(string qualifier, string name, string value)
{
- var value = GetOption(codec, "level");
- if (string.IsNullOrEmpty(value))
+ if (string.IsNullOrEmpty(qualifier))
{
- return null;
+ SetOption(name, value);
}
-
- if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
+ else
{
- return result;
+ SetOption(qualifier + "-" + name, value);
}
+ }
- return null;
+ public void SetOption(string name, string value)
+ {
+ StreamOptions[name] = value;
}
- public int? GetTargetRefFrames(string codec)
+ public string GetOption(string qualifier, string name)
{
- var value = GetOption(codec, "maxrefframes");
+ var value = GetOption(qualifier + "-" + name);
+
if (string.IsNullOrEmpty(value))
{
- return null;
+ value = GetOption(name);
}
- if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
+ return value;
+ }
+
+ public string GetOption(string name)
+ {
+ if (StreamOptions.TryGetValue(name, out var value))
{
- return result;
+ return value;
}
return null;
}
- ///
- /// Predicts the audio sample rate that will be in the output stream.
- ///
- public int? TargetPacketLength
+ public string ToUrl(string baseUrl, string accessToken)
{
- get
+ if (PlayMethod == PlayMethod.DirectPlay)
{
- var stream = TargetVideoStream;
- return !IsDirectStream
- ? null
- : stream == null ? null : stream.PacketLength;
+ return MediaSource.Path;
}
- }
- ///
- /// Predicts the audio sample rate that will be in the output stream.
- ///
- public string TargetVideoProfile
- {
- get
+ if (string.IsNullOrEmpty(baseUrl))
{
- if (IsDirectStream)
+ throw new ArgumentNullException(nameof(baseUrl));
+ }
+
+ var list = new List();
+ foreach (NameValuePair pair in BuildParams(this, accessToken))
+ {
+ if (string.IsNullOrEmpty(pair.Value))
{
- return TargetVideoStream == null ? null : TargetVideoStream.Profile;
+ continue;
}
- var targetVideoCodecs = TargetVideoCodec;
- var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
- if (!string.IsNullOrEmpty(videoCodec))
+ // Try to keep the url clean by omitting defaults
+ if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase) &&
+ string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase))
{
- return GetOption(videoCodec, "profile");
+ continue;
}
- return TargetVideoStream == null ? null : TargetVideoStream.Profile;
- }
- }
+ if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase) &&
+ string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase))
+ {
+ continue;
+ }
- ///
- /// Gets the target video codec tag.
- ///
- /// The target video codec tag.
- public string TargetVideoCodecTag
- {
- get
- {
- var stream = TargetVideoStream;
- return !IsDirectStream
- ? null
- : stream == null ? null : stream.CodecTag;
+ // Be careful, IsDirectStream==true by default (Static != false or not in query).
+ // See initialization of StreamingRequestDto in AudioController.GetAudioStream() method : Static = @static ?? true.
+ if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase) &&
+ string.Equals(pair.Value, "true", StringComparison.OrdinalIgnoreCase))
+ {
+ continue;
+ }
+
+ var encodedValue = pair.Value.Replace(" ", "%20");
+
+ list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue));
}
+
+ string queryString = string.Join("&", list.ToArray());
+
+ return GetUrl(baseUrl, queryString);
}
- ///
- /// Predicts the audio bitrate that will be in the output stream.
- ///
- public int? TargetAudioBitrate
+ private string GetUrl(string baseUrl, string queryString)
{
- get
+ if (string.IsNullOrEmpty(baseUrl))
{
- var stream = TargetAudioStream;
- return AudioBitrate.HasValue && !IsDirectStream
- ? AudioBitrate
- : stream == null ? null : stream.BitRate;
+ throw new ArgumentNullException(nameof(baseUrl));
}
- }
- ///
- /// Predicts the audio channels that will be in the output stream.
- ///
- public int? TargetAudioChannels
- {
- get
+ string extension = string.IsNullOrEmpty(Container) ? string.Empty : "." + Container;
+
+ baseUrl = baseUrl.TrimEnd('/');
+
+ if (MediaType == DlnaProfileType.Audio)
{
- if (IsDirectStream)
+ if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
{
- return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels;
+ return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
}
- var targetAudioCodecs = TargetAudioCodec;
- var codec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
- if (!string.IsNullOrEmpty(codec))
- {
- return GetTargetRefFrames(codec);
- }
+ return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
+ }
- return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels;
+ if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
+ {
+ return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
}
+
+ return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
}
- public int? GetTargetAudioChannels(string codec)
+ private static List BuildParams(StreamInfo item, string accessToken)
{
- var defaultValue = GlobalMaxAudioChannels ?? TranscodingMaxAudioChannels;
+ var list = new List();
- var value = GetOption(codec, "audiochannels");
- if (string.IsNullOrEmpty(value))
+ string audioCodecs = item.AudioCodecs.Length == 0 ?
+ string.Empty :
+ string.Join(",", item.AudioCodecs);
+
+ string videoCodecs = item.VideoCodecs.Length == 0 ?
+ string.Empty :
+ string.Join(",", item.VideoCodecs);
+
+ list.Add(new NameValuePair("DeviceProfileId", item.DeviceProfileId ?? string.Empty));
+ list.Add(new NameValuePair("DeviceId", item.DeviceId ?? string.Empty));
+ list.Add(new NameValuePair("MediaSourceId", item.MediaSourceId ?? string.Empty));
+ list.Add(new NameValuePair("Static", item.IsDirectStream.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
+ list.Add(new NameValuePair("VideoCodec", videoCodecs));
+ list.Add(new NameValuePair("AudioCodec", audioCodecs));
+ list.Add(new NameValuePair("AudioStreamIndex", item.AudioStreamIndex.HasValue ? item.AudioStreamIndex.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
+ list.Add(new NameValuePair("SubtitleStreamIndex", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleStreamIndex.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
+ list.Add(new NameValuePair("VideoBitrate", item.VideoBitrate.HasValue ? item.VideoBitrate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
+ list.Add(new NameValuePair("AudioBitrate", item.AudioBitrate.HasValue ? item.AudioBitrate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
+ list.Add(new NameValuePair("AudioSampleRate", item.AudioSampleRate.HasValue ? item.AudioSampleRate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
+
+ list.Add(new NameValuePair("MaxFramerate", item.MaxFramerate.HasValue ? item.MaxFramerate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
+ list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? item.MaxWidth.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
+ list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? item.MaxHeight.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
+
+ long startPositionTicks = item.StartPositionTicks;
+
+ var isHls = string.Equals(item.SubProtocol, "hls", StringComparison.OrdinalIgnoreCase);
+
+ if (isHls)
{
- return defaultValue;
+ list.Add(new NameValuePair("StartTimeTicks", string.Empty));
}
-
- if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
+ else
{
- return Math.Min(result, defaultValue ?? result);
+ list.Add(new NameValuePair("StartTimeTicks", startPositionTicks.ToString(CultureInfo.InvariantCulture)));
}
- return defaultValue;
- }
+ list.Add(new NameValuePair("PlaySessionId", item.PlaySessionId ?? string.Empty));
+ list.Add(new NameValuePair("api_key", accessToken ?? string.Empty));
- ///
- /// Predicts the audio codec that will be in the output stream.
- ///
- public string[] TargetAudioCodec
- {
- get
- {
- var stream = TargetAudioStream;
+ string liveStreamId = item.MediaSource?.LiveStreamId;
+ list.Add(new NameValuePair("LiveStreamId", liveStreamId ?? string.Empty));
- string inputCodec = stream?.Codec;
+ list.Add(new NameValuePair("SubtitleMethod", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleDeliveryMethod.ToString() : string.Empty));
- if (IsDirectStream)
+ if (!item.IsDirectStream)
+ {
+ if (item.RequireNonAnamorphic)
{
- return string.IsNullOrEmpty(inputCodec) ? Array.Empty() : new[] { inputCodec };
+ list.Add(new NameValuePair("RequireNonAnamorphic", item.RequireNonAnamorphic.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
}
- foreach (string codec in AudioCodecs)
+ list.Add(new NameValuePair("TranscodingMaxAudioChannels", item.TranscodingMaxAudioChannels.HasValue ? item.TranscodingMaxAudioChannels.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
+
+ if (item.EnableSubtitlesInManifest)
{
- if (string.Equals(codec, inputCodec, StringComparison.OrdinalIgnoreCase))
- {
- return string.IsNullOrEmpty(codec) ? Array.Empty() : new[] { codec };
- }
+ list.Add(new NameValuePair("EnableSubtitlesInManifest", item.EnableSubtitlesInManifest.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
}
- return AudioCodecs;
- }
- }
-
- public string[] TargetVideoCodec
- {
- get
- {
- var stream = TargetVideoStream;
+ if (item.EnableMpegtsM2TsMode)
+ {
+ list.Add(new NameValuePair("EnableMpegtsM2TsMode", item.EnableMpegtsM2TsMode.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
+ }
- string inputCodec = stream?.Codec;
+ if (item.EstimateContentLength)
+ {
+ list.Add(new NameValuePair("EstimateContentLength", item.EstimateContentLength.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
+ }
- if (IsDirectStream)
+ if (item.TranscodeSeekInfo != TranscodeSeekInfo.Auto)
{
- return string.IsNullOrEmpty(inputCodec) ? Array.Empty() : new[] { inputCodec };
+ list.Add(new NameValuePair("TranscodeSeekInfo", item.TranscodeSeekInfo.ToString().ToLowerInvariant()));
}
- foreach (string codec in VideoCodecs)
+ if (item.CopyTimestamps)
{
- if (string.Equals(codec, inputCodec, StringComparison.OrdinalIgnoreCase))
- {
- return string.IsNullOrEmpty(codec) ? Array.Empty() : new[] { codec };
- }
+ list.Add(new NameValuePair("CopyTimestamps", item.CopyTimestamps.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
}
- return VideoCodecs;
+ list.Add(new NameValuePair("RequireAvc", item.RequireAvc.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
}
- }
- ///
- /// Predicts the audio channels that will be in the output stream.
- ///
- public long? TargetSize
- {
- get
+ list.Add(new NameValuePair("Tag", item.MediaSource.ETag ?? string.Empty));
+
+ string subtitleCodecs = item.SubtitleCodecs.Length == 0 ?
+ string.Empty :
+ string.Join(",", item.SubtitleCodecs);
+
+ list.Add(new NameValuePair("SubtitleCodec", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Embed ? subtitleCodecs : string.Empty));
+
+ if (isHls)
{
- if (IsDirectStream)
+ list.Add(new NameValuePair("SegmentContainer", item.Container ?? string.Empty));
+
+ if (item.SegmentLength.HasValue)
{
- return MediaSource.Size;
+ list.Add(new NameValuePair("SegmentLength", item.SegmentLength.Value.ToString(CultureInfo.InvariantCulture)));
}
- if (RunTimeTicks.HasValue)
+ if (item.MinSegments.HasValue)
{
- int? totalBitrate = TargetTotalBitrate;
-
- double totalSeconds = RunTimeTicks.Value;
- // Convert to ms
- totalSeconds /= 10000;
- // Convert to seconds
- totalSeconds /= 1000;
-
- return totalBitrate.HasValue ?
- Convert.ToInt64(totalBitrate.Value * totalSeconds) :
- (long?)null;
+ list.Add(new NameValuePair("MinSegments", item.MinSegments.Value.ToString(CultureInfo.InvariantCulture)));
}
- return null;
+ list.Add(new NameValuePair("BreakOnNonKeyFrames", item.BreakOnNonKeyFrames.ToString(CultureInfo.InvariantCulture)));
}
- }
- public int? TargetVideoBitrate
- {
- get
+ foreach (var pair in item.StreamOptions)
{
- var stream = TargetVideoStream;
+ if (string.IsNullOrEmpty(pair.Value))
+ {
+ continue;
+ }
- return VideoBitrate.HasValue && !IsDirectStream
- ? VideoBitrate
- : stream == null ? null : stream.BitRate;
+ // strip spaces to avoid having to encode h264 profile names
+ list.Add(new NameValuePair(pair.Key, pair.Value.Replace(" ", string.Empty)));
}
- }
- public TransportStreamTimestamp TargetTimestamp
- {
- get
+ if (!item.IsDirectStream)
{
- var defaultValue = string.Equals(Container, "m2ts", StringComparison.OrdinalIgnoreCase)
- ? TransportStreamTimestamp.Valid
- : TransportStreamTimestamp.None;
-
- return !IsDirectStream
- ? defaultValue
- : MediaSource == null ? defaultValue : MediaSource.Timestamp ?? TransportStreamTimestamp.None;
+ list.Add(new NameValuePair("TranscodeReasons", string.Join(',', item.TranscodeReasons.Distinct())));
}
+
+ return list;
}
- public int? TargetTotalBitrate => (TargetAudioBitrate ?? 0) + (TargetVideoBitrate ?? 0);
+ public List GetExternalSubtitles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, string baseUrl, string accessToken)
+ {
+ return GetExternalSubtitles(transcoderSupport, includeSelectedTrackOnly, false, baseUrl, accessToken);
+ }
- public bool? IsTargetAnamorphic
+ public List GetExternalSubtitles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, bool enableAllProfiles, string baseUrl, string accessToken)
{
- get
+ var list = GetSubtitleProfiles(transcoderSupport, includeSelectedTrackOnly, enableAllProfiles, baseUrl, accessToken);
+ var newList = new List();
+
+ // First add the selected track
+ foreach (SubtitleStreamInfo stream in list)
{
- if (IsDirectStream)
+ if (stream.DeliveryMethod == SubtitleDeliveryMethod.External)
{
- return TargetVideoStream == null ? null : TargetVideoStream.IsAnamorphic;
+ newList.Add(stream);
}
-
- return false;
}
+
+ return newList;
}
- public bool? IsTargetInterlaced
+ public List GetSubtitleProfiles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, string baseUrl, string accessToken)
{
- get
+ return GetSubtitleProfiles(transcoderSupport, includeSelectedTrackOnly, false, baseUrl, accessToken);
+ }
+
+ public List GetSubtitleProfiles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, bool enableAllProfiles, string baseUrl, string accessToken)
+ {
+ var list = new List();
+
+ // HLS will preserve timestamps so we can just grab the full subtitle stream
+ long startPositionTicks = string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase)
+ ? 0
+ : (PlayMethod == PlayMethod.Transcode && !CopyTimestamps ? StartPositionTicks : 0);
+
+ // First add the selected track
+ if (SubtitleStreamIndex.HasValue)
{
- if (IsDirectStream)
+ foreach (var stream in MediaSource.MediaStreams)
{
- return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced;
+ if (stream.Type == MediaStreamType.Subtitle && stream.Index == SubtitleStreamIndex.Value)
+ {
+ AddSubtitleProfiles(list, stream, transcoderSupport, enableAllProfiles, baseUrl, accessToken, startPositionTicks);
+ }
}
+ }
- var targetVideoCodecs = TargetVideoCodec;
- var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
- if (!string.IsNullOrEmpty(videoCodec))
+ if (!includeSelectedTrackOnly)
+ {
+ foreach (var stream in MediaSource.MediaStreams)
{
- if (string.Equals(GetOption(videoCodec, "deinterlace"), "true", StringComparison.OrdinalIgnoreCase))
+ if (stream.Type == MediaStreamType.Subtitle && (!SubtitleStreamIndex.HasValue || stream.Index != SubtitleStreamIndex.Value))
{
- return false;
+ AddSubtitleProfiles(list, stream, transcoderSupport, enableAllProfiles, baseUrl, accessToken, startPositionTicks);
}
}
-
- return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced;
}
+
+ return list;
}
- public bool? IsTargetAVC
+ private void AddSubtitleProfiles(List list, MediaStream stream, ITranscoderSupport transcoderSupport, bool enableAllProfiles, string baseUrl, string accessToken, long startPositionTicks)
{
- get
+ if (enableAllProfiles)
{
- if (IsDirectStream)
+ foreach (var profile in DeviceProfile.SubtitleProfiles)
{
- return TargetVideoStream == null ? null : TargetVideoStream.IsAVC;
+ var info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks, new[] { profile }, transcoderSupport);
+
+ list.Add(info);
}
+ }
+ else
+ {
+ var info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks, DeviceProfile.SubtitleProfiles, transcoderSupport);
- return true;
+ list.Add(info);
}
}
- public int? TargetWidth
+ private SubtitleStreamInfo GetSubtitleStreamInfo(MediaStream stream, string baseUrl, string accessToken, long startPositionTicks, SubtitleProfile[] subtitleProfiles, ITranscoderSupport transcoderSupport)
{
- get
+ var subtitleProfile = StreamBuilder.GetSubtitleProfile(MediaSource, stream, subtitleProfiles, PlayMethod, transcoderSupport, Container, SubProtocol);
+ var info = new SubtitleStreamInfo
{
- var videoStream = TargetVideoStream;
+ IsForced = stream.IsForced,
+ Language = stream.Language,
+ Name = stream.Language ?? "Unknown",
+ Format = subtitleProfile.Format,
+ Index = stream.Index,
+ DeliveryMethod = subtitleProfile.Method,
+ DisplayTitle = stream.DisplayTitle
+ };
- if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue)
+ if (info.DeliveryMethod == SubtitleDeliveryMethod.External)
+ {
+ if (MediaSource.Protocol == MediaProtocol.File || !string.Equals(stream.Codec, subtitleProfile.Format, StringComparison.OrdinalIgnoreCase) || !stream.IsExternal)
{
- ImageDimensions size = new ImageDimensions(videoStream.Width.Value, videoStream.Height.Value);
+ info.Url = string.Format(
+ CultureInfo.InvariantCulture,
+ "{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
+ baseUrl,
+ ItemId,
+ MediaSourceId,
+ stream.Index.ToString(CultureInfo.InvariantCulture),
+ startPositionTicks.ToString(CultureInfo.InvariantCulture),
+ subtitleProfile.Format);
- size = DrawingUtils.Resize(size, 0, 0, MaxWidth ?? 0, MaxHeight ?? 0);
+ if (!string.IsNullOrEmpty(accessToken))
+ {
+ info.Url += "?api_key=" + accessToken;
+ }
- return size.Width;
+ info.IsExternalUrl = false;
+ }
+ else
+ {
+ info.Url = stream.Path;
+ info.IsExternalUrl = true;
}
+ }
- return MaxWidth;
+ return info;
+ }
+
+ public int? GetTargetVideoBitDepth(string codec)
+ {
+ var value = GetOption(codec, "videobitdepth");
+ if (string.IsNullOrEmpty(value))
+ {
+ return null;
+ }
+
+ if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
+ {
+ return result;
}
+
+ return null;
}
- public int? TargetHeight
+ public int? GetTargetAudioBitDepth(string codec)
{
- get
+ var value = GetOption(codec, "audiobitdepth");
+ if (string.IsNullOrEmpty(value))
{
- var videoStream = TargetVideoStream;
+ return null;
+ }
- if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue)
- {
- ImageDimensions size = new ImageDimensions(videoStream.Width.Value, videoStream.Height.Value);
+ if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
+ {
+ return result;
+ }
- size = DrawingUtils.Resize(size, 0, 0, MaxWidth ?? 0, MaxHeight ?? 0);
+ return null;
+ }
- return size.Height;
- }
+ public double? GetTargetVideoLevel(string codec)
+ {
+ var value = GetOption(codec, "level");
+ if (string.IsNullOrEmpty(value))
+ {
+ return null;
+ }
- return MaxHeight;
+ if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
+ {
+ return result;
}
+
+ return null;
}
- public int? TargetVideoStreamCount
+ public int? GetTargetRefFrames(string codec)
{
- get
+ var value = GetOption(codec, "maxrefframes");
+ if (string.IsNullOrEmpty(value))
{
- if (IsDirectStream)
- {
- return GetMediaStreamCount(MediaStreamType.Video, int.MaxValue);
- }
+ return null;
+ }
- return GetMediaStreamCount(MediaStreamType.Video, 1);
+ if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
+ {
+ return result;
}
+
+ return null;
}
- public int? TargetAudioStreamCount
+ public int? GetTargetAudioChannels(string codec)
{
- get
+ var defaultValue = GlobalMaxAudioChannels ?? TranscodingMaxAudioChannels;
+
+ var value = GetOption(codec, "audiochannels");
+ if (string.IsNullOrEmpty(value))
{
- if (IsDirectStream)
- {
- return GetMediaStreamCount(MediaStreamType.Audio, int.MaxValue);
- }
+ return defaultValue;
+ }
- return GetMediaStreamCount(MediaStreamType.Audio, 1);
+ if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
+ {
+ return Math.Min(result, defaultValue ?? result);
}
+
+ return defaultValue;
}
private int? GetMediaStreamCount(MediaStreamType type, int limit)
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index 2f9f9d3cdb..a784025e3d 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -294,13 +294,13 @@ namespace MediaBrowser.Model.Dto
public NameGuidPair[] GenreItems { get; set; }
///
- /// If the item does not have a logo, this will hold the Id of the Parent that has one.
+ /// Gets or sets wether the item has a logo, this will hold the Id of the Parent that has one.
///
/// The parent logo item id.
public string ParentLogoItemId { get; set; }
///
- /// If the item does not have any backdrops, this will hold the Id of the Parent that has one.
+ /// Gets or sets wether the item has any backdrops, this will hold the Id of the Parent that has one.
///
/// The parent backdrop item id.
public string ParentBackdropItemId { get; set; }
@@ -318,7 +318,7 @@ namespace MediaBrowser.Model.Dto
public int? LocalTrailerCount { get; set; }
///
- /// User data for this item based on the user it's being requested for.
+ /// Gets or sets the user data for this item based on the user it's being requested for.
///
/// The user data.
public UserItemDataDto UserData { get; set; }
@@ -506,7 +506,7 @@ namespace MediaBrowser.Model.Dto
public string ParentLogoImageTag { get; set; }
///
- /// If the item does not have a art, this will hold the Id of the Parent that has one.
+ /// Gets or sets wether the item has fan art, this will hold the Id of the Parent that has one.
///
/// The parent art item id.
public string ParentArtItemId { get; set; }
@@ -695,7 +695,7 @@ namespace MediaBrowser.Model.Dto
public string ChannelPrimaryImageTag { get; set; }
///
- /// The start date of the recording, in UTC.
+ /// Gets or sets the start date of the recording, in UTC.
///
public DateTime? StartDate { get; set; }
diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
index be682be23c..ec3b37efa3 100644
--- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs
+++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
@@ -12,6 +12,18 @@ namespace MediaBrowser.Model.Dto
{
public class MediaSourceInfo
{
+ public MediaSourceInfo()
+ {
+ Formats = Array.Empty();
+ MediaStreams = new List();
+ MediaAttachments = Array.Empty();
+ RequiredHttpHeaders = new Dictionary();
+ SupportsTranscoding = true;
+ SupportsDirectStream = true;
+ SupportsDirectPlay = true;
+ SupportsProbing = true;
+ }
+
public MediaProtocol Protocol { get; set; }
public string Id { get; set; }
@@ -31,6 +43,7 @@ namespace MediaBrowser.Model.Dto
public string Name { get; set; }
///
+ /// Gets or sets a value indicating whether the media is remote.
/// Differentiate internet url vs local network.
///
public bool IsRemote { get; set; }
@@ -95,16 +108,28 @@ namespace MediaBrowser.Model.Dto
public int? AnalyzeDurationMs { get; set; }
- public MediaSourceInfo()
+ [JsonIgnore]
+ public TranscodeReason[] TranscodeReasons { get; set; }
+
+ public int? DefaultAudioStreamIndex { get; set; }
+
+ public int? DefaultSubtitleStreamIndex { get; set; }
+
+ [JsonIgnore]
+ public MediaStream VideoStream
{
- Formats = Array.Empty();
- MediaStreams = new List();
- MediaAttachments = Array.Empty();
- RequiredHttpHeaders = new Dictionary();
- SupportsTranscoding = true;
- SupportsDirectStream = true;
- SupportsDirectPlay = true;
- SupportsProbing = true;
+ get
+ {
+ foreach (var i in MediaStreams)
+ {
+ if (i.Type == MediaStreamType.Video)
+ {
+ return i;
+ }
+ }
+
+ return null;
+ }
}
public void InferTotalBitrate(bool force = false)
@@ -134,13 +159,6 @@ namespace MediaBrowser.Model.Dto
}
}
- [JsonIgnore]
- public TranscodeReason[] TranscodeReasons { get; set; }
-
- public int? DefaultAudioStreamIndex { get; set; }
-
- public int? DefaultSubtitleStreamIndex { get; set; }
-
public MediaStream GetDefaultAudioStream(int? defaultIndex)
{
if (defaultIndex.HasValue)
@@ -175,23 +193,6 @@ namespace MediaBrowser.Model.Dto
return null;
}
- [JsonIgnore]
- public MediaStream VideoStream
- {
- get
- {
- foreach (var i in MediaStreams)
- {
- if (i.Type == MediaStreamType.Video)
- {
- return i;
- }
- }
-
- return null;
- }
- }
-
public MediaStream GetMediaStream(MediaStreamType type, int index)
{
foreach (var i in MediaStreams)
diff --git a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs
index e4f38d6af3..e0e889f7d0 100644
--- a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs
+++ b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs
@@ -10,6 +10,15 @@ namespace MediaBrowser.Model.Dto
{
public class MetadataEditorInfo
{
+ public MetadataEditorInfo()
+ {
+ ParentalRatingOptions = Array.Empty();
+ Countries = Array.Empty();
+ Cultures = Array.Empty();
+ ExternalIdInfos = Array.Empty();
+ ContentTypeOptions = Array.Empty();
+ }
+
public ParentalRating[] ParentalRatingOptions { get; set; }
public CountryInfo[] Countries { get; set; }
@@ -21,14 +30,5 @@ namespace MediaBrowser.Model.Dto
public string ContentType { get; set; }
public NameValuePair[] ContentTypeOptions { get; set; }
-
- public MetadataEditorInfo()
- {
- ParentalRatingOptions = Array.Empty();
- Countries = Array.Empty();
- Cultures = Array.Empty();
- ExternalIdInfos = Array.Empty();
- ContentTypeOptions = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Dto/NameGuidPair.cs b/MediaBrowser.Model/Dto/NameGuidPair.cs
new file mode 100644
index 0000000000..71166df979
--- /dev/null
+++ b/MediaBrowser.Model/Dto/NameGuidPair.cs
@@ -0,0 +1,14 @@
+#nullable disable
+#pragma warning disable CS1591
+
+using System;
+
+namespace MediaBrowser.Model.Dto
+{
+ public class NameGuidPair
+ {
+ public string Name { get; set; }
+
+ public Guid Id { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Dto/NameIdPair.cs b/MediaBrowser.Model/Dto/NameIdPair.cs
index 45c2fb35db..7f18b45028 100644
--- a/MediaBrowser.Model/Dto/NameIdPair.cs
+++ b/MediaBrowser.Model/Dto/NameIdPair.cs
@@ -19,11 +19,4 @@ namespace MediaBrowser.Model.Dto
/// The identifier.
public string Id { get; set; }
}
-
- public class NameGuidPair
- {
- public string Name { get; set; }
-
- public Guid Id { get; set; }
- }
}
diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs
index 40222c9dca..256d7b10f1 100644
--- a/MediaBrowser.Model/Dto/UserDto.cs
+++ b/MediaBrowser.Model/Dto/UserDto.cs
@@ -10,6 +10,15 @@ namespace MediaBrowser.Model.Dto
///
public class UserDto : IItemDto, IHasServerId
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public UserDto()
+ {
+ Configuration = new UserConfiguration();
+ Policy = new UserPolicy();
+ }
+
///
/// Gets or sets the name.
///
@@ -94,15 +103,6 @@ namespace MediaBrowser.Model.Dto
/// The primary image aspect ratio.
public double? PrimaryImageAspectRatio { get; set; }
- ///
- /// Initializes a new instance of the class.
- ///
- public UserDto()
- {
- Configuration = new UserConfiguration();
- Policy = new UserPolicy();
- }
-
///
public override string ToString()
{
diff --git a/MediaBrowser.Model/Entities/CollectionType.cs b/MediaBrowser.Model/Entities/CollectionType.cs
index 3540387129..60b69d4b01 100644
--- a/MediaBrowser.Model/Entities/CollectionType.cs
+++ b/MediaBrowser.Model/Entities/CollectionType.cs
@@ -24,36 +24,4 @@ namespace MediaBrowser.Model.Entities
public const string Playlists = "playlists";
public const string Folders = "folders";
}
-
- public static class SpecialFolder
- {
- public const string TvShowSeries = "TvShowSeries";
- public const string TvGenres = "TvGenres";
- public const string TvGenre = "TvGenre";
- public const string TvLatest = "TvLatest";
- public const string TvNextUp = "TvNextUp";
- public const string TvResume = "TvResume";
- public const string TvFavoriteSeries = "TvFavoriteSeries";
- public const string TvFavoriteEpisodes = "TvFavoriteEpisodes";
-
- public const string MovieLatest = "MovieLatest";
- public const string MovieResume = "MovieResume";
- public const string MovieMovies = "MovieMovies";
- public const string MovieCollections = "MovieCollections";
- public const string MovieFavorites = "MovieFavorites";
- public const string MovieGenres = "MovieGenres";
- public const string MovieGenre = "MovieGenre";
-
- public const string MusicArtists = "MusicArtists";
- public const string MusicAlbumArtists = "MusicAlbumArtists";
- public const string MusicAlbums = "MusicAlbums";
- public const string MusicGenres = "MusicGenres";
- public const string MusicLatest = "MusicLatest";
- public const string MusicPlaylists = "MusicPlaylists";
- public const string MusicSongs = "MusicSongs";
- public const string MusicFavorites = "MusicFavorites";
- public const string MusicFavoriteArtists = "MusicFavoriteArtists";
- public const string MusicFavoriteAlbums = "MusicFavoriteAlbums";
- public const string MusicFavoriteSongs = "MusicFavoriteSongs";
- }
}
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index d85a8cde95..ade9d7e8dd 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -84,7 +84,7 @@ namespace MediaBrowser.Model.Entities
public string Title { get; set; }
///
- /// Gets or sets the video range.
+ /// Gets the video range.
///
/// The video range.
public string VideoRange
@@ -108,11 +108,11 @@ namespace MediaBrowser.Model.Entities
}
}
- public string localizedUndefined { get; set; }
+ public string LocalizedUndefined { get; set; }
- public string localizedDefault { get; set; }
+ public string LocalizedDefault { get; set; }
- public string localizedForced { get; set; }
+ public string LocalizedForced { get; set; }
public string DisplayTitle
{
@@ -154,7 +154,7 @@ namespace MediaBrowser.Model.Entities
if (IsDefault)
{
- attributes.Add(string.IsNullOrEmpty(localizedDefault) ? "Default" : localizedDefault);
+ attributes.Add(string.IsNullOrEmpty(LocalizedDefault) ? "Default" : LocalizedDefault);
}
if (!string.IsNullOrEmpty(Title))
@@ -229,17 +229,17 @@ namespace MediaBrowser.Model.Entities
}
else
{
- attributes.Add(string.IsNullOrEmpty(localizedUndefined) ? "Und" : localizedUndefined);
+ attributes.Add(string.IsNullOrEmpty(LocalizedUndefined) ? "Und" : LocalizedUndefined);
}
if (IsDefault)
{
- attributes.Add(string.IsNullOrEmpty(localizedDefault) ? "Default" : localizedDefault);
+ attributes.Add(string.IsNullOrEmpty(LocalizedDefault) ? "Default" : LocalizedDefault);
}
if (IsForced)
{
- attributes.Add(string.IsNullOrEmpty(localizedForced) ? "Forced" : localizedForced);
+ attributes.Add(string.IsNullOrEmpty(LocalizedForced) ? "Forced" : LocalizedForced);
}
if (!string.IsNullOrEmpty(Title))
@@ -266,67 +266,6 @@ namespace MediaBrowser.Model.Entities
}
}
- private string GetResolutionText()
- {
- var i = this;
-
- if (i.Width.HasValue && i.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;
- }
-
public string NalLengthSize { get; set; }
///
@@ -487,6 +426,96 @@ namespace MediaBrowser.Model.Entities
}
}
+ ///
+ /// Gets or sets a value indicating whether [supports external stream].
+ ///
+ /// true if [supports external stream]; otherwise, false.
+ public bool SupportsExternalStream { get; set; }
+
+ ///
+ /// Gets or sets the filename.
+ ///
+ /// The filename.
+ public string Path { get; set; }
+
+ ///
+ /// Gets or sets the pixel format.
+ ///
+ /// The pixel format.
+ public string PixelFormat { get; set; }
+
+ ///
+ /// Gets or sets the level.
+ ///
+ /// The level.
+ public double? Level { get; set; }
+
+ ///
+ /// Gets or sets whether this instance is anamorphic.
+ ///
+ /// true if this instance is anamorphic; otherwise, false.
+ public bool? IsAnamorphic { get; set; }
+
+ private string GetResolutionText()
+ {
+ var i = this;
+
+ if (i.Width.HasValue && i.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;
+ }
+
public static bool IsTextFormat(string format)
{
string codec = format ?? string.Empty;
@@ -533,35 +562,5 @@ namespace MediaBrowser.Model.Entities
return true;
}
-
- ///
- /// Gets or sets a value indicating whether [supports external stream].
- ///
- /// true if [supports external stream]; otherwise, false.
- public bool SupportsExternalStream { get; set; }
-
- ///
- /// Gets or sets the filename.
- ///
- /// The filename.
- public string Path { get; set; }
-
- ///
- /// Gets or sets the pixel format.
- ///
- /// The pixel format.
- public string PixelFormat { get; set; }
-
- ///
- /// Gets or sets the level.
- ///
- /// The level.
- public double? Level { get; set; }
-
- ///
- /// Gets a value indicating whether this instance is anamorphic.
- ///
- /// true if this instance is anamorphic; otherwise, false.
- public bool? IsAnamorphic { get; set; }
}
}
diff --git a/MediaBrowser.Model/Entities/PackageReviewInfo.cs b/MediaBrowser.Model/Entities/PackageReviewInfo.cs
deleted file mode 100644
index 5b22b34ace..0000000000
--- a/MediaBrowser.Model/Entities/PackageReviewInfo.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-#nullable disable
-#pragma warning disable CS1591
-
-using System;
-
-namespace MediaBrowser.Model.Entities
-{
- public class PackageReviewInfo
- {
- ///
- /// Gets or sets the package id (database key) for this review.
- ///
- public int id { get; set; }
-
- ///
- /// Gets or sets the rating value.
- ///
- public int rating { get; set; }
-
- ///
- /// Gets or sets whether or not this review recommends this item.
- ///
- public bool recommend { get; set; }
-
- ///
- /// Gets or sets a short description of the review.
- ///
- public string title { get; set; }
-
- ///
- /// Gets or sets the full review.
- ///
- public string review { get; set; }
-
- ///
- /// Gets or sets the time of review.
- ///
- public DateTime timestamp { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/Entities/SpecialFolder.cs b/MediaBrowser.Model/Entities/SpecialFolder.cs
new file mode 100644
index 0000000000..2250c5dffb
--- /dev/null
+++ b/MediaBrowser.Model/Entities/SpecialFolder.cs
@@ -0,0 +1,36 @@
+#pragma warning disable CS1591
+
+namespace MediaBrowser.Model.Entities
+{
+ public static class SpecialFolder
+ {
+ public const string TvShowSeries = "TvShowSeries";
+ public const string TvGenres = "TvGenres";
+ public const string TvGenre = "TvGenre";
+ public const string TvLatest = "TvLatest";
+ public const string TvNextUp = "TvNextUp";
+ public const string TvResume = "TvResume";
+ public const string TvFavoriteSeries = "TvFavoriteSeries";
+ public const string TvFavoriteEpisodes = "TvFavoriteEpisodes";
+
+ public const string MovieLatest = "MovieLatest";
+ public const string MovieResume = "MovieResume";
+ public const string MovieMovies = "MovieMovies";
+ public const string MovieCollections = "MovieCollections";
+ public const string MovieFavorites = "MovieFavorites";
+ public const string MovieGenres = "MovieGenres";
+ public const string MovieGenre = "MovieGenre";
+
+ public const string MusicArtists = "MusicArtists";
+ public const string MusicAlbumArtists = "MusicAlbumArtists";
+ public const string MusicAlbums = "MusicAlbums";
+ public const string MusicGenres = "MusicGenres";
+ public const string MusicLatest = "MusicLatest";
+ public const string MusicPlaylists = "MusicPlaylists";
+ public const string MusicSongs = "MusicSongs";
+ public const string MusicFavorites = "MusicFavorites";
+ public const string MusicFavoriteArtists = "MusicFavoriteArtists";
+ public const string MusicFavoriteAlbums = "MusicFavoriteAlbums";
+ public const string MusicFavoriteSongs = "MusicFavoriteSongs";
+ }
+}
diff --git a/MediaBrowser.Model/Entities/VirtualFolderInfo.cs b/MediaBrowser.Model/Entities/VirtualFolderInfo.cs
index f2bc6f25e0..1b0e592401 100644
--- a/MediaBrowser.Model/Entities/VirtualFolderInfo.cs
+++ b/MediaBrowser.Model/Entities/VirtualFolderInfo.cs
@@ -11,6 +11,14 @@ namespace MediaBrowser.Model.Entities
///
public class VirtualFolderInfo
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public VirtualFolderInfo()
+ {
+ Locations = Array.Empty();
+ }
+
///
/// Gets or sets the name.
///
@@ -31,14 +39,6 @@ namespace MediaBrowser.Model.Entities
public LibraryOptions LibraryOptions { get; set; }
- ///
- /// Initializes a new instance of the class.
- ///
- public VirtualFolderInfo()
- {
- Locations = Array.Empty();
- }
-
///
/// Gets or sets the item identifier.
///
diff --git a/MediaBrowser.Model/Globalization/CultureDto.cs b/MediaBrowser.Model/Globalization/CultureDto.cs
index 6af4a872ce..5246f87d92 100644
--- a/MediaBrowser.Model/Globalization/CultureDto.cs
+++ b/MediaBrowser.Model/Globalization/CultureDto.cs
@@ -10,6 +10,11 @@ namespace MediaBrowser.Model.Globalization
///
public class CultureDto
{
+ public CultureDto()
+ {
+ ThreeLetterISOLanguageNames = Array.Empty();
+ }
+
///
/// Gets or sets the name.
///
@@ -29,7 +34,7 @@ namespace MediaBrowser.Model.Globalization
public string TwoLetterISOLanguageName { get; set; }
///
- /// Gets or sets the name of the three letter ISO language.
+ /// Gets the name of the three letter ISO language.
///
/// The name of the three letter ISO language.
public string ThreeLetterISOLanguageName
@@ -47,10 +52,5 @@ namespace MediaBrowser.Model.Globalization
}
public string[] ThreeLetterISOLanguageNames { get; set; }
-
- public CultureDto()
- {
- ThreeLetterISOLanguageNames = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs
index dc65497876..ef08ecec66 100644
--- a/MediaBrowser.Model/IO/IFileSystem.cs
+++ b/MediaBrowser.Model/IO/IFileSystem.cs
@@ -155,13 +155,16 @@ namespace MediaBrowser.Model.IO
/// Gets the directories.
///
/// The path.
- /// if set to true [recursive].
- /// IEnumerable<DirectoryInfo>.
+ /// If set to true also searches in subdirectiories.
+ /// All found directories.
IEnumerable GetDirectories(string path, bool recursive = false);
///
/// Gets the files.
///
+ /// The path in which to search.
+ /// If set to true also searches in subdirectiories.
+ /// All found files.
IEnumerable GetFiles(string path, bool recursive = false);
IEnumerable GetFiles(string path, IReadOnlyList extensions, bool enableCaseSensitiveExtensions, bool recursive);
diff --git a/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs
index 07e76d9600..c6de4c1ab8 100644
--- a/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs
+++ b/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs
@@ -9,7 +9,7 @@ namespace MediaBrowser.Model.LiveTv
public class BaseTimerInfoDto : IHasServerId
{
///
- /// Id of the recording.
+ /// Gets or sets the Id of the recording.
///
public string Id { get; set; }
@@ -28,7 +28,7 @@ namespace MediaBrowser.Model.LiveTv
public string ExternalId { get; set; }
///
- /// ChannelId of the recording.
+ /// Gets or sets the channel id of the recording.
///
public Guid ChannelId { get; set; }
@@ -39,7 +39,7 @@ namespace MediaBrowser.Model.LiveTv
public string ExternalChannelId { get; set; }
///
- /// ChannelName of the recording.
+ /// Gets or sets the channel name of the recording.
///
public string ChannelName { get; set; }
@@ -58,22 +58,22 @@ namespace MediaBrowser.Model.LiveTv
public string ExternalProgramId { get; set; }
///
- /// Name of the recording.
+ /// Gets or sets the name of the recording.
///
public string Name { get; set; }
///
- /// Description of the recording.
+ /// Gets or sets the description of the recording.
///
public string Overview { get; set; }
///
- /// The start date of the recording, in UTC.
+ /// Gets or sets the start date of the recording, in UTC.
///
public DateTime StartDate { get; set; }
///
- /// The end date of the recording, in UTC.
+ /// Gets or sets the end date of the recording, in UTC.
///
public DateTime EndDate { get; set; }
@@ -108,7 +108,7 @@ namespace MediaBrowser.Model.LiveTv
public bool IsPrePaddingRequired { get; set; }
///
- /// If the item does not have any backdrops, this will hold the Id of the Parent that has one.
+ /// Gets or sets the Id of the Parent that has a backdrop if the item does not have one.
///
/// The parent backdrop item id.
public string ParentBackdropItemId { get; set; }
diff --git a/MediaBrowser.Model/LiveTv/ListingsProviderInfo.cs b/MediaBrowser.Model/LiveTv/ListingsProviderInfo.cs
new file mode 100644
index 0000000000..082daeb51b
--- /dev/null
+++ b/MediaBrowser.Model/LiveTv/ListingsProviderInfo.cs
@@ -0,0 +1,58 @@
+#nullable disable
+#pragma warning disable CS1591
+
+using System;
+using MediaBrowser.Model.Dto;
+
+namespace MediaBrowser.Model.LiveTv
+{
+ public class ListingsProviderInfo
+ {
+ public ListingsProviderInfo()
+ {
+ NewsCategories = new[] { "news", "journalism", "documentary", "current affairs" };
+ SportsCategories = new[] { "sports", "basketball", "baseball", "football" };
+ KidsCategories = new[] { "kids", "family", "children", "childrens", "disney" };
+ MovieCategories = new[] { "movie" };
+ EnabledTuners = Array.Empty();
+ EnableAllTuners = true;
+ ChannelMappings = Array.Empty();
+ }
+
+ public string Id { get; set; }
+
+ public string Type { get; set; }
+
+ public string Username { get; set; }
+
+ public string Password { get; set; }
+
+ public string ListingsId { get; set; }
+
+ public string ZipCode { get; set; }
+
+ public string Country { get; set; }
+
+ public string Path { get; set; }
+
+ public string[] EnabledTuners { get; set; }
+
+ public bool EnableAllTuners { get; set; }
+
+ public string[] NewsCategories { get; set; }
+
+ public string[] SportsCategories { get; set; }
+
+ public string[] KidsCategories { get; set; }
+
+ public string[] MovieCategories { get; set; }
+
+ public NameValuePair[] ChannelMappings { get; set; }
+
+ public string MoviePrefix { get; set; }
+
+ public string PreferredLanguage { get; set; }
+
+ public string UserAgent { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
index bcba344cc5..ca8defd8ba 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
@@ -11,6 +11,12 @@ namespace MediaBrowser.Model.LiveTv
///
public class LiveTvChannelQuery
{
+ public LiveTvChannelQuery()
+ {
+ EnableUserData = true;
+ SortBy = Array.Empty();
+ }
+
///
/// Gets or sets the type of the channel.
///
@@ -48,13 +54,13 @@ namespace MediaBrowser.Model.LiveTv
public Guid UserId { get; set; }
///
- /// Skips over a given number of items within the results. Use for paging.
+ /// gets or sets the start index. Used for paging.
///
/// The start index.
public int? StartIndex { get; set; }
///
- /// The maximum number of items to return.
+ /// Gets or sets the maximum number of items to return.
///
/// The limit.
public int? Limit { get; set; }
@@ -68,15 +74,15 @@ namespace MediaBrowser.Model.LiveTv
public bool EnableUserData { get; set; }
///
- /// Used to specific whether to return news or not.
+ /// Gets or sets a value whether to return news or not.
///
- /// If set to null, all programs will be returned
+ /// If set to null, all programs will be returned.
public bool? IsNews { get; set; }
///
- /// Used to specific whether to return movies or not.
+ /// Gets or sets a value whether to return movies or not.
///
- /// If set to null, all programs will be returned
+ /// If set to null, all programs will be returned.
public bool? IsMovie { get; set; }
///
@@ -96,15 +102,9 @@ namespace MediaBrowser.Model.LiveTv
public string[] SortBy { get; set; }
///
- /// The sort order to return results with.
+ /// Gets or sets the sort order to return results with.
///
/// The sort order.
public SortOrder? SortOrder { get; set; }
-
- public LiveTvChannelQuery()
- {
- EnableUserData = true;
- SortBy = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
index 789de3198a..4cece941cf 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
@@ -2,12 +2,19 @@
#pragma warning disable CS1591
using System;
-using MediaBrowser.Model.Dto;
namespace MediaBrowser.Model.LiveTv
{
public class LiveTvOptions
{
+ public LiveTvOptions()
+ {
+ TunerHosts = Array.Empty();
+ ListingProviders = Array.Empty();
+ MediaLocationsCreated = Array.Empty();
+ RecordingPostProcessorArguments = "\"{path}\"";
+ }
+
public int? GuideDays { get; set; }
public string RecordingPath { get; set; }
@@ -33,93 +40,5 @@ namespace MediaBrowser.Model.LiveTv
public string RecordingPostProcessor { get; set; }
public string RecordingPostProcessorArguments { get; set; }
-
- public LiveTvOptions()
- {
- TunerHosts = Array.Empty();
- ListingProviders = Array.Empty();
- MediaLocationsCreated = Array.Empty();
- RecordingPostProcessorArguments = "\"{path}\"";
- }
- }
-
- public class TunerHostInfo
- {
- public string Id { get; set; }
-
- public string Url { get; set; }
-
- public string Type { get; set; }
-
- public string DeviceId { get; set; }
-
- public string FriendlyName { get; set; }
-
- public bool ImportFavoritesOnly { get; set; }
-
- public bool AllowHWTranscoding { get; set; }
-
- public bool EnableStreamLooping { get; set; }
-
- public string Source { get; set; }
-
- public int TunerCount { get; set; }
-
- public string UserAgent { get; set; }
-
- public TunerHostInfo()
- {
- AllowHWTranscoding = true;
- }
- }
-
- public class ListingsProviderInfo
- {
- public string Id { get; set; }
-
- public string Type { get; set; }
-
- public string Username { get; set; }
-
- public string Password { get; set; }
-
- public string ListingsId { get; set; }
-
- public string ZipCode { get; set; }
-
- public string Country { get; set; }
-
- public string Path { get; set; }
-
- public string[] EnabledTuners { get; set; }
-
- public bool EnableAllTuners { get; set; }
-
- public string[] NewsCategories { get; set; }
-
- public string[] SportsCategories { get; set; }
-
- public string[] KidsCategories { get; set; }
-
- public string[] MovieCategories { get; set; }
-
- public NameValuePair[] ChannelMappings { get; set; }
-
- public string MoviePrefix { get; set; }
-
- public string PreferredLanguage { get; set; }
-
- public string UserAgent { get; set; }
-
- public ListingsProviderInfo()
- {
- NewsCategories = new[] { "news", "journalism", "documentary", "current affairs" };
- SportsCategories = new[] { "sports", "basketball", "baseball", "football" };
- KidsCategories = new[] { "kids", "family", "children", "childrens", "disney" };
- MovieCategories = new[] { "movie" };
- EnabledTuners = Array.Empty();
- EnableAllTuners = true;
- ChannelMappings = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs b/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs
index 856f638c5c..ef5c5d2f31 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs
@@ -10,6 +10,11 @@ namespace MediaBrowser.Model.LiveTv
///
public class LiveTvServiceInfo
{
+ public LiveTvServiceInfo()
+ {
+ Tuners = Array.Empty();
+ }
+
///
/// Gets or sets the name.
///
@@ -53,10 +58,5 @@ namespace MediaBrowser.Model.LiveTv
public bool IsVisible { get; set; }
public string[] Tuners { get; set; }
-
- public LiveTvServiceInfo()
- {
- Tuners = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/LiveTv/RecordingQuery.cs b/MediaBrowser.Model/LiveTv/RecordingQuery.cs
index 69e7db4708..99bb1603c3 100644
--- a/MediaBrowser.Model/LiveTv/RecordingQuery.cs
+++ b/MediaBrowser.Model/LiveTv/RecordingQuery.cs
@@ -12,6 +12,11 @@ namespace MediaBrowser.Model.LiveTv
///
public class RecordingQuery
{
+ public RecordingQuery()
+ {
+ EnableTotalRecordCount = true;
+ }
+
///
/// Gets or sets the channel identifier.
///
@@ -31,13 +36,13 @@ namespace MediaBrowser.Model.LiveTv
public string Id { get; set; }
///
- /// Skips over a given number of items within the results. Use for paging.
+ /// Gets or sets the start index. Use for paging.
///
/// The start index.
public int? StartIndex { get; set; }
///
- /// The maximum number of items to return.
+ /// Gets or sets the maximum number of items to return.
///
/// The limit.
public int? Limit { get; set; }
@@ -61,7 +66,7 @@ namespace MediaBrowser.Model.LiveTv
public string SeriesTimerId { get; set; }
///
- /// Fields to return within the items, in addition to basic information.
+ /// Gets or sets the fields to return within the items, in addition to basic information.
///
/// The fields.
public ItemFields[] Fields { get; set; }
@@ -85,10 +90,5 @@ namespace MediaBrowser.Model.LiveTv
public ImageType[] EnableImageTypes { get; set; }
public bool EnableTotalRecordCount { get; set; }
-
- public RecordingQuery()
- {
- EnableTotalRecordCount = true;
- }
}
}
diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs
index 90422d19c3..b26f5f45fe 100644
--- a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs
+++ b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs
@@ -7,6 +7,14 @@ using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.LiveTv
{
+ public enum KeepUntil
+ {
+ UntilDeleted,
+ UntilSpaceNeeded,
+ UntilWatched,
+ UntilDate
+ }
+
///
/// Class SeriesTimerInfoDto.
///
@@ -83,12 +91,4 @@ namespace MediaBrowser.Model.LiveTv
/// The parent primary image tag.
public string ParentPrimaryImageTag { get; set; }
}
-
- public enum KeepUntil
- {
- UntilDeleted,
- UntilSpaceNeeded,
- UntilWatched,
- UntilDate
- }
}
diff --git a/MediaBrowser.Model/LiveTv/TunerHostInfo.cs b/MediaBrowser.Model/LiveTv/TunerHostInfo.cs
new file mode 100644
index 0000000000..7d4bbb2d07
--- /dev/null
+++ b/MediaBrowser.Model/LiveTv/TunerHostInfo.cs
@@ -0,0 +1,38 @@
+#nullable disable
+#pragma warning disable CS1591
+
+using System;
+using MediaBrowser.Model.Dto;
+
+namespace MediaBrowser.Model.LiveTv
+{
+ public class TunerHostInfo
+ {
+ public TunerHostInfo()
+ {
+ AllowHWTranscoding = true;
+ }
+
+ public string Id { get; set; }
+
+ public string Url { get; set; }
+
+ public string Type { get; set; }
+
+ public string DeviceId { get; set; }
+
+ public string FriendlyName { get; set; }
+
+ public bool ImportFavoritesOnly { get; set; }
+
+ public bool AllowHWTranscoding { get; set; }
+
+ public bool EnableStreamLooping { get; set; }
+
+ public string Source { get; set; }
+
+ public int TunerCount { get; set; }
+
+ public string UserAgent { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index c534286510..b6d9169139 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -17,7 +17,7 @@
net5.0
false
true
- true
+ true
enable
latest
true
@@ -44,7 +44,7 @@
-
+
diff --git a/MediaBrowser.Model/MediaInfo/MediaInfo.cs b/MediaBrowser.Model/MediaInfo/MediaInfo.cs
index 472055c22c..a268a4fa66 100644
--- a/MediaBrowser.Model/MediaInfo/MediaInfo.cs
+++ b/MediaBrowser.Model/MediaInfo/MediaInfo.cs
@@ -10,6 +10,17 @@ namespace MediaBrowser.Model.MediaInfo
{
public class MediaInfo : MediaSourceInfo, IHasProviderIds
{
+ public MediaInfo()
+ {
+ Chapters = Array.Empty();
+ Artists = Array.Empty();
+ AlbumArtists = Array.Empty();
+ Studios = Array.Empty();
+ Genres = Array.Empty();
+ People = Array.Empty();
+ ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ }
+
public ChapterInfo[] Chapters { get; set; }
///
@@ -69,16 +80,5 @@ namespace MediaBrowser.Model.MediaInfo
///
/// The overview.
public string Overview { get; set; }
-
- public MediaInfo()
- {
- Chapters = Array.Empty();
- Artists = Array.Empty();
- AlbumArtists = Array.Empty();
- Studios = Array.Empty();
- Genres = Array.Empty();
- People = Array.Empty();
- ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase);
- }
}
}
diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
index 3216856777..ecd9b8834e 100644
--- a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
+++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
@@ -8,6 +8,17 @@ namespace MediaBrowser.Model.MediaInfo
{
public class PlaybackInfoRequest
{
+ public PlaybackInfoRequest()
+ {
+ EnableDirectPlay = true;
+ EnableDirectStream = true;
+ EnableTranscoding = true;
+ AllowVideoStreamCopy = true;
+ AllowAudioStreamCopy = true;
+ IsPlayback = true;
+ DirectPlayProtocols = new MediaProtocol[] { MediaProtocol.Http };
+ }
+
public Guid Id { get; set; }
public Guid UserId { get; set; }
@@ -43,16 +54,5 @@ namespace MediaBrowser.Model.MediaInfo
public bool AutoOpenLiveStream { get; set; }
public MediaProtocol[] DirectPlayProtocols { get; set; }
-
- public PlaybackInfoRequest()
- {
- EnableDirectPlay = true;
- EnableDirectStream = true;
- EnableTranscoding = true;
- AllowVideoStreamCopy = true;
- AllowAudioStreamCopy = true;
- IsPlayback = true;
- DirectPlayProtocols = new MediaProtocol[] { MediaProtocol.Http };
- }
}
}
diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs
index 2733501822..32971b108f 100644
--- a/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs
+++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs
@@ -10,6 +10,14 @@ namespace MediaBrowser.Model.MediaInfo
///
public class PlaybackInfoResponse
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public PlaybackInfoResponse()
+ {
+ MediaSources = Array.Empty();
+ }
+
///
/// Gets or sets the media sources.
///
@@ -27,13 +35,5 @@ namespace MediaBrowser.Model.MediaInfo
///
/// The error code.
public PlaybackErrorCode? ErrorCode { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public PlaybackInfoResponse()
- {
- MediaSources = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/MediaInfo/SubtitleTrackInfo.cs b/MediaBrowser.Model/MediaInfo/SubtitleTrackInfo.cs
index 37f5c55da6..d5c3a6aec5 100644
--- a/MediaBrowser.Model/MediaInfo/SubtitleTrackInfo.cs
+++ b/MediaBrowser.Model/MediaInfo/SubtitleTrackInfo.cs
@@ -7,11 +7,11 @@ namespace MediaBrowser.Model.MediaInfo
{
public class SubtitleTrackInfo
{
- public IReadOnlyList TrackEvents { get; set; }
-
public SubtitleTrackInfo()
{
TrackEvents = Array.Empty();
}
+
+ public IReadOnlyList TrackEvents { get; set; }
}
}
diff --git a/MediaBrowser.Model/Net/ISocket.cs b/MediaBrowser.Model/Net/ISocket.cs
index 5b6ed92df1..3de41d565a 100644
--- a/MediaBrowser.Model/Net/ISocket.cs
+++ b/MediaBrowser.Model/Net/ISocket.cs
@@ -23,6 +23,12 @@ namespace MediaBrowser.Model.Net
///
/// Sends a UDP message to a particular end point (uni or multicast).
///
+ /// An array of type that contains the data to send.
+ /// The zero-based position in buffer at which to begin sending data.
+ /// The number of bytes to send.
+ /// An that represents the remote device.
+ /// The cancellation token to cancel operation.
+ /// The task object representing the asynchronous operation.
Task SendToAsync(byte[] buffer, int offset, int bytes, IPEndPoint endPoint, CancellationToken cancellationToken);
}
}
diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs
index 363abefc19..1527ef595c 100644
--- a/MediaBrowser.Model/Net/ISocketFactory.cs
+++ b/MediaBrowser.Model/Net/ISocketFactory.cs
@@ -14,6 +14,9 @@ namespace MediaBrowser.Model.Net
///
/// Creates a new unicast socket using the specified local port number.
///
+ /// The local IP address to bind to.
+ /// The local port to bind to.
+ /// A new unicast socket using the specified local port number.
ISocket CreateSsdpUdpSocket(IPAddress localIp, int localPort);
///
diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs
index 902db1e9e5..96f5ab51ae 100644
--- a/MediaBrowser.Model/Net/MimeTypes.cs
+++ b/MediaBrowser.Model/Net/MimeTypes.cs
@@ -91,9 +91,9 @@ namespace MediaBrowser.Model.Net
{ ".webp", "image/webp" },
// Type font
- { ".ttf" , "font/ttf" },
- { ".woff" , "font/woff" },
- { ".woff2" , "font/woff2" },
+ { ".ttf", "font/ttf" },
+ { ".woff", "font/woff" },
+ { ".woff2", "font/woff2" },
// Type text
{ ".ass", "text/x-ssa" },
@@ -168,14 +168,17 @@ namespace MediaBrowser.Model.Net
///
/// Gets the type of the MIME.
///
- public static string? GetMimeType(string path, bool enableStreamDefault)
+ /// The filename to find the MIME type of.
+ /// Whether of not to return a default value if no fitting MIME type is found.
+ /// The worrect MIME type for the given filename, or `null` if it wasn't found and is false.
+ public static string? GetMimeType(string filename, bool enableStreamDefault)
{
- if (path.Length == 0)
+ if (filename.Length == 0)
{
- throw new ArgumentException("String can't be empty.", nameof(path));
+ throw new ArgumentException("String can't be empty.", nameof(filename));
}
- var ext = Path.GetExtension(path);
+ var ext = Path.GetExtension(filename);
if (_mimeTypeLookup.TryGetValue(ext, out string? result))
{
@@ -210,9 +213,9 @@ namespace MediaBrowser.Model.Net
return enableStreamDefault ? "application/octet-stream" : null;
}
- public static string? ToExtension(string? mimeType)
+ public static string? ToExtension(string mimeType)
{
- if (string.IsNullOrEmpty(mimeType))
+ if (mimeType.Length == 0)
{
throw new ArgumentException("String can't be empty.", nameof(mimeType));
}
diff --git a/MediaBrowser.Model/Net/NetworkShare.cs b/MediaBrowser.Model/Net/NetworkShare.cs
deleted file mode 100644
index 6344cbe21e..0000000000
--- a/MediaBrowser.Model/Net/NetworkShare.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-#nullable disable
-#pragma warning disable CS1591
-
-namespace MediaBrowser.Model.Net
-{
- public class NetworkShare
- {
- ///
- /// The name of the computer that this share belongs to.
- ///
- public string Server { get; set; }
-
- ///
- /// Share name.
- ///
- public string Name { get; set; }
-
- ///
- /// Local path.
- ///
- public string Path { get; set; }
-
- ///
- /// Share type.
- ///
- public NetworkShareType ShareType { get; set; }
-
- ///
- /// Comment.
- ///
- public string Remark { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/Net/SocketReceiveResult.cs b/MediaBrowser.Model/Net/SocketReceiveResult.cs
index 54139fe9c5..1524786ea7 100644
--- a/MediaBrowser.Model/Net/SocketReceiveResult.cs
+++ b/MediaBrowser.Model/Net/SocketReceiveResult.cs
@@ -20,12 +20,12 @@ namespace MediaBrowser.Model.Net
public int ReceivedBytes { get; set; }
///
- /// The the data was received from.
+ /// Gets or sets the the data was received from.
///
public IPEndPoint RemoteEndPoint { get; set; }
///
- /// The local .
+ /// Gets or sets the local .
///
public IPAddress LocalIPAddress { get; set; }
}
diff --git a/MediaBrowser.Model/Net/WebSocketMessage.cs b/MediaBrowser.Model/Net/WebSocketMessage.cs
index bffbbe612d..b00158cb33 100644
--- a/MediaBrowser.Model/Net/WebSocketMessage.cs
+++ b/MediaBrowser.Model/Net/WebSocketMessage.cs
@@ -9,7 +9,7 @@ namespace MediaBrowser.Model.Net
///
/// Class WebSocketMessage.
///
- ///
+ /// The type of the data.
public class WebSocketMessage
{
///
diff --git a/MediaBrowser.Model/Notifications/NotificationOptions.cs b/MediaBrowser.Model/Notifications/NotificationOptions.cs
index 239a3777e1..94bb5d6e35 100644
--- a/MediaBrowser.Model/Notifications/NotificationOptions.cs
+++ b/MediaBrowser.Model/Notifications/NotificationOptions.cs
@@ -2,18 +2,16 @@
#pragma warning disable CS1591
using System;
-using Jellyfin.Data.Enums;
-using MediaBrowser.Model.Extensions;
using System.Linq;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
+using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Users;
namespace MediaBrowser.Model.Notifications
{
public class NotificationOptions
{
- public NotificationOption[] Options { get; set; }
-
public NotificationOptions()
{
Options = new[]
@@ -71,6 +69,8 @@ namespace MediaBrowser.Model.Notifications
};
}
+ public NotificationOption[] Options { get; set; }
+
public NotificationOption GetOptions(string type)
{
foreach (NotificationOption i in Options)
@@ -104,7 +104,7 @@ namespace MediaBrowser.Model.Notifications
NotificationOption opt = GetOptions(type);
return opt != null && opt.Enabled &&
- !opt.DisabledMonitorUsers.Contains(userId.ToString(""), StringComparer.OrdinalIgnoreCase);
+ !opt.DisabledMonitorUsers.Contains(userId.ToString(string.Empty), StringComparer.OrdinalIgnoreCase);
}
public bool IsEnabledToSendToUser(string type, string userId, User user)
diff --git a/MediaBrowser.Model/Notifications/NotificationRequest.cs b/MediaBrowser.Model/Notifications/NotificationRequest.cs
index febc2bc099..622c50cd88 100644
--- a/MediaBrowser.Model/Notifications/NotificationRequest.cs
+++ b/MediaBrowser.Model/Notifications/NotificationRequest.cs
@@ -7,6 +7,12 @@ namespace MediaBrowser.Model.Notifications
{
public class NotificationRequest
{
+ public NotificationRequest()
+ {
+ UserIds = Array.Empty();
+ Date = DateTime.UtcNow;
+ }
+
public string Name { get; set; }
public string Description { get; set; }
@@ -20,16 +26,10 @@ namespace MediaBrowser.Model.Notifications
public DateTime Date { get; set; }
///
- /// The corresponding type name used in configuration. Not for display.
+ /// Gets or sets the corresponding type name used in configuration. Not for display.
///
public string NotificationType { get; set; }
public SendToUserType? SendToUserMode { get; set; }
-
- public NotificationRequest()
- {
- UserIds = Array.Empty();
- Date = DateTime.UtcNow;
- }
}
}
diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs
index afe95e6eee..0ea3e96cae 100644
--- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs
+++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs
@@ -6,11 +6,11 @@ namespace MediaBrowser.Model.Providers
public class ExternalIdInfo
{
///
- /// Represents the external id information for serialization to the client.
+ /// Initializes a new instance of the class.
///
/// Name of the external id provider (IE: IMDB, MusicBrainz, etc).
/// Key for this id. This key should be unique across all providers.
- /// Specific media type for this id
+ /// Specific media type for this id.
/// URL format string.
public ExternalIdInfo(string name, string key, ExternalIdMediaType? type, string urlFormatString)
{
diff --git a/MediaBrowser.Model/Providers/RemoteImageInfo.cs b/MediaBrowser.Model/Providers/RemoteImageInfo.cs
index fb25999e0a..48207d2d41 100644
--- a/MediaBrowser.Model/Providers/RemoteImageInfo.cs
+++ b/MediaBrowser.Model/Providers/RemoteImageInfo.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Model.Providers
public string Url { get; set; }
///
- /// Gets a url used for previewing a smaller version.
+ /// Gets or sets a url used for previewing a smaller version.
///
public string ThumbnailUrl { get; set; }
diff --git a/MediaBrowser.Model/Providers/SubtitleOptions.cs b/MediaBrowser.Model/Providers/SubtitleOptions.cs
index 5702c460b0..6ea1e14862 100644
--- a/MediaBrowser.Model/Providers/SubtitleOptions.cs
+++ b/MediaBrowser.Model/Providers/SubtitleOptions.cs
@@ -7,6 +7,14 @@ namespace MediaBrowser.Model.Providers
{
public class SubtitleOptions
{
+ public SubtitleOptions()
+ {
+ DownloadLanguages = Array.Empty();
+
+ SkipIfAudioTrackMatches = true;
+ RequirePerfectMatch = true;
+ }
+
public bool SkipIfEmbeddedSubtitlesPresent { get; set; }
public bool SkipIfAudioTrackMatches { get; set; }
@@ -24,13 +32,5 @@ namespace MediaBrowser.Model.Providers
public bool IsOpenSubtitleVipAccount { get; set; }
public bool RequirePerfectMatch { get; set; }
-
- public SubtitleOptions()
- {
- DownloadLanguages = Array.Empty();
-
- SkipIfAudioTrackMatches = true;
- RequirePerfectMatch = true;
- }
}
}
diff --git a/MediaBrowser.Model/Querying/EpisodeQuery.cs b/MediaBrowser.Model/Querying/EpisodeQuery.cs
index 13b1a0dcbf..56a7f33201 100644
--- a/MediaBrowser.Model/Querying/EpisodeQuery.cs
+++ b/MediaBrowser.Model/Querying/EpisodeQuery.cs
@@ -7,6 +7,11 @@ namespace MediaBrowser.Model.Querying
{
public class EpisodeQuery
{
+ public EpisodeQuery()
+ {
+ Fields = Array.Empty();
+ }
+
///
/// Gets or sets the user identifier.
///
@@ -66,10 +71,5 @@ namespace MediaBrowser.Model.Querying
///
/// The start item identifier.
public string StartItemId { get; set; }
-
- public EpisodeQuery()
- {
- Fields = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Querying/LatestItemsQuery.cs b/MediaBrowser.Model/Querying/LatestItemsQuery.cs
index 7954ef4b43..f555ffb36d 100644
--- a/MediaBrowser.Model/Querying/LatestItemsQuery.cs
+++ b/MediaBrowser.Model/Querying/LatestItemsQuery.cs
@@ -14,31 +14,32 @@ namespace MediaBrowser.Model.Querying
}
///
- /// The user to localize search results for.
+ /// Gets or sets the user to localize search results for.
///
/// The user id.
public Guid UserId { get; set; }
///
+ /// Gets or sets the parent id.
/// Specify this to localize the search to a specific item or folder. Omit to use the root.
///
/// The parent id.
public Guid ParentId { get; set; }
///
- /// Skips over a given number of items within the results. Use for paging.
+ /// Gets or sets the start index. Used for paging.
///
/// The start index.
public int? StartIndex { get; set; }
///
- /// The maximum number of items to return.
+ /// Gets or sets the maximum number of items to return.
///
/// The limit.
public int? Limit { get; set; }
///
- /// Fields to return within the items, in addition to basic information.
+ /// Gets or sets the fields to return within the items, in addition to basic information.
///
/// The fields.
public ItemFields[] Fields { get; set; }
diff --git a/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs b/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs
index 1c8875890a..b800f5de5f 100644
--- a/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs
+++ b/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs
@@ -7,6 +7,13 @@ namespace MediaBrowser.Model.Querying
{
public class MovieRecommendationQuery
{
+ public MovieRecommendationQuery()
+ {
+ ItemLimit = 10;
+ CategoryLimit = 6;
+ Fields = Array.Empty();
+ }
+
///
/// Gets or sets the user identifier.
///
@@ -36,12 +43,5 @@ namespace MediaBrowser.Model.Querying
///
/// The fields.
public ItemFields[] Fields { get; set; }
-
- public MovieRecommendationQuery()
- {
- ItemLimit = 10;
- CategoryLimit = 6;
- Fields = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Querying/NextUpQuery.cs b/MediaBrowser.Model/Querying/NextUpQuery.cs
index 001d0623cc..0555afc00d 100644
--- a/MediaBrowser.Model/Querying/NextUpQuery.cs
+++ b/MediaBrowser.Model/Querying/NextUpQuery.cs
@@ -8,6 +8,13 @@ namespace MediaBrowser.Model.Querying
{
public class NextUpQuery
{
+ public NextUpQuery()
+ {
+ EnableImageTypes = Array.Empty();
+ EnableTotalRecordCount = true;
+ DisableFirstEpisode = false;
+ }
+
///
/// Gets or sets the user id.
///
@@ -27,19 +34,19 @@ namespace MediaBrowser.Model.Querying
public string SeriesId { get; set; }
///
- /// Skips over a given number of items within the results. Use for paging.
+ /// Gets or sets the start index. Use for paging.
///
/// The start index.
public int? StartIndex { get; set; }
///
- /// The maximum number of items to return.
+ /// Gets or sets the maximum number of items to return.
///
/// The limit.
public int? Limit { get; set; }
///
- /// Fields to return within the items, in addition to basic information.
+ /// gets or sets the fields to return within the items, in addition to basic information.
///
/// The fields.
public ItemFields[] Fields { get; set; }
@@ -68,12 +75,5 @@ namespace MediaBrowser.Model.Querying
/// Gets or sets a value indicating whether do disable sending first episode as next up.
///
public bool DisableFirstEpisode { get; set; }
-
- public NextUpQuery()
- {
- EnableImageTypes = Array.Empty();
- EnableTotalRecordCount = true;
- DisableFirstEpisode = false;
- }
}
}
diff --git a/MediaBrowser.Model/Querying/QueryFilters.cs b/MediaBrowser.Model/Querying/QueryFilters.cs
index 6e4d251818..73b27a7b06 100644
--- a/MediaBrowser.Model/Querying/QueryFilters.cs
+++ b/MediaBrowser.Model/Querying/QueryFilters.cs
@@ -6,35 +6,16 @@ using MediaBrowser.Model.Dto;
namespace MediaBrowser.Model.Querying
{
- public class QueryFiltersLegacy
+ public class QueryFilters
{
- public string[] Genres { get; set; }
-
- public string[] Tags { get; set; }
-
- public string[] OfficialRatings { get; set; }
-
- public int[] Years { get; set; }
-
- public QueryFiltersLegacy()
+ public QueryFilters()
{
- Genres = Array.Empty();
Tags = Array.Empty();
- OfficialRatings = Array.Empty();
- Years = Array.Empty();
+ Genres = Array.Empty();
}
- }
- public class QueryFilters
- {
public NameGuidPair[] Genres { get; set; }
public string[] Tags { get; set; }
-
- public QueryFilters()
- {
- Tags = Array.Empty();
- Genres = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Querying/QueryFiltersLegacy.cs b/MediaBrowser.Model/Querying/QueryFiltersLegacy.cs
new file mode 100644
index 0000000000..fcb450ed30
--- /dev/null
+++ b/MediaBrowser.Model/Querying/QueryFiltersLegacy.cs
@@ -0,0 +1,26 @@
+#nullable disable
+#pragma warning disable CS1591
+
+using System;
+
+namespace MediaBrowser.Model.Querying
+{
+ public class QueryFiltersLegacy
+ {
+ public QueryFiltersLegacy()
+ {
+ Genres = Array.Empty();
+ Tags = Array.Empty();
+ OfficialRatings = Array.Empty();
+ Years = Array.Empty();
+ }
+
+ public string[] Genres { get; set; }
+
+ public string[] Tags { get; set; }
+
+ public string[] OfficialRatings { get; set; }
+
+ public int[] Years { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Querying/QueryResult.cs b/MediaBrowser.Model/Querying/QueryResult.cs
index 490f48b84b..8ce794800b 100644
--- a/MediaBrowser.Model/Querying/QueryResult.cs
+++ b/MediaBrowser.Model/Querying/QueryResult.cs
@@ -8,6 +8,17 @@ namespace MediaBrowser.Model.Querying
{
public class QueryResult
{
+ public QueryResult()
+ {
+ Items = Array.Empty();
+ }
+
+ public QueryResult(IReadOnlyList items)
+ {
+ Items = items;
+ TotalRecordCount = items.Count;
+ }
+
///
/// Gets or sets the items.
///
@@ -15,26 +26,15 @@ namespace MediaBrowser.Model.Querying
public IReadOnlyList Items { get; set; }
///
- /// The total number of records available.
+ /// Gets or sets the total number of records available.
///
/// The total record count.
public int TotalRecordCount { get; set; }
///
- /// The index of the first record in Items.
+ /// Gets or sets the index of the first record in Items.
///
/// First record index.
public int StartIndex { get; set; }
-
- public QueryResult()
- {
- Items = Array.Empty();
- }
-
- public QueryResult(IReadOnlyList items)
- {
- Items = items;
- TotalRecordCount = items.Count;
- }
}
}
diff --git a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
index eb62394605..2cf0f0d5f8 100644
--- a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
+++ b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
@@ -8,6 +8,11 @@ namespace MediaBrowser.Model.Querying
{
public class UpcomingEpisodesQuery
{
+ public UpcomingEpisodesQuery()
+ {
+ EnableImageTypes = Array.Empty();
+ }
+
///
/// Gets or sets the user id.
///
@@ -21,19 +26,19 @@ namespace MediaBrowser.Model.Querying
public string ParentId { get; set; }
///
- /// Skips over a given number of items within the results. Use for paging.
+ /// Gets or sets the start index. Use for paging.
///
/// The start index.
public int? StartIndex { get; set; }
///
- /// The maximum number of items to return.
+ /// Gets or sets the maximum number of items to return.
///
/// The limit.
public int? Limit { get; set; }
///
- /// Fields to return within the items, in addition to basic information.
+ /// Gets or sets the fields to return within the items, in addition to basic information.
///
/// The fields.
public ItemFields[] Fields { get; set; }
@@ -55,10 +60,5 @@ namespace MediaBrowser.Model.Querying
///
/// The enable image types.
public ImageType[] EnableImageTypes { get; set; }
-
- public UpcomingEpisodesQuery()
- {
- EnableImageTypes = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Search/SearchQuery.cs b/MediaBrowser.Model/Search/SearchQuery.cs
index ce60062cd3..aedfa4d363 100644
--- a/MediaBrowser.Model/Search/SearchQuery.cs
+++ b/MediaBrowser.Model/Search/SearchQuery.cs
@@ -7,8 +7,21 @@ namespace MediaBrowser.Model.Search
{
public class SearchQuery
{
+ public SearchQuery()
+ {
+ IncludeArtists = true;
+ IncludeGenres = true;
+ IncludeMedia = true;
+ IncludePeople = true;
+ IncludeStudios = true;
+
+ MediaTypes = Array.Empty();
+ IncludeItemTypes = Array.Empty();
+ ExcludeItemTypes = Array.Empty();
+ }
+
///
- /// The user to localize search results for.
+ /// Gets or sets the user to localize search results for.
///
/// The user id.
public Guid UserId { get; set; }
@@ -20,13 +33,13 @@ namespace MediaBrowser.Model.Search
public string SearchTerm { get; set; }
///
- /// Skips over a given number of items within the results. Use for paging.
+ /// Gets or sets the start index. Used for paging.
///
/// The start index.
public int? StartIndex { get; set; }
///
- /// The maximum number of items to return.
+ /// Gets or sets the maximum number of items to return.
///
/// The limit.
public int? Limit { get; set; }
@@ -58,18 +71,5 @@ namespace MediaBrowser.Model.Search
public bool? IsKids { get; set; }
public bool? IsSports { get; set; }
-
- public SearchQuery()
- {
- IncludeArtists = true;
- IncludeGenres = true;
- IncludeMedia = true;
- IncludePeople = true;
- IncludeStudios = true;
-
- MediaTypes = Array.Empty();
- IncludeItemTypes = Array.Empty();
- ExcludeItemTypes = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Session/BrowseRequest.cs b/MediaBrowser.Model/Session/BrowseRequest.cs
index 1c997d5846..65afe5cf34 100644
--- a/MediaBrowser.Model/Session/BrowseRequest.cs
+++ b/MediaBrowser.Model/Session/BrowseRequest.cs
@@ -7,6 +7,7 @@ namespace MediaBrowser.Model.Session
public class BrowseRequest
{
///
+ /// Gets or sets the item type.
/// Artist, Genre, Studio, Person, or any kind of BaseItem.
///
/// The type of the item.
diff --git a/MediaBrowser.Model/Session/ClientCapabilities.cs b/MediaBrowser.Model/Session/ClientCapabilities.cs
index 5852f4e37a..d692906c64 100644
--- a/MediaBrowser.Model/Session/ClientCapabilities.cs
+++ b/MediaBrowser.Model/Session/ClientCapabilities.cs
@@ -9,6 +9,13 @@ namespace MediaBrowser.Model.Session
{
public class ClientCapabilities
{
+ public ClientCapabilities()
+ {
+ PlayableMediaTypes = Array.Empty();
+ SupportedCommands = Array.Empty();
+ SupportsPersistentIdentifier = true;
+ }
+
public IReadOnlyList PlayableMediaTypes { get; set; }
public IReadOnlyList SupportedCommands { get; set; }
@@ -28,12 +35,5 @@ namespace MediaBrowser.Model.Session
public string AppStoreUrl { get; set; }
public string IconUrl { get; set; }
-
- public ClientCapabilities()
- {
- PlayableMediaTypes = Array.Empty();
- SupportedCommands = Array.Empty();
- SupportsPersistentIdentifier = true;
- }
}
}
diff --git a/MediaBrowser.Model/Session/GeneralCommand.cs b/MediaBrowser.Model/Session/GeneralCommand.cs
index 77bb6bcf77..29528c1106 100644
--- a/MediaBrowser.Model/Session/GeneralCommand.cs
+++ b/MediaBrowser.Model/Session/GeneralCommand.cs
@@ -1,4 +1,3 @@
-#nullable disable
#pragma warning disable CS1591
using System;
@@ -8,15 +7,15 @@ namespace MediaBrowser.Model.Session
{
public class GeneralCommand
{
- public GeneralCommandType Name { get; set; }
-
- public Guid ControllingUserId { get; set; }
-
- public Dictionary Arguments { get; set; }
-
public GeneralCommand()
{
Arguments = new Dictionary();
}
+
+ public GeneralCommandType Name { get; set; }
+
+ public Guid ControllingUserId { get; set; }
+
+ public Dictionary Arguments { get; }
}
}
diff --git a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs
index 73dbe6a2da..a6e7efcb0c 100644
--- a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs
+++ b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs
@@ -111,18 +111,4 @@ namespace MediaBrowser.Model.Session
public string PlaylistItemId { get; set; }
}
-
- public enum RepeatMode
- {
- RepeatNone = 0,
- RepeatAll = 1,
- RepeatOne = 2
- }
-
- public class QueueItem
- {
- public Guid Id { get; set; }
-
- public string PlaylistItemId { get; set; }
- }
}
diff --git a/MediaBrowser.Model/Session/PlaystateCommand.cs b/MediaBrowser.Model/Session/PlaystateCommand.cs
index 3aa091f791..df47f3b73d 100644
--- a/MediaBrowser.Model/Session/PlaystateCommand.cs
+++ b/MediaBrowser.Model/Session/PlaystateCommand.cs
@@ -1,5 +1,3 @@
-#pragma warning disable CS1591
-
namespace MediaBrowser.Model.Session
{
///
@@ -46,6 +44,10 @@ namespace MediaBrowser.Model.Session
/// The fast forward.
///
FastForward,
+
+ ///
+ /// The play pause.
+ ///
PlayPause
}
}
diff --git a/MediaBrowser.Model/Session/QueueItem.cs b/MediaBrowser.Model/Session/QueueItem.cs
new file mode 100644
index 0000000000..32b19101b2
--- /dev/null
+++ b/MediaBrowser.Model/Session/QueueItem.cs
@@ -0,0 +1,14 @@
+#nullable disable
+#pragma warning disable CS1591
+
+using System;
+
+namespace MediaBrowser.Model.Session
+{
+ public class QueueItem
+ {
+ public Guid Id { get; set; }
+
+ public string PlaylistItemId { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Session/RepeatMode.cs b/MediaBrowser.Model/Session/RepeatMode.cs
new file mode 100644
index 0000000000..c6e173d6b8
--- /dev/null
+++ b/MediaBrowser.Model/Session/RepeatMode.cs
@@ -0,0 +1,11 @@
+#pragma warning disable CS1591
+
+namespace MediaBrowser.Model.Session
+{
+ public enum RepeatMode
+ {
+ RepeatNone = 0,
+ RepeatAll = 1,
+ RepeatOne = 2
+ }
+}
diff --git a/MediaBrowser.Model/Session/TranscodeReason.cs b/MediaBrowser.Model/Session/TranscodeReason.cs
new file mode 100644
index 0000000000..e93b5d2882
--- /dev/null
+++ b/MediaBrowser.Model/Session/TranscodeReason.cs
@@ -0,0 +1,31 @@
+#pragma warning disable CS1591
+
+namespace MediaBrowser.Model.Session
+{
+ public enum TranscodeReason
+ {
+ ContainerNotSupported = 0,
+ VideoCodecNotSupported = 1,
+ AudioCodecNotSupported = 2,
+ ContainerBitrateExceedsLimit = 3,
+ AudioBitrateNotSupported = 4,
+ AudioChannelsNotSupported = 5,
+ VideoResolutionNotSupported = 6,
+ UnknownVideoStreamInfo = 7,
+ UnknownAudioStreamInfo = 8,
+ AudioProfileNotSupported = 9,
+ AudioSampleRateNotSupported = 10,
+ AnamorphicVideoNotSupported = 11,
+ InterlacedVideoNotSupported = 12,
+ SecondaryAudioNotSupported = 13,
+ RefFramesNotSupported = 14,
+ VideoBitDepthNotSupported = 15,
+ VideoBitrateNotSupported = 16,
+ VideoFramerateNotSupported = 17,
+ VideoLevelNotSupported = 18,
+ VideoProfileNotSupported = 19,
+ AudioBitDepthNotSupported = 20,
+ SubtitleCodecNotSupported = 21,
+ DirectPlayError = 22
+ }
+}
diff --git a/MediaBrowser.Model/Session/TranscodingInfo.cs b/MediaBrowser.Model/Session/TranscodingInfo.cs
index e832c2f6fa..064a087d5d 100644
--- a/MediaBrowser.Model/Session/TranscodingInfo.cs
+++ b/MediaBrowser.Model/Session/TranscodingInfo.cs
@@ -7,6 +7,11 @@ namespace MediaBrowser.Model.Session
{
public class TranscodingInfo
{
+ public TranscodingInfo()
+ {
+ TranscodeReasons = Array.Empty();
+ }
+
public string AudioCodec { get; set; }
public string VideoCodec { get; set; }
@@ -30,37 +35,5 @@ namespace MediaBrowser.Model.Session
public int? AudioChannels { get; set; }
public TranscodeReason[] TranscodeReasons { get; set; }
-
- public TranscodingInfo()
- {
- TranscodeReasons = Array.Empty();
- }
- }
-
- public enum TranscodeReason
- {
- ContainerNotSupported = 0,
- VideoCodecNotSupported = 1,
- AudioCodecNotSupported = 2,
- ContainerBitrateExceedsLimit = 3,
- AudioBitrateNotSupported = 4,
- AudioChannelsNotSupported = 5,
- VideoResolutionNotSupported = 6,
- UnknownVideoStreamInfo = 7,
- UnknownAudioStreamInfo = 8,
- AudioProfileNotSupported = 9,
- AudioSampleRateNotSupported = 10,
- AnamorphicVideoNotSupported = 11,
- InterlacedVideoNotSupported = 12,
- SecondaryAudioNotSupported = 13,
- RefFramesNotSupported = 14,
- VideoBitDepthNotSupported = 15,
- VideoBitrateNotSupported = 16,
- VideoFramerateNotSupported = 17,
- VideoLevelNotSupported = 18,
- VideoProfileNotSupported = 19,
- AudioBitDepthNotSupported = 20,
- SubtitleCodecNotSupported = 21,
- DirectPlayError = 22
}
}
diff --git a/MediaBrowser.Model/Sync/SyncJob.cs b/MediaBrowser.Model/Sync/SyncJob.cs
index b9290b6e83..3e396e5d13 100644
--- a/MediaBrowser.Model/Sync/SyncJob.cs
+++ b/MediaBrowser.Model/Sync/SyncJob.cs
@@ -7,6 +7,11 @@ namespace MediaBrowser.Model.Sync
{
public class SyncJob
{
+ public SyncJob()
+ {
+ RequestedItemIds = Array.Empty();
+ }
+
///
/// Gets or sets the identifier.
///
@@ -126,10 +131,5 @@ namespace MediaBrowser.Model.Sync
public string PrimaryImageItemId { get; set; }
public string PrimaryImageTag { get; set; }
-
- public SyncJob()
- {
- RequestedItemIds = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs
index 4b83fb7e61..d75ae91c02 100644
--- a/MediaBrowser.Model/System/SystemInfo.cs
+++ b/MediaBrowser.Model/System/SystemInfo.cs
@@ -30,6 +30,14 @@ namespace MediaBrowser.Model.System
///
public class SystemInfo : PublicSystemInfo
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SystemInfo()
+ {
+ CompletedInstallations = Array.Empty();
+ }
+
///
/// Gets or sets the display name of the operating system.
///
@@ -37,7 +45,7 @@ namespace MediaBrowser.Model.System
public string OperatingSystemDisplayName { get; set; }
///
- /// Get or sets the package name.
+ /// Gets or sets the package name.
///
/// The value of the '-package' command line argument.
public string PackageName { get; set; }
@@ -127,13 +135,5 @@ namespace MediaBrowser.Model.System
public FFmpegLocation EncoderLocation { get; set; }
public Architecture SystemArchitecture { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public SystemInfo()
- {
- CompletedInstallations = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/System/WakeOnLanInfo.cs b/MediaBrowser.Model/System/WakeOnLanInfo.cs
index b2cbe737d1..aba19a6baf 100644
--- a/MediaBrowser.Model/System/WakeOnLanInfo.cs
+++ b/MediaBrowser.Model/System/WakeOnLanInfo.cs
@@ -36,7 +36,7 @@ namespace MediaBrowser.Model.System
/// Gets the MAC address of the device.
///
/// The MAC address.
- public string? MacAddress { get; set; }
+ public string? MacAddress { get; }
///
/// Gets or sets the wake-on-LAN port.
diff --git a/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs b/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs
index 2f05e08c51..ca769e26b3 100644
--- a/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs
+++ b/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs
@@ -15,7 +15,7 @@ namespace MediaBrowser.Model.Tasks
event EventHandler> TaskProgress;
///
- /// Gets or sets the scheduled task.
+ /// Gets the scheduled task.
///
/// The scheduled task.
IScheduledTask ScheduledTask { get; }
@@ -57,10 +57,9 @@ namespace MediaBrowser.Model.Tasks
double? CurrentProgress { get; }
///
- /// Gets the triggers that define when the task will run.
+ /// Gets or sets the triggers that define when the task will run.
///
/// The triggers.
- /// value
TaskTriggerInfo[] Triggers { get; set; }
///
diff --git a/MediaBrowser.Model/Tasks/ITaskManager.cs b/MediaBrowser.Model/Tasks/ITaskManager.cs
index 02b29074e3..a86bf2a1c8 100644
--- a/MediaBrowser.Model/Tasks/ITaskManager.cs
+++ b/MediaBrowser.Model/Tasks/ITaskManager.cs
@@ -9,6 +9,10 @@ namespace MediaBrowser.Model.Tasks
{
public interface ITaskManager : IDisposable
{
+ event EventHandler> TaskExecuting;
+
+ event EventHandler TaskCompleted;
+
///
/// Gets the list of Scheduled Tasks.
///
@@ -18,7 +22,7 @@ namespace MediaBrowser.Model.Tasks
///
/// Cancels if running and queue.
///
- ///
+ /// An implementatin of .
/// Task options.
void CancelIfRunningAndQueue(TaskOptions options)
where T : IScheduledTask;
@@ -26,21 +30,21 @@ namespace MediaBrowser.Model.Tasks
///
/// Cancels if running and queue.
///
- ///
+ /// An implementatin of .
void CancelIfRunningAndQueue()
where T : IScheduledTask;
///
/// Cancels if running.
///
- ///
+ /// An implementatin of .
void CancelIfRunning()
where T : IScheduledTask;
///
/// Queues the scheduled task.
///
- ///
+ /// An implementatin of .
/// Task options.
void QueueScheduledTask(TaskOptions options)
where T : IScheduledTask;
@@ -48,7 +52,7 @@ namespace MediaBrowser.Model.Tasks
///
/// Queues the scheduled task.
///
- ///
+ /// An implementatin of .
void QueueScheduledTask()
where T : IScheduledTask;
@@ -58,6 +62,8 @@ namespace MediaBrowser.Model.Tasks
///
/// Queues the scheduled task.
///
+ /// The to queue.
+ /// The to use.
void QueueScheduledTask(IScheduledTask task, TaskOptions options);
///
@@ -67,12 +73,10 @@ namespace MediaBrowser.Model.Tasks
void AddTasks(IEnumerable tasks);
void Cancel(IScheduledTaskWorker task);
+
Task Execute(IScheduledTaskWorker task, TaskOptions options);
void Execute()
where T : IScheduledTask;
-
- event EventHandler> TaskExecuting;
- event EventHandler TaskCompleted;
}
}
diff --git a/MediaBrowser.Model/Tasks/ITaskTrigger.cs b/MediaBrowser.Model/Tasks/ITaskTrigger.cs
index 5c30d6c220..cbd60cca18 100644
--- a/MediaBrowser.Model/Tasks/ITaskTrigger.cs
+++ b/MediaBrowser.Model/Tasks/ITaskTrigger.cs
@@ -21,6 +21,10 @@ namespace MediaBrowser.Model.Tasks
///
/// Stars waiting for the trigger action.
///
+ /// Result of the last run triggerd task.
+ /// The .
+ /// The name of the task.
+ /// Wheter or not this is is fired during startup.
void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup);
///
diff --git a/MediaBrowser.Model/Tasks/TaskInfo.cs b/MediaBrowser.Model/Tasks/TaskInfo.cs
index 77100dfe76..16de0b1210 100644
--- a/MediaBrowser.Model/Tasks/TaskInfo.cs
+++ b/MediaBrowser.Model/Tasks/TaskInfo.cs
@@ -8,6 +8,14 @@ namespace MediaBrowser.Model.Tasks
///
public class TaskInfo
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TaskInfo()
+ {
+ Triggers = Array.Empty();
+ }
+
///
/// Gets or sets the name.
///
@@ -67,13 +75,5 @@ namespace MediaBrowser.Model.Tasks
///
/// The key.
public string Key { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public TaskInfo()
- {
- Triggers = Array.Empty();
- }
}
}
diff --git a/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs b/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs
index 5aeaffc2b3..f8a8c727ef 100644
--- a/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs
+++ b/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs
@@ -10,6 +10,12 @@ namespace MediaBrowser.Model.Tasks
///
public class TaskTriggerInfo
{
+ public const string TriggerDaily = "DailyTrigger";
+ public const string TriggerWeekly = "WeeklyTrigger";
+ public const string TriggerInterval = "IntervalTrigger";
+ public const string TriggerSystemEvent = "SystemEventTrigger";
+ public const string TriggerStartup = "StartupTrigger";
+
///
/// Gets or sets the type.
///
@@ -39,11 +45,5 @@ namespace MediaBrowser.Model.Tasks
///
/// The maximum runtime ticks.
public long? MaxRuntimeTicks { get; set; }
-
- public const string TriggerDaily = "DailyTrigger";
- public const string TriggerWeekly = "WeeklyTrigger";
- public const string TriggerInterval = "IntervalTrigger";
- public const string TriggerSystemEvent = "SystemEventTrigger";
- public const string TriggerStartup = "StartupTrigger";
}
}
diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs
index 37da04adf7..111070d813 100644
--- a/MediaBrowser.Model/Users/UserPolicy.cs
+++ b/MediaBrowser.Model/Users/UserPolicy.cs
@@ -10,6 +10,56 @@ namespace MediaBrowser.Model.Users
{
public class UserPolicy
{
+ public UserPolicy()
+ {
+ IsHidden = true;
+
+ EnableContentDeletion = false;
+ EnableContentDeletionFromFolders = Array.Empty();
+
+ EnableSyncTranscoding = true;
+ EnableMediaConversion = true;
+
+ EnableMediaPlayback = true;
+ EnableAudioPlaybackTranscoding = true;
+ EnableVideoPlaybackTranscoding = true;
+ EnablePlaybackRemuxing = true;
+ ForceRemoteSourceTranscoding = false;
+ EnableLiveTvManagement = true;
+ EnableLiveTvAccess = true;
+
+ // Without this on by default, admins won't be able to do this
+ // Improve in the future
+ EnableLiveTvManagement = true;
+
+ EnableSharedDeviceControl = true;
+
+ BlockedTags = Array.Empty();
+ BlockUnratedItems = Array.Empty();
+
+ EnableUserPreferenceAccess = true;
+
+ AccessSchedules = Array.Empty();
+
+ LoginAttemptsBeforeLockout = -1;
+
+ MaxActiveSessions = 0;
+
+ EnableAllChannels = true;
+ EnabledChannels = Array.Empty();
+
+ EnableAllFolders = true;
+ EnabledFolders = Array.Empty();
+
+ EnabledDevices = Array.Empty();
+ EnableAllDevices = true;
+
+ EnableContentDownloading = true;
+ EnablePublicSharing = true;
+ EnableRemoteAccess = true;
+ SyncPlayAccess = SyncPlayUserAccessType.CreateAndJoinGroups;
+ }
+
///
/// Gets or sets a value indicating whether this instance is administrator.
///
@@ -112,55 +162,5 @@ namespace MediaBrowser.Model.Users
///
/// Access level to SyncPlay features.
public SyncPlayUserAccessType SyncPlayAccess { get; set; }
-
- public UserPolicy()
- {
- IsHidden = true;
-
- EnableContentDeletion = false;
- EnableContentDeletionFromFolders = Array.Empty();
-
- EnableSyncTranscoding = true;
- EnableMediaConversion = true;
-
- EnableMediaPlayback = true;
- EnableAudioPlaybackTranscoding = true;
- EnableVideoPlaybackTranscoding = true;
- EnablePlaybackRemuxing = true;
- ForceRemoteSourceTranscoding = false;
- EnableLiveTvManagement = true;
- EnableLiveTvAccess = true;
-
- // Without this on by default, admins won't be able to do this
- // Improve in the future
- EnableLiveTvManagement = true;
-
- EnableSharedDeviceControl = true;
-
- BlockedTags = Array.Empty();
- BlockUnratedItems = Array.Empty();
-
- EnableUserPreferenceAccess = true;
-
- AccessSchedules = Array.Empty();
-
- LoginAttemptsBeforeLockout = -1;
-
- MaxActiveSessions = 0;
-
- EnableAllChannels = true;
- EnabledChannels = Array.Empty();
-
- EnableAllFolders = true;
- EnabledFolders = Array.Empty();
-
- EnabledDevices = Array.Empty();
- EnableAllDevices = true;
-
- EnableContentDownloading = true;
- EnablePublicSharing = true;
- EnableRemoteAccess = true;
- SyncPlayAccess = SyncPlayUserAccessType.CreateAndJoinGroups;
- }
}
}
diff --git a/jellyfin.ruleset b/jellyfin.ruleset
index fa09bfb66a..81337390cc 100644
--- a/jellyfin.ruleset
+++ b/jellyfin.ruleset
@@ -32,6 +32,8 @@
+
+
diff --git a/tests/Jellyfin.Api.Tests/ModelBinders/TestType.cs b/tests/Jellyfin.Api.Tests/ModelBinders/TestType.cs
index 544a74637a..92c534eaea 100644
--- a/tests/Jellyfin.Api.Tests/ModelBinders/TestType.cs
+++ b/tests/Jellyfin.Api.Tests/ModelBinders/TestType.cs
@@ -1,17 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
namespace Jellyfin.Api.Tests.ModelBinders
{
public enum TestType
{
-#pragma warning disable SA1602 // Enumeration items should be documented
How,
Much,
Is,
The,
Fish
-#pragma warning restore SA1602 // Enumeration items should be documented
}
}