repo creation with initial code after cloning public repo

This commit is contained in:
2026-02-19 07:36:25 -05:00
commit 460884fea3
2860 changed files with 650825 additions and 0 deletions
@@ -0,0 +1,85 @@
using System;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Model.Activity
{
/// <summary>
/// An activity log entry.
/// </summary>
public class ActivityLogEntry
{
/// <summary>
/// Initializes a new instance of the <see cref="ActivityLogEntry"/> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="type">The type.</param>
/// <param name="userId">The user id.</param>
public ActivityLogEntry(string name, string type, Guid userId)
{
Name = name;
Type = type;
UserId = userId;
}
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
public long Id { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the overview.
/// </summary>
/// <value>The overview.</value>
public string? Overview { get; set; }
/// <summary>
/// Gets or sets the short overview.
/// </summary>
/// <value>The short overview.</value>
public string? ShortOverview { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
public string Type { get; set; }
/// <summary>
/// Gets or sets the item identifier.
/// </summary>
/// <value>The item identifier.</value>
public string? ItemId { get; set; }
/// <summary>
/// Gets or sets the date.
/// </summary>
/// <value>The date.</value>
public DateTime Date { get; set; }
/// <summary>
/// Gets or sets the user identifier.
/// </summary>
/// <value>The user identifier.</value>
public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the user primary image tag.
/// </summary>
/// <value>The user primary image tag.</value>
[Obsolete("UserPrimaryImageTag is not used.")]
public string? UserPrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets the log severity.
/// </summary>
/// <value>The log severity.</value>
public LogLevel Severity { get; set; }
}
}
@@ -0,0 +1,40 @@
using System;
using System.Threading.Tasks;
using Jellyfin.Data.Events;
using Jellyfin.Data.Queries;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Model.Activity;
/// <summary>
/// Interface for the activity manager.
/// </summary>
public interface IActivityManager
{
/// <summary>
/// The event that is triggered when an entity is created.
/// </summary>
event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
/// <summary>
/// Create a new activity log entry.
/// </summary>
/// <param name="entry">The entry to create.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
Task CreateAsync(ActivityLog entry);
/// <summary>
/// Get a paged list of activity log entries.
/// </summary>
/// <param name="query">The activity log query.</param>
/// <returns>The page of entries.</returns>
Task<QueryResult<ActivityLogEntry>> GetPagedResultAsync(ActivityLogQuery query);
/// <summary>
/// Remove all activity logs before the specified date.
/// </summary>
/// <param name="startDate">Activity log start date.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
Task CleanAsync(DateTime startDate);
}
@@ -0,0 +1,43 @@
namespace MediaBrowser.Model.ApiClient
{
/// <summary>
/// The server discovery info model.
/// </summary>
public class ServerDiscoveryInfo
{
/// <summary>
/// Initializes a new instance of the <see cref="ServerDiscoveryInfo"/> class.
/// </summary>
/// <param name="address">The server address.</param>
/// <param name="id">The server id.</param>
/// <param name="name">The server name.</param>
/// <param name="endpointAddress">The endpoint address.</param>
public ServerDiscoveryInfo(string address, string id, string name, string? endpointAddress = null)
{
Address = address;
Id = id;
Name = name;
EndpointAddress = endpointAddress;
}
/// <summary>
/// Gets the address.
/// </summary>
public string Address { get; }
/// <summary>
/// Gets the server identifier.
/// </summary>
public string Id { get; }
/// <summary>
/// Gets the name.
/// </summary>
public string Name { get; }
/// <summary>
/// Gets the endpoint address.
/// </summary>
public string? EndpointAddress { get; }
}
}
@@ -0,0 +1,29 @@
namespace MediaBrowser.Model.Branding;
/// <summary>
/// The branding options.
/// </summary>
public class BrandingOptions
{
/// <summary>
/// Gets or sets the login disclaimer.
/// </summary>
/// <value>The login disclaimer.</value>
public string? LoginDisclaimer { get; set; }
/// <summary>
/// Gets or sets the custom CSS.
/// </summary>
/// <value>The custom CSS.</value>
public string? CustomCss { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to enable the splashscreen.
/// </summary>
public bool SplashscreenEnabled { get; set; } = false;
/// <summary>
/// Gets or sets the splashscreen location on disk.
/// </summary>
public string? SplashscreenLocation { get; set; }
}
@@ -0,0 +1,25 @@
namespace MediaBrowser.Model.Branding;
/// <summary>
/// The branding options DTO for API use.
/// This DTO excludes SplashscreenLocation to prevent it from being updated via API.
/// </summary>
public class BrandingOptionsDto
{
/// <summary>
/// Gets or sets the login disclaimer.
/// </summary>
/// <value>The login disclaimer.</value>
public string? LoginDisclaimer { get; set; }
/// <summary>
/// Gets or sets the custom CSS.
/// </summary>
/// <value>The custom CSS.</value>
public string? CustomCss { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to enable the splashscreen.
/// </summary>
public bool SplashscreenEnabled { get; set; } = false;
}
@@ -0,0 +1,89 @@
#pragma warning disable CS1591
using System;
namespace MediaBrowser.Model.Channels
{
public class ChannelFeatures
{
public ChannelFeatures(string name, Guid id)
{
MediaTypes = Array.Empty<ChannelMediaType>();
ContentTypes = Array.Empty<ChannelMediaContentType>();
DefaultSortFields = Array.Empty<ChannelItemSortField>();
Name = name;
Id = id;
}
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
public Guid Id { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance can search.
/// </summary>
/// <value><c>true</c> if this instance can search; otherwise, <c>false</c>.</value>
public bool CanSearch { get; set; }
/// <summary>
/// Gets or sets the media types.
/// </summary>
/// <value>The media types.</value>
public ChannelMediaType[] MediaTypes { get; set; }
/// <summary>
/// Gets or sets the content types.
/// </summary>
/// <value>The content types.</value>
public ChannelMediaContentType[] ContentTypes { get; set; }
/// <summary>
/// Gets or sets the maximum number of records the channel allows retrieving at a time.
/// </summary>
public int? MaxPageSize { get; set; }
/// <summary>
/// Gets or sets the automatic refresh levels.
/// </summary>
/// <value>The automatic refresh levels.</value>
public int? AutoRefreshLevels { get; set; }
/// <summary>
/// Gets or sets the default sort orders.
/// </summary>
/// <value>The default sort orders.</value>
public ChannelItemSortField[] DefaultSortFields { get; set; }
/// <summary>
/// Gets or sets a value indicating whether a sort ascending/descending toggle is supported.
/// </summary>
public bool SupportsSortOrderToggle { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports latest media].
/// </summary>
/// <value><c>true</c> if [supports latest media]; otherwise, <c>false</c>.</value>
public bool SupportsLatestMedia { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance can filter.
/// </summary>
/// <value><c>true</c> if this instance can filter; otherwise, <c>false</c>.</value>
public bool CanFilter { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports content downloading].
/// </summary>
/// <value><c>true</c> if [supports content downloading]; otherwise, <c>false</c>.</value>
public bool SupportsContentDownloading { get; set; }
}
}
@@ -0,0 +1,19 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Channels
{
public enum ChannelFolderType
{
Container = 0,
MusicAlbum = 1,
PhotoAlbum = 2,
MusicArtist = 3,
Series = 4,
Season = 5
}
}
@@ -0,0 +1,15 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Channels
{
public enum ChannelItemSortField
{
Name = 0,
CommunityRating = 1,
PremiereDate = 2,
DateCreated = 3,
Runtime = 4,
PlayCount = 5,
CommunityPlayCount = 6
}
}
@@ -0,0 +1,23 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Channels
{
public enum ChannelMediaContentType
{
Clip = 0,
Podcast = 1,
Trailer = 2,
Movie = 3,
Episode = 4,
Song = 5,
MovieExtra = 6,
TvExtra = 7
}
}
@@ -0,0 +1,13 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Channels
{
public enum ChannelMediaType
{
Audio = 0,
Video = 1,
Photo = 2
}
}
@@ -0,0 +1,59 @@
#pragma warning disable CS1591
using System;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Model.Channels
{
public class ChannelQuery
{
/// <summary>
/// Gets or sets the fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
public ItemFields[]? Fields { get; set; }
public bool? EnableImages { get; set; }
public int? ImageTypeLimit { get; set; }
public ImageType[]? EnableImageTypes { get; set; }
/// <summary>
/// Gets or sets the user identifier.
/// </summary>
/// <value>The user identifier.</value>
public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the start index. Use for paging.
/// </summary>
/// <value>The start index.</value>
public int? StartIndex { get; set; }
/// <summary>
/// Gets or sets the maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
public int? Limit { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports latest items].
/// </summary>
/// <value><c>true</c> if [supports latest items]; otherwise, <c>false</c>.</value>
public bool? SupportsLatestItems { get; set; }
public bool? SupportsMediaDeletion { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is favorite.
/// </summary>
/// <value><c>null</c> if [is favorite] contains no value, <c>true</c> if [is favorite]; otherwise, <c>false</c>.</value>
public bool? IsFavorite { get; set; }
public bool? IsRecordingsFolder { get; set; }
public bool RefreshLatestChannelItems { get; set; }
}
}
@@ -0,0 +1,11 @@
#pragma warning disable CS1591
using System;
namespace MediaBrowser.Model.Collections
{
public class CollectionCreationResult
{
public Guid Id { get; set; }
}
}
@@ -0,0 +1,63 @@
using System;
using System.Xml.Serialization;
namespace MediaBrowser.Model.Configuration
{
/// <summary>
/// Serves as a common base class for the Server and UI application Configurations
/// ProtoInclude tells Protobuf about subclasses,
/// The number 50 can be any number, so long as it doesn't clash with any of the ProtoMember numbers either here or in subclasses.
/// </summary>
public class BaseApplicationConfiguration
{
/// <summary>
/// Initializes a new instance of the <see cref="BaseApplicationConfiguration" /> class.
/// </summary>
public BaseApplicationConfiguration()
{
LogFileRetentionDays = 3;
}
/// <summary>
/// Gets or sets the number of days we should retain log files.
/// </summary>
/// <value>The log file retention days.</value>
public int LogFileRetentionDays { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is first run.
/// </summary>
/// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
public bool IsStartupWizardCompleted { get; set; }
/// <summary>
/// Gets or sets the cache path.
/// </summary>
/// <value>The cache path.</value>
public string? CachePath { get; set; }
/// <summary>
/// Gets or sets the last known version that was ran using the configuration.
/// </summary>
/// <value>The version from previous run.</value>
[XmlIgnore]
public Version? PreviousVersion { get; set; }
/// <summary>
/// Gets or sets the stringified PreviousVersion to be stored/loaded,
/// because System.Version itself isn't xml-serializable.
/// </summary>
/// <value>String value of PreviousVersion.</value>
public string? PreviousVersionStr
{
get => PreviousVersion?.ToString();
set
{
if (Version.TryParse(value, out var version))
{
PreviousVersion = version;
}
}
}
}
}
@@ -0,0 +1,28 @@
namespace MediaBrowser.Model.Configuration
{
/// <summary>
/// An enum representing the options to disable embedded subs.
/// </summary>
public enum EmbeddedSubtitleOptions
{
/// <summary>
/// Allow all embedded subs.
/// </summary>
AllowAll = 0,
/// <summary>
/// Allow only embedded subs that are text based.
/// </summary>
AllowText = 1,
/// <summary>
/// Allow only embedded subs that are image based.
/// </summary>
AllowImage = 2,
/// <summary>
/// Disable all embedded subs.
/// </summary>
AllowNone = 3,
}
}
@@ -0,0 +1,312 @@
#pragma warning disable CA1819 // XML serialization handles collections improperly, so we need to use arrays
#nullable disable
using System.ComponentModel;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Configuration;
/// <summary>
/// Class EncodingOptions.
/// </summary>
public class EncodingOptions
{
/// <summary>
/// Initializes a new instance of the <see cref="EncodingOptions" /> class.
/// </summary>
public EncodingOptions()
{
EnableFallbackFont = false;
EnableAudioVbr = false;
DownMixAudioBoost = 2;
DownMixStereoAlgorithm = DownMixStereoAlgorithms.None;
MaxMuxingQueueSize = 2048;
EnableThrottling = false;
ThrottleDelaySeconds = 180;
EnableSegmentDeletion = false;
SegmentKeepSeconds = 720;
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";
QsvDevice = string.Empty;
EnableTonemapping = false;
EnableVppTonemapping = false;
EnableVideoToolboxTonemapping = false;
TonemappingAlgorithm = TonemappingAlgorithm.bt2390;
TonemappingMode = TonemappingMode.auto;
TonemappingRange = TonemappingRange.auto;
TonemappingDesat = 0;
TonemappingPeak = 100;
TonemappingParam = 0;
VppTonemappingBrightness = 16;
VppTonemappingContrast = 1;
H264Crf = 23;
H265Crf = 28;
DeinterlaceDoubleRate = false;
DeinterlaceMethod = DeinterlaceMethod.yadif;
EnableDecodingColorDepth10Hevc = true;
EnableDecodingColorDepth10Vp9 = true;
EnableDecodingColorDepth10HevcRext = false;
EnableDecodingColorDepth12HevcRext = false;
// Enhanced Nvdec or system native decoder is required for DoVi to SDR tone-mapping.
EnableEnhancedNvdecDecoder = true;
PreferSystemNativeHwDecoder = true;
EnableIntelLowPowerH264HwEncoder = false;
EnableIntelLowPowerHevcHwEncoder = false;
EnableHardwareEncoding = true;
AllowHevcEncoding = false;
AllowAv1Encoding = false;
EnableSubtitleExtraction = true;
SubtitleExtractionTimeoutMinutes = 30;
AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = ["mkv"];
HardwareDecodingCodecs = ["h264", "vc1"];
HlsAudioSeekStrategy = HlsAudioSeekStrategy.DisableAccurateSeek;
}
/// <summary>
/// Gets or sets the thread count used for encoding.
/// </summary>
public int EncodingThreadCount { get; set; }
/// <summary>
/// Gets or sets the temporary transcoding path.
/// </summary>
public string TranscodingTempPath { get; set; }
/// <summary>
/// Gets or sets the path to the fallback font.
/// </summary>
public string FallbackFontPath { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to use the fallback font.
/// </summary>
public bool EnableFallbackFont { get; set; }
/// <summary>
/// Gets or sets a value indicating whether audio VBR is enabled.
/// </summary>
public bool EnableAudioVbr { get; set; }
/// <summary>
/// Gets or sets the audio boost applied when downmixing audio.
/// </summary>
public double DownMixAudioBoost { get; set; }
/// <summary>
/// Gets or sets the algorithm used for downmixing audio to stereo.
/// </summary>
public DownMixStereoAlgorithms DownMixStereoAlgorithm { get; set; }
/// <summary>
/// Gets or sets the maximum size of the muxing queue.
/// </summary>
public int MaxMuxingQueueSize { get; set; }
/// <summary>
/// Gets or sets a value indicating whether throttling is enabled.
/// </summary>
public bool EnableThrottling { get; set; }
/// <summary>
/// Gets or sets the delay after which throttling happens.
/// </summary>
public int ThrottleDelaySeconds { get; set; }
/// <summary>
/// Gets or sets a value indicating whether segment deletion is enabled.
/// </summary>
public bool EnableSegmentDeletion { get; set; }
/// <summary>
/// Gets or sets seconds for which segments should be kept before being deleted.
/// </summary>
public int SegmentKeepSeconds { get; set; }
/// <summary>
/// Gets or sets the hardware acceleration type.
/// </summary>
public HardwareAccelerationType HardwareAccelerationType { get; set; }
/// <summary>
/// Gets or sets the FFmpeg path as set by the user via the UI.
/// </summary>
public string EncoderAppPath { get; set; }
/// <summary>
/// Gets or sets the current FFmpeg path being used by the system and displayed on the transcode page.
/// </summary>
public string EncoderAppPathDisplay { get; set; }
/// <summary>
/// Gets or sets the VA-API device.
/// </summary>
public string VaapiDevice { get; set; }
/// <summary>
/// Gets or sets the QSV device.
/// </summary>
public string QsvDevice { get; set; }
/// <summary>
/// Gets or sets a value indicating whether tonemapping is enabled.
/// </summary>
public bool EnableTonemapping { get; set; }
/// <summary>
/// Gets or sets a value indicating whether VPP tonemapping is enabled.
/// </summary>
public bool EnableVppTonemapping { get; set; }
/// <summary>
/// Gets or sets a value indicating whether videotoolbox tonemapping is enabled.
/// </summary>
public bool EnableVideoToolboxTonemapping { get; set; }
/// <summary>
/// Gets or sets the tone-mapping algorithm.
/// </summary>
public TonemappingAlgorithm TonemappingAlgorithm { get; set; }
/// <summary>
/// Gets or sets the tone-mapping mode.
/// </summary>
public TonemappingMode TonemappingMode { get; set; }
/// <summary>
/// Gets or sets the tone-mapping range.
/// </summary>
public TonemappingRange TonemappingRange { get; set; }
/// <summary>
/// Gets or sets the tone-mapping desaturation.
/// </summary>
public double TonemappingDesat { get; set; }
/// <summary>
/// Gets or sets the tone-mapping peak.
/// </summary>
public double TonemappingPeak { get; set; }
/// <summary>
/// Gets or sets the tone-mapping parameters.
/// </summary>
public double TonemappingParam { get; set; }
/// <summary>
/// Gets or sets the VPP tone-mapping brightness.
/// </summary>
public double VppTonemappingBrightness { get; set; }
/// <summary>
/// Gets or sets the VPP tone-mapping contrast.
/// </summary>
public double VppTonemappingContrast { get; set; }
/// <summary>
/// Gets or sets the H264 CRF.
/// </summary>
public int H264Crf { get; set; }
/// <summary>
/// Gets or sets the H265 CRF.
/// </summary>
public int H265Crf { get; set; }
/// <summary>
/// Gets or sets the encoder preset.
/// </summary>
public EncoderPreset? EncoderPreset { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the framerate is doubled when deinterlacing.
/// </summary>
public bool DeinterlaceDoubleRate { get; set; }
/// <summary>
/// Gets or sets the deinterlace method.
/// </summary>
public DeinterlaceMethod DeinterlaceMethod { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 10bit HEVC decoding is enabled.
/// </summary>
public bool EnableDecodingColorDepth10Hevc { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 10bit VP9 decoding is enabled.
/// </summary>
public bool EnableDecodingColorDepth10Vp9 { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 8/10bit HEVC RExt decoding is enabled.
/// </summary>
public bool EnableDecodingColorDepth10HevcRext { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 12bit HEVC RExt decoding is enabled.
/// </summary>
public bool EnableDecodingColorDepth12HevcRext { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the enhanced NVDEC is enabled.
/// </summary>
public bool EnableEnhancedNvdecDecoder { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the system native hardware decoder should be used.
/// </summary>
public bool PreferSystemNativeHwDecoder { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the Intel H264 low-power hardware encoder should be used.
/// </summary>
public bool EnableIntelLowPowerH264HwEncoder { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the Intel HEVC low-power hardware encoder should be used.
/// </summary>
public bool EnableIntelLowPowerHevcHwEncoder { get; set; }
/// <summary>
/// Gets or sets a value indicating whether hardware encoding is enabled.
/// </summary>
public bool EnableHardwareEncoding { get; set; }
/// <summary>
/// Gets or sets a value indicating whether HEVC encoding is enabled.
/// </summary>
public bool AllowHevcEncoding { get; set; }
/// <summary>
/// Gets or sets a value indicating whether AV1 encoding is enabled.
/// </summary>
public bool AllowAv1Encoding { get; set; }
/// <summary>
/// Gets or sets a value indicating whether subtitle extraction is enabled.
/// </summary>
public bool EnableSubtitleExtraction { get; set; }
/// <summary>
/// Gets or sets the timeout for subtitle extraction in minutes.
/// </summary>
public int SubtitleExtractionTimeoutMinutes { get; set; }
/// <summary>
/// Gets or sets the codecs hardware encoding is used for.
/// </summary>
public string[] HardwareDecodingCodecs { get; set; }
/// <summary>
/// Gets or sets the file extensions on-demand metadata based keyframe extraction is enabled for.
/// </summary>
public string[] AllowOnDemandMetadataBasedKeyframeExtractionForExtensions { get; set; }
/// <summary>
/// Gets or sets the method used for audio seeking in HLS.
/// </summary>
[DefaultValue(HlsAudioSeekStrategy.DisableAccurateSeek)]
public HlsAudioSeekStrategy HlsAudioSeekStrategy { get; set; }
}
@@ -0,0 +1,23 @@
namespace MediaBrowser.Model.Configuration
{
/// <summary>
/// An enum representing the options to seek the input audio stream when
/// transcoding HLS segments.
/// </summary>
public enum HlsAudioSeekStrategy
{
/// <summary>
/// If the video stream is transcoded and the audio stream is copied,
/// seek the video stream to the same keyframe as the audio stream. The
/// resulting timestamps in the output streams may be inaccurate.
/// </summary>
DisableAccurateSeek = 0,
/// <summary>
/// Prevent audio streams from being copied if the video stream is transcoded.
/// The resulting timestamps will be accurate, but additional audio transcoding
/// overhead will be incurred.
/// </summary>
TranscodeAudio = 1,
}
}
@@ -0,0 +1,32 @@
#pragma warning disable CS1591
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Configuration
{
public class ImageOption
{
public ImageOption()
{
Limit = 1;
}
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
public ImageType Type { get; set; }
/// <summary>
/// Gets or sets the limit.
/// </summary>
/// <value>The limit.</value>
public int Limit { get; set; }
/// <summary>
/// Gets or sets the minimum width.
/// </summary>
/// <value>The minimum width.</value>
public int MinWidth { get; set; }
}
}
@@ -0,0 +1,10 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Configuration
{
public enum ImageSavingConvention
{
Legacy,
Compatible
}
}
@@ -0,0 +1,153 @@
#pragma warning disable CS1591
using System;
using System.ComponentModel;
using System.Linq;
namespace MediaBrowser.Model.Configuration
{
public class LibraryOptions
{
private static readonly string[] _defaultTagDelimiters = ["/", "|", ";", "\\"];
public LibraryOptions()
{
TypeOptions = Array.Empty<TypeOptions>();
DisabledSubtitleFetchers = Array.Empty<string>();
DisabledMediaSegmentProviders = Array.Empty<string>();
MediaSegmentProviderOrder = Array.Empty<string>();
SubtitleFetcherOrder = Array.Empty<string>();
DisabledLocalMetadataReaders = Array.Empty<string>();
DisabledLyricFetchers = Array.Empty<string>();
LyricFetcherOrder = Array.Empty<string>();
SkipSubtitlesIfAudioTrackMatches = true;
RequirePerfectSubtitleMatch = true;
AllowEmbeddedSubtitles = EmbeddedSubtitleOptions.AllowAll;
AutomaticallyAddToCollection = false;
EnablePhotos = true;
SaveSubtitlesWithMedia = true;
SaveLyricsWithMedia = false;
SaveTrickplayWithMedia = false;
PathInfos = Array.Empty<MediaPathInfo>();
EnableAutomaticSeriesGrouping = true;
SeasonZeroDisplayName = "Specials";
PreferNonstandardArtistsTag = false;
UseCustomTagDelimiters = false;
CustomTagDelimiters = _defaultTagDelimiters;
DelimiterWhitelist = Array.Empty<string>();
}
public bool Enabled { get; set; } = true;
public bool EnablePhotos { get; set; }
public bool EnableRealtimeMonitor { get; set; }
public bool EnableLUFSScan { get; set; }
public bool EnableChapterImageExtraction { get; set; }
public bool ExtractChapterImagesDuringLibraryScan { get; set; }
public bool EnableTrickplayImageExtraction { get; set; }
public bool ExtractTrickplayImagesDuringLibraryScan { get; set; }
public MediaPathInfo[] PathInfos { get; set; }
public bool SaveLocalMetadata { get; set; }
[Obsolete("Disable remote providers in TypeOptions instead")]
public bool EnableInternetProviders { get; set; }
public bool EnableAutomaticSeriesGrouping { get; set; }
public bool EnableEmbeddedTitles { get; set; }
public bool EnableEmbeddedExtrasTitles { get; set; }
public bool EnableEmbeddedEpisodeInfos { get; set; }
public int AutomaticRefreshIntervalDays { get; set; }
/// <summary>
/// Gets or sets the preferred metadata language.
/// </summary>
/// <value>The preferred metadata language.</value>
public string? PreferredMetadataLanguage { get; set; }
/// <summary>
/// Gets or sets the metadata country code.
/// </summary>
/// <value>The metadata country code.</value>
public string? MetadataCountryCode { get; set; }
public string SeasonZeroDisplayName { get; set; }
public string[]? MetadataSavers { get; set; }
public string[] DisabledLocalMetadataReaders { get; set; }
public string[]? LocalMetadataReaderOrder { get; set; }
public string[] DisabledSubtitleFetchers { get; set; }
public string[] SubtitleFetcherOrder { get; set; }
public string[] DisabledMediaSegmentProviders { get; set; }
public string[] MediaSegmentProviderOrder { get; set; }
public bool SkipSubtitlesIfEmbeddedSubtitlesPresent { get; set; }
public bool SkipSubtitlesIfAudioTrackMatches { get; set; }
public string[]? SubtitleDownloadLanguages { get; set; }
public bool RequirePerfectSubtitleMatch { get; set; }
public bool SaveSubtitlesWithMedia { get; set; }
[DefaultValue(false)]
public bool SaveLyricsWithMedia { get; set; }
[DefaultValue(false)]
public bool SaveTrickplayWithMedia { get; set; }
public string[] DisabledLyricFetchers { get; set; }
public string[] LyricFetcherOrder { get; set; }
[DefaultValue(false)]
public bool PreferNonstandardArtistsTag { get; set; }
[DefaultValue(false)]
public bool UseCustomTagDelimiters { get; set; }
public string[] CustomTagDelimiters { get; set; }
public string[] DelimiterWhitelist { get; set; }
public bool AutomaticallyAddToCollection { get; set; }
public EmbeddedSubtitleOptions AllowEmbeddedSubtitles { get; set; }
public TypeOptions[] TypeOptions { get; set; }
public TypeOptions? GetTypeOptions(string type)
{
foreach (var options in TypeOptions)
{
if (string.Equals(options.Type, type, StringComparison.OrdinalIgnoreCase))
{
return options;
}
}
return null;
}
}
}
@@ -0,0 +1,20 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Configuration
{
public class MediaPathInfo
{
public MediaPathInfo(string path)
{
Path = path;
}
// Needed for xml serialization
public MediaPathInfo()
{
Path = string.Empty;
}
public string Path { get; set; }
}
}
@@ -0,0 +1,14 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Configuration
{
public class MetadataConfiguration
{
public MetadataConfiguration()
{
UseFileCreationTimeForDateAdded = true;
}
public bool UseFileCreationTimeForDateAdded { get; set; }
}
}
@@ -0,0 +1,37 @@
#nullable disable
#pragma warning disable CS1591, CA1819
using System;
namespace MediaBrowser.Model.Configuration
{
/// <summary>
/// Class MetadataOptions.
/// </summary>
public class MetadataOptions
{
public MetadataOptions()
{
DisabledMetadataSavers = Array.Empty<string>();
LocalMetadataReaderOrder = Array.Empty<string>();
DisabledMetadataFetchers = Array.Empty<string>();
MetadataFetcherOrder = Array.Empty<string>();
DisabledImageFetchers = Array.Empty<string>();
ImageFetcherOrder = Array.Empty<string>();
}
public string ItemType { get; set; }
public string[] DisabledMetadataSavers { get; set; }
public string[] LocalMetadataReaderOrder { get; set; }
public string[] DisabledMetadataFetchers { get; set; }
public string[] MetadataFetcherOrder { get; set; }
public string[] DisabledImageFetchers { get; set; }
public string[] ImageFetcherOrder { get; set; }
}
}
@@ -0,0 +1,20 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Configuration
{
public class MetadataPlugin
{
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
public MetadataPluginType Type { get; set; }
}
}
@@ -0,0 +1,35 @@
#nullable disable
#pragma warning disable CS1591
using System;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Configuration
{
public class MetadataPluginSummary
{
public MetadataPluginSummary()
{
SupportedImageTypes = Array.Empty<ImageType>();
Plugins = Array.Empty<MetadataPlugin>();
}
/// <summary>
/// Gets or sets the type of the item.
/// </summary>
/// <value>The type of the item.</value>
public string ItemType { get; set; }
/// <summary>
/// Gets or sets the plugins.
/// </summary>
/// <value>The plugins.</value>
public MetadataPlugin[] Plugins { get; set; }
/// <summary>
/// Gets or sets the supported image types.
/// </summary>
/// <value>The supported image types.</value>
public ImageType[] SupportedImageTypes { get; set; }
}
}
@@ -0,0 +1,20 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Configuration
{
/// <summary>
/// Enum MetadataPluginType.
/// </summary>
public enum MetadataPluginType
{
LocalImageProvider,
ImageFetcher,
ImageSaver,
LocalMetadataProvider,
MetadataFetcher,
MetadataSaver,
SubtitleFetcher,
LyricFetcher,
MediaSegmentProvider
}
}
@@ -0,0 +1,18 @@
namespace MediaBrowser.Model.Configuration
{
/// <summary>
/// Defines the <see cref="PathSubstitution" />.
/// </summary>
public class PathSubstitution
{
/// <summary>
/// Gets or sets the value to substitute.
/// </summary>
public string From { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the value to substitution with.
/// </summary>
public string To { get; set; } = string.Empty;
}
}
@@ -0,0 +1,291 @@
#pragma warning disable CS1591
#pragma warning disable CA1819
using System;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Updates;
namespace MediaBrowser.Model.Configuration;
/// <summary>
/// Represents the server configuration.
/// </summary>
public class ServerConfiguration : BaseApplicationConfiguration
{
/// <summary>
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
/// </summary>
public ServerConfiguration()
{
MetadataOptions = new[]
{
new MetadataOptions()
{
ItemType = "Book"
},
new MetadataOptions()
{
ItemType = "Movie"
},
new MetadataOptions
{
ItemType = "MusicVideo",
DisabledMetadataFetchers = new[] { "The Open Movie Database" },
DisabledImageFetchers = new[] { "The Open Movie Database" }
},
new MetadataOptions
{
ItemType = "Series",
},
new MetadataOptions
{
ItemType = "MusicAlbum",
DisabledMetadataFetchers = new[] { "TheAudioDB" }
},
new MetadataOptions
{
ItemType = "MusicArtist",
DisabledMetadataFetchers = new[] { "TheAudioDB" }
},
new MetadataOptions
{
ItemType = "BoxSet"
},
new MetadataOptions
{
ItemType = "Season",
},
new MetadataOptions
{
ItemType = "Episode",
}
};
}
/// <summary>
/// Gets or sets a value indicating whether to enable prometheus metrics exporting.
/// </summary>
public bool EnableMetrics { get; set; } = false;
public bool EnableNormalizedItemByNameIds { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether this instance is port authorized.
/// </summary>
/// <value><c>true</c> if this instance is port authorized; otherwise, <c>false</c>.</value>
public bool IsPortAuthorized { get; set; }
/// <summary>
/// Gets or sets a value indicating whether quick connect is available for use on this server.
/// </summary>
public bool QuickConnectAvailable { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether [enable case-sensitive item ids].
/// </summary>
/// <value><c>true</c> if [enable case-sensitive item ids]; otherwise, <c>false</c>.</value>
public bool EnableCaseSensitiveItemIds { get; set; } = true;
public bool DisableLiveTvChannelUserDataName { get; set; } = true;
/// <summary>
/// Gets or sets the metadata path.
/// </summary>
/// <value>The metadata path.</value>
public string MetadataPath { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the preferred metadata language.
/// </summary>
/// <value>The preferred metadata language.</value>
public string PreferredMetadataLanguage { get; set; } = "en";
/// <summary>
/// Gets or sets the metadata country code.
/// </summary>
/// <value>The metadata country code.</value>
public string MetadataCountryCode { get; set; } = "US";
/// <summary>
/// Gets or sets characters to be replaced with a ' ' in strings to create a sort name.
/// </summary>
/// <value>The sort replace characters.</value>
public string[] SortReplaceCharacters { get; set; } = new[] { ".", "+", "%" };
/// <summary>
/// Gets or sets characters to be removed from strings to create a sort name.
/// </summary>
/// <value>The sort remove characters.</value>
public string[] SortRemoveCharacters { get; set; } = new[] { ",", "&", "-", "{", "}", "'" };
/// <summary>
/// Gets or sets words to be removed from strings to create a sort name.
/// </summary>
/// <value>The sort remove words.</value>
public string[] SortRemoveWords { get; set; } = new[] { "the", "a", "an" };
/// <summary>
/// Gets or sets the minimum percentage of an item that must be played in order for playstate to be updated.
/// </summary>
/// <value>The min resume PCT.</value>
public int MinResumePct { get; set; } = 5;
/// <summary>
/// Gets or sets the maximum percentage of an item that can be played while still saving playstate. If this percentage is crossed playstate will be reset to the beginning and the item will be marked watched.
/// </summary>
/// <value>The max resume PCT.</value>
public int MaxResumePct { get; set; } = 90;
/// <summary>
/// Gets or sets the minimum duration that an item must have in order to be eligible for playstate updates..
/// </summary>
/// <value>The min resume duration seconds.</value>
public int MinResumeDurationSeconds { get; set; } = 300;
/// <summary>
/// Gets or sets the minimum minutes of a book that must be played in order for playstate to be updated.
/// </summary>
/// <value>The min resume in minutes.</value>
public int MinAudiobookResume { get; set; } = 5;
/// <summary>
/// Gets or sets the remaining minutes of a book that can be played while still saving playstate. If this percentage is crossed playstate will be reset to the beginning and the item will be marked watched.
/// </summary>
/// <value>The remaining time in minutes.</value>
public int MaxAudiobookResume { get; set; } = 5;
/// <summary>
/// Gets or sets the threshold in minutes after a inactive session gets closed automatically.
/// If set to 0 the check for inactive sessions gets disabled.
/// </summary>
/// <value>The close inactive session threshold in minutes. 0 to disable.</value>
public int InactiveSessionThreshold { get; set; }
/// <summary>
/// Gets or sets the delay in seconds that we will wait after a file system change to try and discover what has been added/removed
/// Some delay is necessary with some items because their creation is not atomic. It involves the creation of several
/// different directories and files.
/// </summary>
/// <value>The file watcher delay.</value>
public int LibraryMonitorDelay { get; set; } = 60;
/// <summary>
/// Gets or sets the duration in seconds that we will wait after a library updated event before executing the library changed notification.
/// </summary>
/// <value>The library update duration.</value>
public int LibraryUpdateDuration { get; set; } = 30;
/// <summary>
/// Gets or sets the maximum amount of items to cache.
/// </summary>
public int CacheSize { get; set; } = Environment.ProcessorCount * 100;
/// <summary>
/// Gets or sets the image saving convention.
/// </summary>
/// <value>The image saving convention.</value>
public ImageSavingConvention ImageSavingConvention { get; set; }
public MetadataOptions[] MetadataOptions { get; set; }
public bool SkipDeserializationForBasicTypes { get; set; } = true;
public string ServerName { get; set; } = string.Empty;
public string UICulture { get; set; } = "en-US";
public bool SaveMetadataHidden { get; set; } = false;
public NameValuePair[] ContentTypes { get; set; } = Array.Empty<NameValuePair>();
public int RemoteClientBitrateLimit { get; set; }
public bool EnableFolderView { get; set; } = false;
public bool EnableGroupingMoviesIntoCollections { get; set; } = false;
public bool EnableGroupingShowsIntoCollections { get; set; } = false;
public bool DisplaySpecialsWithinSeasons { get; set; } = true;
public string[] CodecsUsed { get; set; } = Array.Empty<string>();
public RepositoryInfo[] PluginRepositories { get; set; } = Array.Empty<RepositoryInfo>();
public bool EnableExternalContentInSuggestions { get; set; } = true;
public int ImageExtractionTimeoutMs { get; set; }
public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty<PathSubstitution>();
/// <summary>
/// Gets or sets a value indicating whether slow server responses should be logged as a warning.
/// </summary>
public bool EnableSlowResponseWarning { get; set; } = true;
/// <summary>
/// Gets or sets the threshold for the slow response time warning in ms.
/// </summary>
public long SlowResponseThresholdMs { get; set; } = 500;
/// <summary>
/// Gets or sets the cors hosts.
/// </summary>
public string[] CorsHosts { get; set; } = new[] { "*" };
/// <summary>
/// Gets or sets the number of days we should retain activity logs.
/// </summary>
public int? ActivityLogRetentionDays { get; set; } = 30;
/// <summary>
/// Gets or sets the how the library scan fans out.
/// </summary>
public int LibraryScanFanoutConcurrency { get; set; }
/// <summary>
/// Gets or sets the how many metadata refreshes can run concurrently.
/// </summary>
public int LibraryMetadataRefreshConcurrency { get; set; }
/// <summary>
/// Gets or sets a value indicating whether clients should be allowed to upload logs.
/// </summary>
public bool AllowClientLogUpload { get; set; } = true;
/// <summary>
/// Gets or sets the dummy chapter duration in seconds, use 0 (zero) or less to disable generation altogether.
/// </summary>
/// <value>The dummy chapters duration.</value>
public int DummyChapterDuration { get; set; }
/// <summary>
/// Gets or sets the chapter image resolution.
/// </summary>
/// <value>The chapter image resolution.</value>
public ImageResolution ChapterImageResolution { get; set; } = ImageResolution.MatchSource;
/// <summary>
/// Gets or sets the limit for parallel image encoding.
/// </summary>
/// <value>The limit for parallel image encoding.</value>
public int ParallelImageEncodingLimit { get; set; }
/// <summary>
/// Gets or sets the list of cast receiver applications.
/// </summary>
public CastReceiverApplication[] CastReceiverApplications { get; set; } = Array.Empty<CastReceiverApplication>();
/// <summary>
/// Gets or sets the trickplay options.
/// </summary>
/// <value>The trickplay options.</value>
public TrickplayOptions TrickplayOptions { get; set; } = new TrickplayOptions();
/// <summary>
/// Gets or sets a value indicating whether old authorization methods are allowed.
/// </summary>
public bool EnableLegacyAuthorization { get; set; }
}
@@ -0,0 +1,71 @@
using System.Collections.Generic;
using System.Diagnostics;
namespace MediaBrowser.Model.Configuration;
/// <summary>
/// Class TrickplayOptions.
/// </summary>
public class TrickplayOptions
{
/// <summary>
/// Gets or sets a value indicating whether or not to use HW acceleration.
/// </summary>
public bool EnableHwAcceleration { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether or not to use HW accelerated MJPEG encoding.
/// </summary>
public bool EnableHwEncoding { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether to only extract key frames.
/// Significantly faster, but is not compatible with all decoders and/or video files.
/// </summary>
public bool EnableKeyFrameOnlyExtraction { get; set; } = false;
/// <summary>
/// Gets or sets the behavior used by trickplay provider on library scan/update.
/// </summary>
public TrickplayScanBehavior ScanBehavior { get; set; } = TrickplayScanBehavior.NonBlocking;
/// <summary>
/// Gets or sets the process priority for the ffmpeg process.
/// </summary>
public ProcessPriorityClass ProcessPriority { get; set; } = ProcessPriorityClass.BelowNormal;
/// <summary>
/// Gets or sets the interval, in ms, between each new trickplay image.
/// </summary>
public int Interval { get; set; } = 10000;
/// <summary>
/// Gets or sets the target width resolutions, in px, to generates preview images for.
/// </summary>
public int[] WidthResolutions { get; set; } = new[] { 320 };
/// <summary>
/// Gets or sets number of tile images to allow in X dimension.
/// </summary>
public int TileWidth { get; set; } = 10;
/// <summary>
/// Gets or sets number of tile images to allow in Y dimension.
/// </summary>
public int TileHeight { get; set; } = 10;
/// <summary>
/// Gets or sets the ffmpeg output quality level.
/// </summary>
public int Qscale { get; set; } = 4;
/// <summary>
/// Gets or sets the jpeg quality to use for image tiles.
/// </summary>
public int JpegQuality { get; set; } = 90;
/// <summary>
/// Gets or sets the number of threads to be used by ffmpeg.
/// </summary>
public int ProcessThreads { get; set; } = 1;
}
@@ -0,0 +1,17 @@
namespace MediaBrowser.Model.Configuration;
/// <summary>
/// Enum TrickplayScanBehavior.
/// </summary>
public enum TrickplayScanBehavior
{
/// <summary>
/// Starts generation, only return once complete.
/// </summary>
Blocking,
/// <summary>
/// Start generation, return immediately.
/// </summary>
NonBlocking
}
@@ -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<string, ImageOption[]> DefaultImageOptions = new Dictionary<string, ImageOption[]>
{
{
"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<string>();
MetadataFetcherOrder = Array.Empty<string>();
ImageFetchers = Array.Empty<string>();
ImageFetcherOrder = Array.Empty<string>();
ImageOptions = Array.Empty<ImageOption>();
}
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;
}
}
}
@@ -0,0 +1,78 @@
#pragma warning disable CS1591
using System;
using Jellyfin.Database.Implementations.Enums;
namespace MediaBrowser.Model.Configuration
{
/// <summary>
/// Class UserConfiguration.
/// </summary>
public class UserConfiguration
{
/// <summary>
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
/// </summary>
public UserConfiguration()
{
EnableNextEpisodeAutoPlay = true;
RememberAudioSelections = true;
RememberSubtitleSelections = true;
HidePlayedInLatest = true;
PlayDefaultAudioTrack = true;
LatestItemsExcludes = Array.Empty<Guid>();
OrderedViews = Array.Empty<Guid>();
MyMediaExcludes = Array.Empty<Guid>();
GroupedFolders = Array.Empty<Guid>();
}
/// <summary>
/// Gets or sets the audio language preference.
/// </summary>
/// <value>The audio language preference.</value>
public string? AudioLanguagePreference { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [play default audio track].
/// </summary>
/// <value><c>true</c> if [play default audio track]; otherwise, <c>false</c>.</value>
public bool PlayDefaultAudioTrack { get; set; }
/// <summary>
/// Gets or sets the subtitle language preference.
/// </summary>
/// <value>The subtitle language preference.</value>
public string? SubtitleLanguagePreference { get; set; }
public bool DisplayMissingEpisodes { get; set; }
public Guid[] GroupedFolders { get; set; }
public SubtitlePlaybackMode SubtitleMode { get; set; }
public bool DisplayCollectionsView { get; set; }
public bool EnableLocalPassword { get; set; }
public Guid[] OrderedViews { get; set; }
public Guid[] LatestItemsExcludes { get; set; }
public Guid[] MyMediaExcludes { get; set; }
public bool HidePlayedInLatest { get; set; }
public bool RememberAudioSelections { get; set; }
public bool RememberSubtitleSelections { get; set; }
public bool EnableNextEpisodeAutoPlay { get; set; }
/// <summary>
/// Gets or sets the id of the selected cast receiver.
/// </summary>
public string? CastReceiverId { get; set; }
}
}
@@ -0,0 +1,25 @@
#pragma warning disable CS1591
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; }
public bool SaveImagePathsInNfo { get; set; }
public bool EnablePathSubstitution { get; set; }
public bool EnableExtraThumbsDuplication { get; set; }
}
}
@@ -0,0 +1,23 @@
namespace MediaBrowser.Model.Cryptography
{
/// <summary>
/// Class containing global constants for Jellyfin Cryptography.
/// </summary>
public static class Constants
{
/// <summary>
/// The default length for new salts.
/// </summary>
public const int DefaultSaltLength = 128 / 8;
/// <summary>
/// The default output length.
/// </summary>
public const int DefaultOutputLength = 512 / 8;
/// <summary>
/// The default amount of iterations for hashing passwords.
/// </summary>
public const int DefaultIterations = 210000;
}
}
@@ -0,0 +1,24 @@
#pragma warning disable CS1591
using System;
namespace MediaBrowser.Model.Cryptography
{
public interface ICryptoProvider
{
string DefaultHashMethod { get; }
/// <summary>
/// Creates a new <see cref="PasswordHash" /> instance.
/// </summary>
/// <param name="password">The password that will be hashed.</param>
/// <returns>A <see cref="PasswordHash" /> instance with the hash method, hash, salt and number of iterations.</returns>
PasswordHash CreatePasswordHash(ReadOnlySpan<char> password);
bool Verify(PasswordHash hash, ReadOnlySpan<char> password);
byte[] GenerateSalt();
byte[] GenerateSalt(int length);
}
}
@@ -0,0 +1,212 @@
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Text;
namespace MediaBrowser.Model.Cryptography
{
// Defined from this hash storage spec
// https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md
// $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]
// with one slight amendment to ease the transition, we're writing out the bytes in hex
// rather than making them a BASE64 string with stripped padding
public class PasswordHash
{
private readonly Dictionary<string, string> _parameters;
private readonly byte[] _salt;
private readonly byte[] _hash;
public PasswordHash(string id, byte[] hash)
: this(id, hash, Array.Empty<byte>())
{
}
public PasswordHash(string id, byte[] hash, byte[] salt)
: this(id, hash, salt, new Dictionary<string, string>())
{
}
public PasswordHash(string id, byte[] hash, byte[] salt, Dictionary<string, string> parameters)
{
ArgumentException.ThrowIfNullOrEmpty(id);
Id = id;
_hash = hash;
_salt = salt;
_parameters = parameters;
}
/// <summary>
/// Gets the symbolic name for the function used.
/// </summary>
/// <value>Returns the symbolic name for the function used.</value>
public string Id { get; }
/// <summary>
/// Gets the additional parameters used by the hash function.
/// </summary>
public IReadOnlyDictionary<string, string> Parameters => _parameters;
/// <summary>
/// Gets the salt used for hashing the password.
/// </summary>
/// <value>Returns the salt used for hashing the password.</value>
public ReadOnlySpan<byte> Salt => _salt;
/// <summary>
/// Gets the hashed password.
/// </summary>
/// <value>Return the hashed password.</value>
public ReadOnlySpan<byte> Hash => _hash;
public static PasswordHash Parse(ReadOnlySpan<char> hashString)
{
if (hashString.IsEmpty)
{
throw new ArgumentException("String can't be empty", nameof(hashString));
}
if (hashString[0] != '$')
{
throw new FormatException("Hash string must start with a $");
}
// Ignore first $
hashString = hashString[1..];
int nextSegment = hashString.IndexOf('$');
if (hashString.IsEmpty || nextSegment == 0)
{
throw new FormatException("Hash string must contain a valid id");
}
if (nextSegment == -1)
{
return new PasswordHash(hashString.ToString(), Array.Empty<byte>());
}
ReadOnlySpan<char> id = hashString[..nextSegment];
hashString = hashString[(nextSegment + 1)..];
Dictionary<string, string>? parameters = null;
nextSegment = hashString.IndexOf('$');
// Optional parameters
ReadOnlySpan<char> parametersSpan = nextSegment == -1 ? hashString : hashString[..nextSegment];
if (parametersSpan.Contains('='))
{
while (!parametersSpan.IsEmpty)
{
ReadOnlySpan<char> parameter;
int index = parametersSpan.IndexOf(',');
if (index == -1)
{
parameter = parametersSpan;
parametersSpan = ReadOnlySpan<char>.Empty;
}
else
{
parameter = parametersSpan[..index];
parametersSpan = parametersSpan[(index + 1)..];
}
int splitIndex = parameter.IndexOf('=');
if (splitIndex == -1 || splitIndex == 0 || splitIndex == parameter.Length - 1)
{
throw new FormatException("Malformed parameter in password hash string");
}
(parameters ??= new Dictionary<string, string>()).Add(
parameter[..splitIndex].ToString(),
parameter[(splitIndex + 1)..].ToString());
}
if (nextSegment == -1)
{
// parameters can't be null here
return new PasswordHash(id.ToString(), Array.Empty<byte>(), Array.Empty<byte>(), parameters!);
}
hashString = hashString[(nextSegment + 1)..];
nextSegment = hashString.IndexOf('$');
}
if (nextSegment == 0)
{
throw new FormatException("Hash string contains an empty segment");
}
byte[] hash;
byte[] salt;
if (nextSegment == -1)
{
salt = Array.Empty<byte>();
hash = Convert.FromHexString(hashString);
}
else
{
salt = Convert.FromHexString(hashString[..nextSegment]);
hashString = hashString[(nextSegment + 1)..];
nextSegment = hashString.IndexOf('$');
if (nextSegment != -1)
{
throw new FormatException("Hash string contains too many segments");
}
if (hashString.IsEmpty)
{
throw new FormatException("Hash segment is empty");
}
hash = Convert.FromHexString(hashString);
}
return new PasswordHash(id.ToString(), hash, salt, parameters ?? new Dictionary<string, string>());
}
private void SerializeParameters(StringBuilder stringBuilder)
{
if (_parameters.Count == 0)
{
return;
}
stringBuilder.Append('$');
foreach (var pair in _parameters)
{
stringBuilder.Append(pair.Key)
.Append('=')
.Append(pair.Value)
.Append(',');
}
// Remove last ','
stringBuilder.Length -= 1;
}
/// <inheritdoc />
public override string ToString()
{
var str = new StringBuilder()
.Append('$')
.Append(Id);
SerializeParameters(str);
if (_salt.Length != 0)
{
str.Append('$')
.Append(Convert.ToHexString(_salt));
}
if (_hash.Length != 0)
{
str.Append('$')
.Append(Convert.ToHexString(_hash));
}
return str.ToString();
}
}
}
+84
View File
@@ -0,0 +1,84 @@
using System;
using MediaBrowser.Model.Session;
namespace MediaBrowser.Model.Devices;
/// <summary>
/// A class for device Information.
/// </summary>
public class DeviceInfo
{
/// <summary>
/// Initializes a new instance of the <see cref="DeviceInfo"/> class.
/// </summary>
public DeviceInfo()
{
Capabilities = new ClientCapabilities();
}
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string? Name { get; set; }
/// <summary>
/// Gets or sets the custom name.
/// </summary>
/// <value>The custom name.</value>
public string? CustomName { get; set; }
/// <summary>
/// Gets or sets the access token.
/// </summary>
/// <value>The access token.</value>
public string? AccessToken { get; set; }
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
public string? Id { get; set; }
/// <summary>
/// Gets or sets the last name of the user.
/// </summary>
/// <value>The last name of the user.</value>
public string? LastUserName { get; set; }
/// <summary>
/// Gets or sets the name of the application.
/// </summary>
/// <value>The name of the application.</value>
public string? AppName { get; set; }
/// <summary>
/// Gets or sets the application version.
/// </summary>
/// <value>The application version.</value>
public string? AppVersion { get; set; }
/// <summary>
/// Gets or sets the last user identifier.
/// </summary>
/// <value>The last user identifier.</value>
public Guid? LastUserId { get; set; }
/// <summary>
/// Gets or sets the date last modified.
/// </summary>
/// <value>The date last modified.</value>
public DateTime? DateLastActivity { get; set; }
/// <summary>
/// Gets or sets the capabilities.
/// </summary>
/// <value>The capabilities.</value>
public ClientCapabilities Capabilities { get; set; }
/// <summary>
/// Gets or sets the icon URL.
/// </summary>
/// <value>The icon URL.</value>
public string? IconUrl { get; set; }
}
+94
View File
@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Model.Dlna;
/// <summary>
/// Defines the <see cref="CodecProfile"/>.
/// </summary>
public class CodecProfile
{
/// <summary>
/// Initializes a new instance of the <see cref="CodecProfile"/> class.
/// </summary>
public CodecProfile()
{
Conditions = [];
ApplyConditions = [];
}
/// <summary>
/// Gets or sets the <see cref="CodecType"/> which this container must meet.
/// </summary>
[XmlAttribute("type")]
public CodecType Type { get; set; }
/// <summary>
/// Gets or sets the list of <see cref="ProfileCondition"/> which this profile must meet.
/// </summary>
public ProfileCondition[] Conditions { get; set; }
/// <summary>
/// Gets or sets the list of <see cref="ProfileCondition"/> to apply if this profile is met.
/// </summary>
public ProfileCondition[] ApplyConditions { get; set; }
/// <summary>
/// Gets or sets the codec(s) that this profile applies to.
/// </summary>
[XmlAttribute("codec")]
public string? Codec { get; set; }
/// <summary>
/// Gets or sets the container(s) which this profile will be applied to.
/// </summary>
[XmlAttribute("container")]
public string? Container { get; set; }
/// <summary>
/// Gets or sets the sub-container(s) which this profile will be applied to.
/// </summary>
[XmlAttribute("subcontainer")]
public string? SubContainer { get; set; }
/// <summary>
/// Checks to see whether the codecs and containers contain the given parameters.
/// </summary>
/// <param name="codecs">The codecs to match.</param>
/// <param name="container">The container to match.</param>
/// <param name="useSubContainer">Consider sub-containers.</param>
/// <returns>True if both conditions are met.</returns>
public bool ContainsAnyCodec(IReadOnlyList<string> codecs, string? container, bool useSubContainer = false)
{
var containerToCheck = useSubContainer && string.Equals(Container, "hls", StringComparison.OrdinalIgnoreCase) ? SubContainer : Container;
return ContainerHelper.ContainsContainer(containerToCheck, container) && codecs.Any(c => ContainerHelper.ContainsContainer(Codec, false, c));
}
/// <summary>
/// Checks to see whether the codecs and containers contain the given parameters.
/// </summary>
/// <param name="codec">The codec to match.</param>
/// <param name="container">The container to match.</param>
/// <param name="useSubContainer">Consider sub-containers.</param>
/// <returns>True if both conditions are met.</returns>
public bool ContainsAnyCodec(string? codec, string? container, bool useSubContainer = false)
{
return ContainsAnyCodec(codec.AsSpan(), container, useSubContainer);
}
/// <summary>
/// Checks to see whether the codecs and containers contain the given parameters.
/// </summary>
/// <param name="codec">The codec to match.</param>
/// <param name="container">The container to match.</param>
/// <param name="useSubContainer">Consider sub-containers.</param>
/// <returns>True if both conditions are met.</returns>
public bool ContainsAnyCodec(ReadOnlySpan<char> codec, string? container, bool useSubContainer = false)
{
var containerToCheck = useSubContainer && string.Equals(Container, "hls", StringComparison.OrdinalIgnoreCase) ? SubContainer : Container;
return ContainerHelper.ContainsContainer(containerToCheck, container) && ContainerHelper.ContainsContainer(Codec, false, codec);
}
}
+11
View File
@@ -0,0 +1,11 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public enum CodecType
{
Video = 0,
VideoAudio = 1,
Audio = 2
}
}
@@ -0,0 +1,385 @@
using System;
using System.Globalization;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Model.Dlna
{
/// <summary>
/// The condition processor.
/// </summary>
public static class ConditionProcessor
{
/// <summary>
/// Checks if a video condition is satisfied.
/// </summary>
/// <param name="condition">The <see cref="ProfileCondition"/>.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="videoBitDepth">The bit depth.</param>
/// <param name="videoBitrate">The bitrate.</param>
/// <param name="videoProfile">The video profile.</param>
/// <param name="videoRangeType">The <see cref="VideoRangeType"/>.</param>
/// <param name="videoLevel">The video level.</param>
/// <param name="videoFramerate">The framerate.</param>
/// <param name="packetLength">The packet length.</param>
/// <param name="timestamp">The <see cref="TransportStreamTimestamp"/>.</param>
/// <param name="isAnamorphic">A value indicating whether the video is anamorphic.</param>
/// <param name="isInterlaced">A value indicating whether the video is interlaced.</param>
/// <param name="refFrames">The reference frames.</param>
/// <param name="numStreams">The number of streams.</param>
/// <param name="numVideoStreams">The number of video streams.</param>
/// <param name="numAudioStreams">The number of audio streams.</param>
/// <param name="videoCodecTag">The video codec tag.</param>
/// <param name="isAvc">A value indicating whether the video is AVC.</param>
/// <returns><b>True</b> if the condition is satisfied.</returns>
public static bool IsVideoConditionSatisfied(
ProfileCondition condition,
int? width,
int? height,
int? videoBitDepth,
int? videoBitrate,
string? videoProfile,
VideoRangeType? videoRangeType,
double? videoLevel,
float? videoFramerate,
int? packetLength,
TransportStreamTimestamp? timestamp,
bool? isAnamorphic,
bool? isInterlaced,
int? refFrames,
int numStreams,
int? numVideoStreams,
int? numAudioStreams,
string? videoCodecTag,
bool? isAvc)
{
switch (condition.Property)
{
case ProfileConditionValue.IsInterlaced:
return IsConditionSatisfied(condition, isInterlaced);
case ProfileConditionValue.IsAnamorphic:
return IsConditionSatisfied(condition, isAnamorphic);
case ProfileConditionValue.IsAvc:
return IsConditionSatisfied(condition, isAvc);
case ProfileConditionValue.VideoFramerate:
return IsConditionSatisfied(condition, videoFramerate);
case ProfileConditionValue.VideoLevel:
return IsConditionSatisfied(condition, videoLevel);
case ProfileConditionValue.VideoProfile:
return IsConditionSatisfied(condition, videoProfile);
case ProfileConditionValue.VideoRangeType:
return IsConditionSatisfied(condition, videoRangeType);
case ProfileConditionValue.VideoCodecTag:
return IsConditionSatisfied(condition, videoCodecTag);
case ProfileConditionValue.PacketLength:
return IsConditionSatisfied(condition, packetLength);
case ProfileConditionValue.VideoBitDepth:
return IsConditionSatisfied(condition, videoBitDepth);
case ProfileConditionValue.VideoBitrate:
return IsConditionSatisfied(condition, videoBitrate);
case ProfileConditionValue.Height:
return IsConditionSatisfied(condition, height);
case ProfileConditionValue.Width:
return IsConditionSatisfied(condition, width);
case ProfileConditionValue.RefFrames:
return IsConditionSatisfied(condition, refFrames);
case ProfileConditionValue.NumStreams:
return IsConditionSatisfied(condition, numStreams);
case ProfileConditionValue.NumAudioStreams:
return IsConditionSatisfied(condition, numAudioStreams);
case ProfileConditionValue.NumVideoStreams:
return IsConditionSatisfied(condition, numVideoStreams);
case ProfileConditionValue.VideoTimestamp:
return IsConditionSatisfied(condition, timestamp);
default:
return true;
}
}
/// <summary>
/// Checks if a image condition is satisfied.
/// </summary>
/// <param name="condition">The <see cref="ProfileCondition"/>.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns><b>True</b> if the condition is satisfied.</returns>
public static bool IsImageConditionSatisfied(ProfileCondition condition, int? width, int? height)
{
switch (condition.Property)
{
case ProfileConditionValue.Height:
return IsConditionSatisfied(condition, height);
case ProfileConditionValue.Width:
return IsConditionSatisfied(condition, width);
default:
throw new ArgumentException("Unexpected condition on image file: " + condition.Property);
}
}
/// <summary>
/// Checks if an audio condition is satisfied.
/// </summary>
/// <param name="condition">The <see cref="ProfileCondition"/>.</param>
/// <param name="audioChannels">The channel count.</param>
/// <param name="audioBitrate">The bitrate.</param>
/// <param name="audioSampleRate">The sample rate.</param>
/// <param name="audioBitDepth">The bit depth.</param>
/// <returns><b>True</b> if the condition is satisfied.</returns>
public static bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth)
{
switch (condition.Property)
{
case ProfileConditionValue.AudioBitrate:
return IsConditionSatisfied(condition, audioBitrate);
case ProfileConditionValue.AudioChannels:
return IsConditionSatisfied(condition, audioChannels);
case ProfileConditionValue.AudioSampleRate:
return IsConditionSatisfied(condition, audioSampleRate);
case ProfileConditionValue.AudioBitDepth:
return IsConditionSatisfied(condition, audioBitDepth);
default:
throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
}
}
/// <summary>
/// Checks if an audio condition is satisfied for a video.
/// </summary>
/// <param name="condition">The <see cref="ProfileCondition"/>.</param>
/// <param name="audioChannels">The channel count.</param>
/// <param name="audioBitrate">The bitrate.</param>
/// <param name="audioSampleRate">The sample rate.</param>
/// <param name="audioBitDepth">The bit depth.</param>
/// <param name="audioProfile">The profile.</param>
/// <param name="isSecondaryTrack">A value indicating whether the audio is a secondary track.</param>
/// <returns><b>True</b> if the condition is satisfied.</returns>
public static bool IsVideoAudioConditionSatisfied(
ProfileCondition condition,
int? audioChannels,
int? audioBitrate,
int? audioSampleRate,
int? audioBitDepth,
string? audioProfile,
bool? isSecondaryTrack)
{
switch (condition.Property)
{
case ProfileConditionValue.AudioProfile:
return IsConditionSatisfied(condition, audioProfile);
case ProfileConditionValue.AudioBitrate:
return IsConditionSatisfied(condition, audioBitrate);
case ProfileConditionValue.AudioChannels:
return IsConditionSatisfied(condition, audioChannels);
case ProfileConditionValue.IsSecondaryAudio:
return IsConditionSatisfied(condition, isSecondaryTrack);
case ProfileConditionValue.AudioSampleRate:
return IsConditionSatisfied(condition, audioSampleRate);
case ProfileConditionValue.AudioBitDepth:
return IsConditionSatisfied(condition, audioBitDepth);
default:
throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
}
}
private static bool IsConditionSatisfied(ProfileCondition condition, int? currentValue)
{
if (!currentValue.HasValue)
{
// If the value is unknown, it satisfies if not marked as required
return !condition.IsRequired;
}
var conditionType = condition.Condition;
if (condition.Condition == ProfileConditionType.EqualsAny)
{
foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
{
if (int.TryParse(singleConditionString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int conditionValue)
&& conditionValue.Equals(currentValue))
{
return true;
}
}
return false;
}
if (int.TryParse(condition.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var expected))
{
switch (conditionType)
{
case ProfileConditionType.Equals:
return currentValue.Value.Equals(expected);
case ProfileConditionType.GreaterThanEqual:
return currentValue.Value >= expected;
case ProfileConditionType.LessThanEqual:
return currentValue.Value <= expected;
case ProfileConditionType.NotEquals:
return !currentValue.Value.Equals(expected);
default:
throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
}
}
return false;
}
private static bool IsConditionSatisfied(ProfileCondition condition, string? currentValue)
{
if (string.IsNullOrEmpty(currentValue))
{
// If the value is unknown, it satisfies if not marked as required
return !condition.IsRequired;
}
string expected = condition.Value;
switch (condition.Condition)
{
case ProfileConditionType.EqualsAny:
return expected.Split('|').Contains(currentValue, StringComparison.OrdinalIgnoreCase);
case ProfileConditionType.Equals:
return string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
case ProfileConditionType.NotEquals:
return !string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
default:
throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
}
}
private static bool IsConditionSatisfied(ProfileCondition condition, bool? currentValue)
{
if (!currentValue.HasValue)
{
// If the value is unknown, it satisfies if not marked as required
return !condition.IsRequired;
}
if (bool.TryParse(condition.Value, out var expected))
{
switch (condition.Condition)
{
case ProfileConditionType.Equals:
return currentValue.Value == expected;
case ProfileConditionType.NotEquals:
return currentValue.Value != expected;
default:
throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
}
}
return false;
}
private static bool IsConditionSatisfied(ProfileCondition condition, double? currentValue)
{
if (!currentValue.HasValue)
{
// If the value is unknown, it satisfies if not marked as required
return !condition.IsRequired;
}
var conditionType = condition.Condition;
if (condition.Condition == ProfileConditionType.EqualsAny)
{
foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
{
if (double.TryParse(singleConditionString, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out double conditionValue)
&& conditionValue.Equals(currentValue))
{
return true;
}
}
return false;
}
if (double.TryParse(condition.Value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var expected))
{
switch (conditionType)
{
case ProfileConditionType.Equals:
return currentValue.Value.Equals(expected);
case ProfileConditionType.GreaterThanEqual:
return currentValue.Value >= expected;
case ProfileConditionType.LessThanEqual:
return currentValue.Value <= expected;
case ProfileConditionType.NotEquals:
return !currentValue.Value.Equals(expected);
default:
throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
}
}
return false;
}
private static bool IsConditionSatisfied(ProfileCondition condition, TransportStreamTimestamp? timestamp)
{
if (!timestamp.HasValue)
{
// If the value is unknown, it satisfies if not marked as required
return !condition.IsRequired;
}
var expected = (TransportStreamTimestamp)Enum.Parse(typeof(TransportStreamTimestamp), condition.Value, true);
switch (condition.Condition)
{
case ProfileConditionType.Equals:
return timestamp == expected;
case ProfileConditionType.NotEquals:
return timestamp != expected;
default:
throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
}
}
private static bool IsConditionSatisfied(ProfileCondition condition, VideoRangeType? currentValue)
{
if (!currentValue.HasValue || currentValue.Equals(VideoRangeType.Unknown))
{
// If the value is unknown, it satisfies if not marked as required
return !condition.IsRequired;
}
// Special case: HDR10 also satisfies if the video is HDR10Plus
if (currentValue.Value == VideoRangeType.HDR10Plus)
{
if (IsConditionSatisfied(condition, VideoRangeType.HDR10))
{
return true;
}
}
var conditionType = condition.Condition;
if (conditionType == ProfileConditionType.EqualsAny)
{
foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
{
if (Enum.TryParse(singleConditionString, true, out VideoRangeType conditionValue)
&& conditionValue.Equals(currentValue))
{
return true;
}
}
return false;
}
if (Enum.TryParse(condition.Value, true, out VideoRangeType expected))
{
return conditionType switch
{
ProfileConditionType.Equals => currentValue.Value == expected,
ProfileConditionType.NotEquals => currentValue.Value != expected,
_ => throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition)
};
}
return false;
}
}
}
@@ -0,0 +1,49 @@
#pragma warning disable CA1819 // Properties should not return arrays
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Model.Dlna;
/// <summary>
/// Defines the <see cref="ContainerProfile"/>.
/// </summary>
public class ContainerProfile
{
/// <summary>
/// Gets or sets the <see cref="DlnaProfileType"/> which this container must meet.
/// </summary>
[XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
/// <summary>
/// Gets or sets the list of <see cref="ProfileCondition"/> which this container will be applied to.
/// </summary>
public ProfileCondition[] Conditions { get; set; } = [];
/// <summary>
/// Gets or sets the container(s) which this container must meet.
/// </summary>
[XmlAttribute("container")]
public string? Container { get; set; }
/// <summary>
/// Gets or sets the sub container(s) which this container must meet.
/// </summary>
[XmlAttribute("subcontainer")]
public string? SubContainer { get; set; }
/// <summary>
/// Returns true if an item in <paramref name="container"/> appears in the <see cref="Container"/> property.
/// </summary>
/// <param name="container">The item to match.</param>
/// <param name="useSubContainer">Consider subcontainers.</param>
/// <returns>The result of the operation.</returns>
public bool ContainsContainer(ReadOnlySpan<char> container, bool useSubContainer = false)
{
var containerToCheck = useSubContainer && string.Equals(Container, "hls", StringComparison.OrdinalIgnoreCase) ? SubContainer : Container;
return ContainerHelper.ContainsContainer(containerToCheck, container);
}
}
+71
View File
@@ -0,0 +1,71 @@
#pragma warning disable CA1819 // Properties should not return arrays
using System;
namespace MediaBrowser.Model.Dlna;
/// <summary>
/// A <see cref="DeviceProfile" /> represents a set of metadata which determines which content a certain device is able to play.
/// <br/>
/// Specifically, it defines the supported <see cref="ContainerProfiles">containers</see> and
/// <see cref="CodecProfiles">codecs</see> (video and/or audio, including codec profiles and levels)
/// the device is able to direct play (without transcoding or remuxing),
/// as well as which <see cref="TranscodingProfiles">containers/codecs to transcode to</see> in case it isn't.
/// </summary>
public class DeviceProfile
{
/// <summary>
/// Gets or sets the name of this device profile. User profiles must have a unique name.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Gets or sets the unique internal identifier.
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// Gets or sets the maximum allowed bitrate for all streamed content.
/// </summary>
public int? MaxStreamingBitrate { get; set; } = 8000000;
/// <summary>
/// Gets or sets the maximum allowed bitrate for statically streamed content (= direct played files).
/// </summary>
public int? MaxStaticBitrate { get; set; } = 8000000;
/// <summary>
/// Gets or sets the maximum allowed bitrate for transcoded music streams.
/// </summary>
public int? MusicStreamingTranscodingBitrate { get; set; } = 128000;
/// <summary>
/// Gets or sets the maximum allowed bitrate for statically streamed (= direct played) music files.
/// </summary>
public int? MaxStaticMusicBitrate { get; set; } = 8000000;
/// <summary>
/// Gets or sets the direct play profiles.
/// </summary>
public DirectPlayProfile[] DirectPlayProfiles { get; set; } = [];
/// <summary>
/// Gets or sets the transcoding profiles.
/// </summary>
public TranscodingProfile[] TranscodingProfiles { get; set; } = [];
/// <summary>
/// Gets or sets the container profiles. Failing to meet these optional conditions causes transcoding to occur.
/// </summary>
public ContainerProfile[] ContainerProfiles { get; set; } = [];
/// <summary>
/// Gets or sets the codec profiles.
/// </summary>
public CodecProfile[] CodecProfiles { get; set; } = [];
/// <summary>
/// Gets or sets the subtitle profiles.
/// </summary>
public SubtitleProfile[] SubtitleProfiles { get; set; } = [];
}
@@ -0,0 +1,65 @@
using System.Xml.Serialization;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Model.Dlna;
/// <summary>
/// Defines the <see cref="DirectPlayProfile"/>.
/// </summary>
public class DirectPlayProfile
{
/// <summary>
/// Gets or sets the container.
/// </summary>
[XmlAttribute("container")]
public string Container { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the audio codec.
/// </summary>
[XmlAttribute("audioCodec")]
public string? AudioCodec { get; set; }
/// <summary>
/// Gets or sets the video codec.
/// </summary>
[XmlAttribute("videoCodec")]
public string? VideoCodec { get; set; }
/// <summary>
/// Gets or sets the Dlna profile type.
/// </summary>
[XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
/// <summary>
/// Returns whether the <see cref="Container"/> supports the <paramref name="container"/>.
/// </summary>
/// <param name="container">The container to match against.</param>
/// <returns>True if supported.</returns>
public bool SupportsContainer(string? container)
{
return ContainerHelper.ContainsContainer(Container, container);
}
/// <summary>
/// Returns whether the <see cref="VideoCodec"/> supports the <paramref name="codec"/>.
/// </summary>
/// <param name="codec">The codec to match against.</param>
/// <returns>True if supported.</returns>
public bool SupportsVideoCodec(string? codec)
{
return Type == DlnaProfileType.Video && ContainerHelper.ContainsContainer(VideoCodec, codec);
}
/// <summary>
/// Returns whether the <see cref="AudioCodec"/> supports the <paramref name="codec"/>.
/// </summary>
/// <param name="codec">The codec to match against.</param>
/// <returns>True if supported.</returns>
public bool SupportsAudioCodec(string? codec)
{
// Video profiles can have audio codec restrictions too, therefore include Video as valid type.
return (Type == DlnaProfileType.Audio || Type == DlnaProfileType.Video) && ContainerHelper.ContainsContainer(AudioCodec, codec);
}
}
@@ -0,0 +1,13 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public enum DlnaProfileType
{
Audio = 0,
Video = 1,
Photo = 2,
Subtitle = 3,
Lyric = 4
}
}
@@ -0,0 +1,10 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public enum EncodingContext
{
Streaming = 0,
Static = 1
}
}
@@ -0,0 +1,13 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public interface ITranscoderSupport
{
bool CanEncodeToAudioCodec(string codec);
bool CanEncodeToSubtitleCodec(string codec);
bool CanExtractSubtitles(string codec);
}
}
+145
View File
@@ -0,0 +1,145 @@
using System;
using MediaBrowser.Model.Dto;
namespace MediaBrowser.Model.Dlna
{
/// <summary>
/// Class MediaOptions.
/// </summary>
public class MediaOptions
{
/// <summary>
/// Initializes a new instance of the <see cref="MediaOptions"/> class.
/// </summary>
public MediaOptions()
{
Context = EncodingContext.Streaming;
EnableDirectPlay = true;
EnableDirectStream = true;
}
/// <summary>
/// Gets or sets a value indicating whether direct playback is allowed.
/// </summary>
public bool EnableDirectPlay { get; set; }
/// <summary>
/// Gets or sets a value indicating whether direct streaming is allowed.
/// </summary>
public bool EnableDirectStream { get; set; }
/// <summary>
/// Gets or sets a value indicating whether direct playback is forced.
/// </summary>
public bool ForceDirectPlay { get; set; }
/// <summary>
/// Gets or sets a value indicating whether direct streaming is forced.
/// </summary>
public bool ForceDirectStream { get; set; }
/// <summary>
/// Gets or sets a value indicating whether audio stream copy is allowed.
/// </summary>
public bool AllowAudioStreamCopy { get; set; }
/// <summary>
/// Gets or sets a value indicating whether video stream copy is allowed.
/// </summary>
public bool AllowVideoStreamCopy { get; set; }
/// <summary>
/// Gets or sets a value indicating whether always burn in subtitles when transcoding.
/// </summary>
public bool AlwaysBurnInSubtitleWhenTranscoding { get; set; }
/// <summary>
/// Gets or sets the item id.
/// </summary>
public Guid ItemId { get; set; }
/// <summary>
/// Gets or sets the media sources.
/// </summary>
public MediaSourceInfo[] MediaSources { get; set; } = Array.Empty<MediaSourceInfo>();
/// <summary>
/// Gets or sets the device profile.
/// </summary>
public required DeviceProfile Profile { get; set; }
/// <summary>
/// Gets or sets a media source id. Optional. Only needed if a specific AudioStreamIndex or SubtitleStreamIndex are requested.
/// </summary>
public string? MediaSourceId { get; set; }
/// <summary>
/// Gets or sets the device id.
/// </summary>
public string? DeviceId { get; set; }
/// <summary>
/// Gets or sets an override of supported number of audio channels
/// Example: DeviceProfile supports five channel, but user only has stereo speakers.
/// </summary>
public int? MaxAudioChannels { get; set; }
/// <summary>
/// Gets or sets the application's configured maximum bitrate.
/// </summary>
public int? MaxBitrate { get; set; }
/// <summary>
/// Gets or sets the context.
/// </summary>
/// <value>The context.</value>
public EncodingContext Context { get; set; }
/// <summary>
/// Gets or sets the audio transcoding bitrate.
/// </summary>
/// <value>The audio transcoding bitrate.</value>
public int? AudioTranscodingBitrate { get; set; }
/// <summary>
/// Gets or sets an override for the audio stream index.
/// </summary>
public int? AudioStreamIndex { get; set; }
/// <summary>
/// Gets or sets an override for the subtitle stream index.
/// </summary>
public int? SubtitleStreamIndex { get; set; }
/// <summary>
/// Gets the maximum bitrate.
/// </summary>
/// <param name="isAudio">Whether or not this is audio.</param>
/// <returns>System.Nullable&lt;System.Int32&gt;.</returns>
public int? GetMaxBitrate(bool isAudio)
{
if (MaxBitrate.HasValue)
{
return MaxBitrate;
}
if (Profile is null)
{
return null;
}
if (Context == EncodingContext.Static)
{
if (isAudio && Profile.MaxStaticMusicBitrate.HasValue)
{
return Profile.MaxStaticMusicBitrate;
}
return Profile.MaxStaticBitrate;
}
return Profile.MaxStreamingBitrate;
}
}
}
@@ -0,0 +1,11 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public enum PlaybackErrorCode
{
NotAllowed = 0,
NoCompatibleStream = 1,
RateLimitExceeded = 2
}
}
@@ -0,0 +1,40 @@
#nullable disable
#pragma warning disable CS1591
using System.Xml.Serialization;
namespace MediaBrowser.Model.Dlna
{
public class ProfileCondition
{
public ProfileCondition()
{
IsRequired = true;
}
public ProfileCondition(ProfileConditionType condition, ProfileConditionValue property, string value)
: this(condition, property, value, false)
{
}
public ProfileCondition(ProfileConditionType condition, ProfileConditionValue property, string value, bool isRequired)
{
Condition = condition;
Property = property;
Value = value;
IsRequired = isRequired;
}
[XmlAttribute("condition")]
public ProfileConditionType Condition { get; set; }
[XmlAttribute("property")]
public ProfileConditionValue Property { get; set; }
[XmlAttribute("value")]
public string Value { get; set; }
[XmlAttribute("isRequired")]
public bool IsRequired { get; set; }
}
}
@@ -0,0 +1,13 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public enum ProfileConditionType
{
Equals = 0,
NotEquals = 1,
LessThanEqual = 2,
GreaterThanEqual = 3,
EqualsAny = 4
}
}
@@ -0,0 +1,33 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public enum ProfileConditionValue
{
AudioChannels = 0,
AudioBitrate = 1,
AudioProfile = 2,
Width = 3,
Height = 4,
Has64BitOffsets = 5,
PacketLength = 6,
VideoBitDepth = 7,
VideoBitrate = 8,
VideoFramerate = 9,
VideoLevel = 10,
VideoProfile = 11,
VideoTimestamp = 12,
IsAnamorphic = 13,
RefFrames = 14,
NumAudioStreams = 16,
NumVideoStreams = 17,
IsSecondaryAudio = 18,
VideoCodecTag = 19,
IsAvc = 20,
IsInterlaced = 21,
AudioSampleRate = 22,
AudioBitDepth = 23,
VideoRangeType = 24,
NumStreams = 25
}
}
@@ -0,0 +1,17 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public class ResolutionConfiguration
{
public ResolutionConfiguration(int maxWidth, int maxBitrate)
{
MaxWidth = maxWidth;
MaxBitrate = maxBitrate;
}
public int MaxWidth { get; set; }
public int MaxBitrate { get; set; }
}
}
@@ -0,0 +1,85 @@
#nullable disable
#pragma warning disable CS1591
using System;
using System.Linq;
namespace MediaBrowser.Model.Dlna
{
public static class ResolutionNormalizer
{
// Please note: all bitrate here are in the scale of SDR h264 bitrate at 30fps
private static readonly ResolutionConfiguration[] _configurations =
[
new ResolutionConfiguration(416, 365000),
new ResolutionConfiguration(640, 730000),
new ResolutionConfiguration(768, 1100000),
new ResolutionConfiguration(960, 3000000),
new ResolutionConfiguration(1280, 6000000),
new ResolutionConfiguration(1920, 13500000),
new ResolutionConfiguration(2560, 28000000),
new ResolutionConfiguration(3840, 50000000)
];
public static ResolutionOptions Normalize(
int? inputBitrate,
int outputBitrate,
int h264EquivalentOutputBitrate,
int? maxWidth,
int? maxHeight,
float? targetFps,
bool isHdr = false) // We are not doing HDR transcoding for now, leave for future use
{
// If the bitrate isn't changing, then don't downscale the resolution
if (inputBitrate.HasValue && outputBitrate >= inputBitrate.Value)
{
if (maxWidth.HasValue || maxHeight.HasValue)
{
return new ResolutionOptions
{
MaxWidth = maxWidth,
MaxHeight = maxHeight
};
}
}
// Our reference bitrate is based on SDR h264 at 30fps
var referenceFps = targetFps ?? 30.0f;
var referenceScale = referenceFps <= 30.0f
? 30.0f / referenceFps
: 1.0f / MathF.Sqrt(referenceFps / 30.0f);
var referenceBitrate = h264EquivalentOutputBitrate * referenceScale;
if (isHdr)
{
referenceBitrate *= 0.8f;
}
var resolutionConfig = GetResolutionConfiguration(Convert.ToInt32(referenceBitrate));
if (resolutionConfig is null)
{
return new ResolutionOptions { MaxWidth = maxWidth, MaxHeight = maxHeight };
}
var originWidthValue = maxWidth;
maxWidth = Math.Min(resolutionConfig.MaxWidth, maxWidth ?? resolutionConfig.MaxWidth);
if (!originWidthValue.HasValue || originWidthValue.Value != maxWidth.Value)
{
maxHeight = null;
}
return new ResolutionOptions
{
MaxWidth = maxWidth,
MaxHeight = maxHeight
};
}
private static ResolutionConfiguration GetResolutionConfiguration(int outputBitrate)
{
return _configurations.FirstOrDefault(config => outputBitrate <= config.MaxBitrate);
}
}
}
@@ -0,0 +1,11 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public class ResolutionOptions
{
public int? MaxWidth { get; set; }
public int? MaxHeight { get; set; }
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,35 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
/// <summary>
/// Delivery method to use during playback of a specific subtitle format.
/// </summary>
public enum SubtitleDeliveryMethod
{
/// <summary>
/// Burn the subtitles in the video track.
/// </summary>
Encode = 0,
/// <summary>
/// Embed the subtitles in the file or stream.
/// </summary>
Embed = 1,
/// <summary>
/// Serve the subtitles as an external file.
/// </summary>
External = 2,
/// <summary>
/// Serve the subtitles as a separate HLS stream.
/// </summary>
Hls = 3,
/// <summary>
/// Drop the subtitle.
/// </summary>
Drop = 4
}
}
@@ -0,0 +1,62 @@
#nullable disable
using System.Xml.Serialization;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Model.Dlna;
/// <summary>
/// A class for subtitle profile information.
/// </summary>
public class SubtitleProfile
{
/// <summary>
/// Gets or sets the format.
/// </summary>
[XmlAttribute("format")]
public string Format { get; set; }
/// <summary>
/// Gets or sets the delivery method.
/// </summary>
[XmlAttribute("method")]
public SubtitleDeliveryMethod Method { get; set; }
/// <summary>
/// Gets or sets the DIDL mode.
/// </summary>
[XmlAttribute("didlMode")]
public string DidlMode { get; set; }
/// <summary>
/// Gets or sets the language.
/// </summary>
[XmlAttribute("language")]
public string Language { get; set; }
/// <summary>
/// Gets or sets the container.
/// </summary>
[XmlAttribute("container")]
public string Container { get; set; }
/// <summary>
/// Checks if a language is supported.
/// </summary>
/// <param name="subLanguage">The language to check for support.</param>
/// <returns><c>true</c> if supported.</returns>
public bool SupportsLanguage(string subLanguage)
{
if (string.IsNullOrEmpty(Language))
{
return true;
}
if (string.IsNullOrEmpty(subLanguage))
{
subLanguage = "und";
}
return ContainerHelper.ContainsContainer(Language, subLanguage);
}
}
@@ -0,0 +1,26 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public class SubtitleStreamInfo
{
public string Url { get; set; }
public string Language { get; set; }
public string Name { get; set; }
public bool IsForced { get; set; }
public string Format { get; set; }
public string DisplayTitle { get; set; }
public int Index { get; set; }
public SubtitleDeliveryMethod DeliveryMethod { get; set; }
public bool IsExternalUrl { get; set; }
}
}
@@ -0,0 +1,10 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dlna
{
public enum TranscodeSeekInfo
{
Auto = 0,
Bytes = 1
}
}
@@ -0,0 +1,159 @@
using System;
using System.ComponentModel;
using System.Xml.Serialization;
using Jellyfin.Data.Enums;
namespace MediaBrowser.Model.Dlna;
/// <summary>
/// A class for transcoding profile information.
/// Note for client developers: Conditions defined in <see cref="CodecProfile"/> has higher priority and can override values defined here.
/// </summary>
public class TranscodingProfile
{
/// <summary>
/// Initializes a new instance of the <see cref="TranscodingProfile" /> class.
/// </summary>
public TranscodingProfile()
{
Conditions = [];
}
/// <summary>
/// Initializes a new instance of the <see cref="TranscodingProfile" /> class copying the values from another instance.
/// </summary>
/// <param name="other">Another instance of <see cref="TranscodingProfile" /> to be copied.</param>
public TranscodingProfile(TranscodingProfile other)
{
ArgumentNullException.ThrowIfNull(other);
Container = other.Container;
Type = other.Type;
VideoCodec = other.VideoCodec;
AudioCodec = other.AudioCodec;
Protocol = other.Protocol;
EstimateContentLength = other.EstimateContentLength;
EnableMpegtsM2TsMode = other.EnableMpegtsM2TsMode;
TranscodeSeekInfo = other.TranscodeSeekInfo;
CopyTimestamps = other.CopyTimestamps;
Context = other.Context;
EnableSubtitlesInManifest = other.EnableSubtitlesInManifest;
MaxAudioChannels = other.MaxAudioChannels;
MinSegments = other.MinSegments;
SegmentLength = other.SegmentLength;
Conditions = other.Conditions;
EnableAudioVbrEncoding = other.EnableAudioVbrEncoding;
}
/// <summary>
/// Gets or sets the container.
/// </summary>
[XmlAttribute("container")]
public string Container { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the DLNA profile type.
/// </summary>
[XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
/// <summary>
/// Gets or sets the video codec.
/// </summary>
[XmlAttribute("videoCodec")]
public string VideoCodec { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the audio codec.
/// </summary>
[XmlAttribute("audioCodec")]
public string AudioCodec { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the protocol.
/// </summary>
[XmlAttribute("protocol")]
public MediaStreamProtocol Protocol { get; set; } = MediaStreamProtocol.http;
/// <summary>
/// Gets or sets a value indicating whether the content length should be estimated.
/// </summary>
[DefaultValue(false)]
[XmlAttribute("estimateContentLength")]
public bool EstimateContentLength { get; set; }
/// <summary>
/// Gets or sets a value indicating whether M2TS mode is enabled.
/// </summary>
[DefaultValue(false)]
[XmlAttribute("enableMpegtsM2TsMode")]
public bool EnableMpegtsM2TsMode { get; set; }
/// <summary>
/// Gets or sets the transcoding seek info mode.
/// </summary>
[DefaultValue(TranscodeSeekInfo.Auto)]
[XmlAttribute("transcodeSeekInfo")]
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
/// <summary>
/// Gets or sets a value indicating whether timestamps should be copied.
/// </summary>
[DefaultValue(false)]
[XmlAttribute("copyTimestamps")]
public bool CopyTimestamps { get; set; }
/// <summary>
/// Gets or sets the encoding context.
/// </summary>
[DefaultValue(EncodingContext.Streaming)]
[XmlAttribute("context")]
public EncodingContext Context { get; set; }
/// <summary>
/// Gets or sets a value indicating whether subtitles are allowed in the manifest.
/// </summary>
[DefaultValue(false)]
[XmlAttribute("enableSubtitlesInManifest")]
public bool EnableSubtitlesInManifest { get; set; }
/// <summary>
/// Gets or sets the maximum audio channels.
/// </summary>
[XmlAttribute("maxAudioChannels")]
public string? MaxAudioChannels { get; set; }
/// <summary>
/// Gets or sets the minimum amount of segments.
/// </summary>
[DefaultValue(0)]
[XmlAttribute("minSegments")]
public int MinSegments { get; set; }
/// <summary>
/// Gets or sets the segment length.
/// </summary>
[DefaultValue(0)]
[XmlAttribute("segmentLength")]
public int SegmentLength { get; set; }
/// <summary>
/// Gets or sets a value indicating whether breaking the video stream on non-keyframes is supported.
/// </summary>
[DefaultValue(false)]
[XmlAttribute("breakOnNonKeyFrames")]
[Obsolete("This is always false")]
public bool? BreakOnNonKeyFrames { get; set; }
/// <summary>
/// Gets or sets the profile conditions.
/// </summary>
public ProfileCondition[] Conditions { get; set; }
/// <summary>
/// Gets or sets a value indicating whether variable bitrate encoding is supported.
/// </summary>
[DefaultValue(true)]
[XmlAttribute("enableAudioVbrEncoding")]
public bool EnableAudioVbrEncoding { get; set; } = true;
}
+126
View File
@@ -0,0 +1,126 @@
using System;
namespace MediaBrowser.Model.Drawing
{
/// <summary>
/// Class DrawingUtils.
/// </summary>
public static class DrawingUtils
{
/// <summary>
/// Resizes a set of dimensions.
/// </summary>
/// <param name="size">The original size object.</param>
/// <param name="width">A new fixed width, if desired.</param>
/// <param name="height">A new fixed height, if desired.</param>
/// <param name="maxWidth">A max fixed width, if desired.</param>
/// <param name="maxHeight">A max fixed height, if desired.</param>
/// <returns>A new size object.</returns>
public static ImageDimensions Resize(
ImageDimensions size,
int width,
int height,
int maxWidth,
int maxHeight)
{
int newWidth = size.Width;
int newHeight = size.Height;
if (width > 0 && height > 0)
{
newWidth = width;
newHeight = height;
}
else if (height > 0)
{
newWidth = GetNewWidth(newHeight, newWidth, height);
newHeight = height;
}
else if (width > 0)
{
newHeight = GetNewHeight(newHeight, newWidth, width);
newWidth = width;
}
if (maxHeight > 0 && maxHeight < newHeight)
{
newWidth = GetNewWidth(newHeight, newWidth, maxHeight);
newHeight = maxHeight;
}
if (maxWidth > 0 && maxWidth < newWidth)
{
newHeight = GetNewHeight(newHeight, newWidth, maxWidth);
newWidth = maxWidth;
}
return new ImageDimensions(newWidth, newHeight);
}
/// <summary>
/// Scale down to fill box.
/// Returns original size if both width and height are null or zero.
/// </summary>
/// <param name="size">The original size object.</param>
/// <param name="fillWidth">A new fixed width, if desired.</param>
/// <param name="fillHeight">A new fixed height, if desired.</param>
/// <returns>A new size object or size.</returns>
public static ImageDimensions ResizeFill(
ImageDimensions size,
int? fillWidth,
int? fillHeight)
{
// Return original size if input is invalid.
if ((fillWidth is null || fillWidth == 0)
&& (fillHeight is null || fillHeight == 0))
{
return size;
}
if (fillWidth is null || fillWidth == 0)
{
fillWidth = 1;
}
if (fillHeight is null || fillHeight == 0)
{
fillHeight = 1;
}
double widthRatio = size.Width / (double)fillWidth;
double heightRatio = size.Height / (double)fillHeight;
double scaleRatio = Math.Min(widthRatio, heightRatio);
// Clamp to current size.
if (scaleRatio < 1)
{
return size;
}
int newWidth = Convert.ToInt32(Math.Ceiling(size.Width / scaleRatio));
int newHeight = Convert.ToInt32(Math.Ceiling(size.Height / scaleRatio));
return new ImageDimensions(newWidth, newHeight);
}
/// <summary>
/// Gets the new width.
/// </summary>
/// <param name="currentHeight">Height of the current.</param>
/// <param name="currentWidth">Width of the current.</param>
/// <param name="newHeight">The new height.</param>
/// <returns>The new width.</returns>
private static int GetNewWidth(int currentHeight, int currentWidth, int newHeight)
=> Convert.ToInt32((double)newHeight / currentHeight * currentWidth);
/// <summary>
/// Gets the new height.
/// </summary>
/// <param name="currentHeight">Height of the current.</param>
/// <param name="currentWidth">Width of the current.</param>
/// <param name="newWidth">The new width.</param>
/// <returns>System.Double.</returns>
private static int GetNewHeight(int currentHeight, int currentWidth, int newWidth)
=> Convert.ToInt32((double)newWidth / currentWidth * currentHeight);
}
}
@@ -0,0 +1,45 @@
#pragma warning disable CS1591
using System.Globalization;
namespace MediaBrowser.Model.Drawing
{
/// <summary>
/// Struct ImageDimensions.
/// </summary>
public readonly struct ImageDimensions
{
public ImageDimensions(int width, int height)
{
Width = width;
Height = height;
}
/// <summary>
/// Gets the height.
/// </summary>
/// <value>The height.</value>
public int Height { get; }
/// <summary>
/// Gets the width.
/// </summary>
/// <value>The width.</value>
public int Width { get; }
public bool Equals(ImageDimensions size)
{
return Width.Equals(size.Width) && Height.Equals(size.Height);
}
/// <inheritdoc />
public override string ToString()
{
return string.Format(
CultureInfo.InvariantCulture,
"{0}-{1}",
Width,
Height);
}
}
}
+38
View File
@@ -0,0 +1,38 @@
namespace MediaBrowser.Model.Drawing
{
/// <summary>
/// Enum ImageOutputFormat.
/// </summary>
public enum ImageFormat
{
/// <summary>
/// BMP format.
/// </summary>
Bmp,
/// <summary>
/// GIF format.
/// </summary>
Gif,
/// <summary>
/// JPG format.
/// </summary>
Jpg,
/// <summary>
/// PNG format.
/// </summary>
Png,
/// <summary>
/// WEBP format.
/// </summary>
Webp,
/// <summary>
/// SVG format.
/// </summary>
Svg,
}
}
@@ -0,0 +1,46 @@
using System.ComponentModel;
using System.Net.Mime;
namespace MediaBrowser.Model.Drawing;
/// <summary>
/// Extension class for the <see cref="ImageFormat" /> enum.
/// </summary>
public static class ImageFormatExtensions
{
/// <summary>
/// Returns the correct mime type for this <see cref="ImageFormat" />.
/// </summary>
/// <param name="format">This <see cref="ImageFormat" />.</param>
/// <exception cref="InvalidEnumArgumentException">The <paramref name="format"/> is an invalid enumeration value.</exception>
/// <returns>The correct mime type for this <see cref="ImageFormat" />.</returns>
public static string GetMimeType(this ImageFormat format)
=> format switch
{
ImageFormat.Bmp => MediaTypeNames.Image.Bmp,
ImageFormat.Gif => MediaTypeNames.Image.Gif,
ImageFormat.Jpg => MediaTypeNames.Image.Jpeg,
ImageFormat.Png => MediaTypeNames.Image.Png,
ImageFormat.Webp => MediaTypeNames.Image.Webp,
ImageFormat.Svg => MediaTypeNames.Image.Svg,
_ => throw new InvalidEnumArgumentException(nameof(format), (int)format, typeof(ImageFormat))
};
/// <summary>
/// Returns the correct extension for this <see cref="ImageFormat" />.
/// </summary>
/// <param name="format">This <see cref="ImageFormat" />.</param>
/// <exception cref="InvalidEnumArgumentException">The <paramref name="format"/> is an invalid enumeration value.</exception>
/// <returns>The correct extension for this <see cref="ImageFormat" />.</returns>
public static string GetExtension(this ImageFormat format)
=> format switch
{
ImageFormat.Bmp => ".bmp",
ImageFormat.Gif => ".gif",
ImageFormat.Jpg => ".jpg",
ImageFormat.Png => ".png",
ImageFormat.Webp => ".webp",
ImageFormat.Svg => ".svg",
_ => throw new InvalidEnumArgumentException(nameof(format), (int)format, typeof(ImageFormat))
};
}
@@ -0,0 +1,16 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Drawing
{
public enum ImageOrientation
{
TopLeft = 1,
TopRight = 2,
BottomRight = 3,
BottomLeft = 4,
LeftTop = 5,
RightTop = 6,
RightBottom = 7,
LeftBottom = 8,
}
}
@@ -0,0 +1,52 @@
namespace MediaBrowser.Model.Drawing;
/// <summary>
/// Enum ImageResolution.
/// </summary>
public enum ImageResolution
{
/// <summary>
/// MatchSource.
/// </summary>
MatchSource = 0,
/// <summary>
/// 144p.
/// </summary>
P144 = 1,
/// <summary>
/// 240p.
/// </summary>
P240 = 2,
/// <summary>
/// 360p.
/// </summary>
P360 = 3,
/// <summary>
/// 480p.
/// </summary>
P480 = 4,
/// <summary>
/// 720p.
/// </summary>
P720 = 5,
/// <summary>
/// 1080p.
/// </summary>
P1080 = 6,
/// <summary>
/// 1440p.
/// </summary>
P1440 = 7,
/// <summary>
/// 2160p.
/// </summary>
P2160 = 8
}
+798
View File
@@ -0,0 +1,798 @@
#nullable disable
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Providers;
namespace MediaBrowser.Model.Dto
{
/// <summary>
/// This is strictly used as a data transfer object from the api layer.
/// This holds information about a BaseItem in a format that is convenient for the client.
/// </summary>
public class BaseItemDto : IHasProviderIds, IItemDto, IHasServerId
{
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
public string OriginalTitle { get; set; }
/// <summary>
/// Gets or sets the server identifier.
/// </summary>
/// <value>The server identifier.</value>
public string ServerId { get; set; }
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
public Guid Id { get; set; }
/// <summary>
/// Gets or sets the etag.
/// </summary>
/// <value>The etag.</value>
public string Etag { get; set; }
/// <summary>
/// Gets or sets the type of the source.
/// </summary>
/// <value>The type of the source.</value>
public string SourceType { get; set; }
/// <summary>
/// Gets or sets the playlist item identifier.
/// </summary>
/// <value>The playlist item identifier.</value>
public string PlaylistItemId { get; set; }
/// <summary>
/// Gets or sets the date created.
/// </summary>
/// <value>The date created.</value>
public DateTime? DateCreated { get; set; }
public DateTime? DateLastMediaAdded { get; set; }
public ExtraType? ExtraType { get; set; }
public int? AirsBeforeSeasonNumber { get; set; }
public int? AirsAfterSeasonNumber { get; set; }
public int? AirsBeforeEpisodeNumber { get; set; }
public bool? CanDelete { get; set; }
public bool? CanDownload { get; set; }
public bool? HasLyrics { get; set; }
public bool? HasSubtitles { get; set; }
public string PreferredMetadataLanguage { get; set; }
public string PreferredMetadataCountryCode { get; set; }
public string Container { get; set; }
/// <summary>
/// Gets or sets the name of the sort.
/// </summary>
/// <value>The name of the sort.</value>
public string SortName { get; set; }
public string ForcedSortName { get; set; }
/// <summary>
/// Gets or sets the video3 D format.
/// </summary>
/// <value>The video3 D format.</value>
public Video3DFormat? Video3DFormat { get; set; }
/// <summary>
/// Gets or sets the premiere date.
/// </summary>
/// <value>The premiere date.</value>
public DateTime? PremiereDate { get; set; }
/// <summary>
/// Gets or sets the external urls.
/// </summary>
/// <value>The external urls.</value>
public ExternalUrl[] ExternalUrls { get; set; }
/// <summary>
/// Gets or sets the media versions.
/// </summary>
/// <value>The media versions.</value>
public MediaSourceInfo[] MediaSources { get; set; }
/// <summary>
/// Gets or sets the critic rating.
/// </summary>
/// <value>The critic rating.</value>
public float? CriticRating { get; set; }
public string[] ProductionLocations { get; set; }
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public string Path { get; set; }
public bool? EnableMediaSourceDisplay { get; set; }
/// <summary>
/// Gets or sets the official rating.
/// </summary>
/// <value>The official rating.</value>
public string OfficialRating { get; set; }
/// <summary>
/// Gets or sets the custom rating.
/// </summary>
/// <value>The custom rating.</value>
public string CustomRating { get; set; }
/// <summary>
/// Gets or sets the channel identifier.
/// </summary>
/// <value>The channel identifier.</value>
public Guid? ChannelId { get; set; }
public string ChannelName { get; set; }
/// <summary>
/// Gets or sets the overview.
/// </summary>
/// <value>The overview.</value>
public string Overview { get; set; }
/// <summary>
/// Gets or sets the taglines.
/// </summary>
/// <value>The taglines.</value>
public string[] Taglines { get; set; }
/// <summary>
/// Gets or sets the genres.
/// </summary>
/// <value>The genres.</value>
public string[] Genres { get; set; }
/// <summary>
/// Gets or sets the community rating.
/// </summary>
/// <value>The community rating.</value>
public float? CommunityRating { get; set; }
/// <summary>
/// Gets or sets the cumulative run time ticks.
/// </summary>
/// <value>The cumulative run time ticks.</value>
public long? CumulativeRunTimeTicks { get; set; }
/// <summary>
/// Gets or sets the run time ticks.
/// </summary>
/// <value>The run time ticks.</value>
public long? RunTimeTicks { get; set; }
/// <summary>
/// Gets or sets the play access.
/// </summary>
/// <value>The play access.</value>
public PlayAccess? PlayAccess { get; set; }
/// <summary>
/// Gets or sets the aspect ratio.
/// </summary>
/// <value>The aspect ratio.</value>
public string AspectRatio { get; set; }
/// <summary>
/// Gets or sets the production year.
/// </summary>
/// <value>The production year.</value>
public int? ProductionYear { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is place holder.
/// </summary>
/// <value><c>null</c> if [is place holder] contains no value, <c>true</c> if [is place holder]; otherwise, <c>false</c>.</value>
public bool? IsPlaceHolder { get; set; }
/// <summary>
/// Gets or sets the number.
/// </summary>
/// <value>The number.</value>
public string Number { get; set; }
public string ChannelNumber { get; set; }
/// <summary>
/// Gets or sets the index number.
/// </summary>
/// <value>The index number.</value>
public int? IndexNumber { get; set; }
/// <summary>
/// Gets or sets the index number end.
/// </summary>
/// <value>The index number end.</value>
public int? IndexNumberEnd { get; set; }
/// <summary>
/// Gets or sets the parent index number.
/// </summary>
/// <value>The parent index number.</value>
public int? ParentIndexNumber { get; set; }
/// <summary>
/// Gets or sets the trailer urls.
/// </summary>
/// <value>The trailer urls.</value>
public IReadOnlyCollection<MediaUrl> RemoteTrailers { get; set; }
/// <summary>
/// Gets or sets the provider ids.
/// </summary>
/// <value>The provider ids.</value>
public Dictionary<string, string> ProviderIds { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is HD.
/// </summary>
/// <value><c>null</c> if [is HD] contains no value, <c>true</c> if [is HD]; otherwise, <c>false</c>.</value>
public bool? IsHD { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is folder.
/// </summary>
/// <value><c>true</c> if this instance is folder; otherwise, <c>false</c>.</value>
public bool? IsFolder { get; set; }
/// <summary>
/// Gets or sets the parent id.
/// </summary>
/// <value>The parent id.</value>
public Guid? ParentId { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
public BaseItemKind Type { get; set; }
/// <summary>
/// Gets or sets the people.
/// </summary>
/// <value>The people.</value>
public BaseItemPerson[] People { get; set; }
/// <summary>
/// Gets or sets the studios.
/// </summary>
/// <value>The studios.</value>
public NameGuidPair[] Studios { get; set; }
public NameGuidPair[] GenreItems { get; set; }
/// <summary>
/// Gets or sets whether the item has a logo, this will hold the Id of the Parent that has one.
/// </summary>
/// <value>The parent logo item id.</value>
public Guid? ParentLogoItemId { get; set; }
/// <summary>
/// Gets or sets whether the item has any backdrops, this will hold the Id of the Parent that has one.
/// </summary>
/// <value>The parent backdrop item id.</value>
public Guid? ParentBackdropItemId { get; set; }
/// <summary>
/// Gets or sets the parent backdrop image tags.
/// </summary>
/// <value>The parent backdrop image tags.</value>
public string[] ParentBackdropImageTags { get; set; }
/// <summary>
/// Gets or sets the local trailer count.
/// </summary>
/// <value>The local trailer count.</value>
public int? LocalTrailerCount { get; set; }
/// <summary>
/// Gets or sets the user data for this item based on the user it's being requested for.
/// </summary>
/// <value>The user data.</value>
public UserItemDataDto UserData { get; set; }
/// <summary>
/// Gets or sets the recursive item count.
/// </summary>
/// <value>The recursive item count.</value>
public int? RecursiveItemCount { get; set; }
/// <summary>
/// Gets or sets the child count.
/// </summary>
/// <value>The child count.</value>
public int? ChildCount { get; set; }
/// <summary>
/// Gets or sets the name of the series.
/// </summary>
/// <value>The name of the series.</value>
public string SeriesName { get; set; }
/// <summary>
/// Gets or sets the series id.
/// </summary>
/// <value>The series id.</value>
public Guid? SeriesId { get; set; }
/// <summary>
/// Gets or sets the season identifier.
/// </summary>
/// <value>The season identifier.</value>
public Guid? SeasonId { get; set; }
/// <summary>
/// Gets or sets the special feature count.
/// </summary>
/// <value>The special feature count.</value>
public int? SpecialFeatureCount { get; set; }
/// <summary>
/// Gets or sets the display preferences id.
/// </summary>
/// <value>The display preferences id.</value>
public string DisplayPreferencesId { get; set; }
/// <summary>
/// Gets or sets the status.
/// </summary>
/// <value>The status.</value>
public string Status { get; set; }
/// <summary>
/// Gets or sets the air time.
/// </summary>
/// <value>The air time.</value>
public string AirTime { get; set; }
/// <summary>
/// Gets or sets the air days.
/// </summary>
/// <value>The air days.</value>
public DayOfWeek[] AirDays { get; set; }
/// <summary>
/// Gets or sets the tags.
/// </summary>
/// <value>The tags.</value>
public string[] Tags { get; set; }
/// <summary>
/// Gets or sets the primary image aspect ratio, after image enhancements.
/// </summary>
/// <value>The primary image aspect ratio.</value>
public double? PrimaryImageAspectRatio { get; set; }
/// <summary>
/// Gets or sets the artists.
/// </summary>
/// <value>The artists.</value>
public IReadOnlyList<string> Artists { get; set; }
/// <summary>
/// Gets or sets the artist items.
/// </summary>
/// <value>The artist items.</value>
public NameGuidPair[] ArtistItems { get; set; }
/// <summary>
/// Gets or sets the album.
/// </summary>
/// <value>The album.</value>
public string Album { get; set; }
/// <summary>
/// Gets or sets the type of the collection.
/// </summary>
/// <value>The type of the collection.</value>
public CollectionType? CollectionType { get; set; }
/// <summary>
/// Gets or sets the display order.
/// </summary>
/// <value>The display order.</value>
public string DisplayOrder { get; set; }
/// <summary>
/// Gets or sets the album id.
/// </summary>
/// <value>The album id.</value>
public Guid? AlbumId { get; set; }
/// <summary>
/// Gets or sets the album image tag.
/// </summary>
/// <value>The album image tag.</value>
public string AlbumPrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets the series primary image tag.
/// </summary>
/// <value>The series primary image tag.</value>
public string SeriesPrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets the album artist.
/// </summary>
/// <value>The album artist.</value>
public string AlbumArtist { get; set; }
/// <summary>
/// Gets or sets the album artists.
/// </summary>
/// <value>The album artists.</value>
public NameGuidPair[] AlbumArtists { get; set; }
/// <summary>
/// Gets or sets the name of the season.
/// </summary>
/// <value>The name of the season.</value>
public string SeasonName { get; set; }
/// <summary>
/// Gets or sets the media streams.
/// </summary>
/// <value>The media streams.</value>
public MediaStream[] MediaStreams { get; set; }
/// <summary>
/// Gets or sets the type of the video.
/// </summary>
/// <value>The type of the video.</value>
public VideoType? VideoType { get; set; }
/// <summary>
/// Gets or sets the part count.
/// </summary>
/// <value>The part count.</value>
public int? PartCount { get; set; }
public int? MediaSourceCount { get; set; }
/// <summary>
/// Gets or sets the image tags.
/// </summary>
/// <value>The image tags.</value>
public Dictionary<ImageType, string> ImageTags { get; set; }
/// <summary>
/// Gets or sets the backdrop image tags.
/// </summary>
/// <value>The backdrop image tags.</value>
public string[] BackdropImageTags { get; set; }
/// <summary>
/// Gets or sets the screenshot image tags.
/// </summary>
/// <value>The screenshot image tags.</value>
public string[] ScreenshotImageTags { get; set; }
/// <summary>
/// Gets or sets the parent logo image tag.
/// </summary>
/// <value>The parent logo image tag.</value>
public string ParentLogoImageTag { get; set; }
/// <summary>
/// Gets or sets whether the item has fan art, this will hold the Id of the Parent that has one.
/// </summary>
/// <value>The parent art item id.</value>
public Guid? ParentArtItemId { get; set; }
/// <summary>
/// Gets or sets the parent art image tag.
/// </summary>
/// <value>The parent art image tag.</value>
public string ParentArtImageTag { get; set; }
/// <summary>
/// Gets or sets the series thumb image tag.
/// </summary>
/// <value>The series thumb image tag.</value>
public string SeriesThumbImageTag { get; set; }
/// <summary>
/// Gets or sets the blurhashes for the image tags.
/// Maps image type to dictionary mapping image tag to blurhash value.
/// </summary>
/// <value>The blurhashes.</value>
public Dictionary<ImageType, Dictionary<string, string>> ImageBlurHashes { get; set; }
/// <summary>
/// Gets or sets the series studio.
/// </summary>
/// <value>The series studio.</value>
public string SeriesStudio { get; set; }
/// <summary>
/// Gets or sets the parent thumb item id.
/// </summary>
/// <value>The parent thumb item id.</value>
public Guid? ParentThumbItemId { get; set; }
/// <summary>
/// Gets or sets the parent thumb image tag.
/// </summary>
/// <value>The parent thumb image tag.</value>
public string ParentThumbImageTag { get; set; }
/// <summary>
/// Gets or sets the parent primary image item identifier.
/// </summary>
/// <value>The parent primary image item identifier.</value>
public Guid? ParentPrimaryImageItemId { get; set; }
/// <summary>
/// Gets or sets the parent primary image tag.
/// </summary>
/// <value>The parent primary image tag.</value>
public string ParentPrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets the chapters.
/// </summary>
/// <value>The chapters.</value>
public List<ChapterInfo> Chapters { get; set; }
/// <summary>
/// Gets or sets the trickplay manifest.
/// </summary>
/// <value>The trickplay manifest.</value>
public Dictionary<string, Dictionary<int, TrickplayInfoDto>> Trickplay { get; set; }
/// <summary>
/// Gets or sets the type of the location.
/// </summary>
/// <value>The type of the location.</value>
public LocationType? LocationType { get; set; }
/// <summary>
/// Gets or sets the type of the iso.
/// </summary>
/// <value>The type of the iso.</value>
public IsoType? IsoType { get; set; }
/// <summary>
/// Gets or sets the type of the media.
/// </summary>
/// <value>The type of the media.</value>
[DefaultValue(MediaType.Unknown)]
public MediaType MediaType { get; set; }
/// <summary>
/// Gets or sets the end date.
/// </summary>
/// <value>The end date.</value>
public DateTime? EndDate { get; set; }
/// <summary>
/// Gets or sets the locked fields.
/// </summary>
/// <value>The locked fields.</value>
public MetadataField[] LockedFields { get; set; }
/// <summary>
/// Gets or sets the trailer count.
/// </summary>
/// <value>The trailer count.</value>
public int? TrailerCount { get; set; }
/// <summary>
/// Gets or sets the movie count.
/// </summary>
/// <value>The movie count.</value>
public int? MovieCount { get; set; }
/// <summary>
/// Gets or sets the series count.
/// </summary>
/// <value>The series count.</value>
public int? SeriesCount { get; set; }
public int? ProgramCount { get; set; }
/// <summary>
/// Gets or sets the episode count.
/// </summary>
/// <value>The episode count.</value>
public int? EpisodeCount { get; set; }
/// <summary>
/// Gets or sets the song count.
/// </summary>
/// <value>The song count.</value>
public int? SongCount { get; set; }
/// <summary>
/// Gets or sets the album count.
/// </summary>
/// <value>The album count.</value>
public int? AlbumCount { get; set; }
public int? ArtistCount { get; set; }
/// <summary>
/// Gets or sets the music video count.
/// </summary>
/// <value>The music video count.</value>
public int? MusicVideoCount { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [enable internet providers].
/// </summary>
/// <value><c>true</c> if [enable internet providers]; otherwise, <c>false</c>.</value>
public bool? LockData { get; set; }
public int? Width { get; set; }
public int? Height { get; set; }
public string CameraMake { get; set; }
public string CameraModel { get; set; }
public string Software { get; set; }
public double? ExposureTime { get; set; }
public double? FocalLength { get; set; }
public ImageOrientation? ImageOrientation { get; set; }
public double? Aperture { get; set; }
public double? ShutterSpeed { get; set; }
public double? Latitude { get; set; }
public double? Longitude { get; set; }
public double? Altitude { get; set; }
public int? IsoSpeedRating { get; set; }
/// <summary>
/// Gets or sets the series timer identifier.
/// </summary>
/// <value>The series timer identifier.</value>
public string SeriesTimerId { get; set; }
/// <summary>
/// Gets or sets the program identifier.
/// </summary>
/// <value>The program identifier.</value>
public string ProgramId { get; set; }
/// <summary>
/// Gets or sets the channel primary image tag.
/// </summary>
/// <value>The channel primary image tag.</value>
public string ChannelPrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets the start date of the recording, in UTC.
/// </summary>
public DateTime? StartDate { get; set; }
/// <summary>
/// Gets or sets the completion percentage.
/// </summary>
/// <value>The completion percentage.</value>
public double? CompletionPercentage { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is repeat.
/// </summary>
/// <value><c>true</c> if this instance is repeat; otherwise, <c>false</c>.</value>
public bool? IsRepeat { get; set; }
/// <summary>
/// Gets or sets the episode title.
/// </summary>
/// <value>The episode title.</value>
public string EpisodeTitle { get; set; }
/// <summary>
/// Gets or sets the type of the channel.
/// </summary>
/// <value>The type of the channel.</value>
public ChannelType? ChannelType { get; set; }
/// <summary>
/// Gets or sets the audio.
/// </summary>
/// <value>The audio.</value>
public ProgramAudio? Audio { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is movie.
/// </summary>
/// <value><c>true</c> if this instance is movie; otherwise, <c>false</c>.</value>
public bool? IsMovie { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is sports.
/// </summary>
/// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value>
public bool? IsSports { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is series.
/// </summary>
/// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value>
public bool? IsSeries { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is live.
/// </summary>
/// <value><c>true</c> if this instance is live; otherwise, <c>false</c>.</value>
public bool? IsLive { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is news.
/// </summary>
/// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value>
public bool? IsNews { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is kids.
/// </summary>
/// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value>
public bool? IsKids { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is premiere.
/// </summary>
/// <value><c>true</c> if this instance is premiere; otherwise, <c>false</c>.</value>
public bool? IsPremiere { get; set; }
/// <summary>
/// Gets or sets the timer identifier.
/// </summary>
/// <value>The timer identifier.</value>
public string TimerId { get; set; }
/// <summary>
/// Gets or sets the gain required for audio normalization.
/// </summary>
/// <value>The gain required for audio normalization.</value>
public float? NormalizationGain { get; set; }
/// <summary>
/// Gets or sets the current program.
/// </summary>
/// <value>The current program.</value>
public BaseItemDto CurrentProgram { get; set; }
}
}
+60
View File
@@ -0,0 +1,60 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.Json.Serialization;
using Jellyfin.Data.Enums;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Dto
{
/// <summary>
/// This is used by the api to get information about a Person within a BaseItem.
/// </summary>
public class BaseItemPerson
{
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
public Guid Id { get; set; }
/// <summary>
/// Gets or sets the role.
/// </summary>
/// <value>The role.</value>
public string Role { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
[DefaultValue(PersonKind.Unknown)]
public PersonKind Type { get; set; }
/// <summary>
/// Gets or sets the primary image tag.
/// </summary>
/// <value>The primary image tag.</value>
public string PrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets the primary image blurhash.
/// </summary>
/// <value>The primary image blurhash.</value>
public Dictionary<ImageType, Dictionary<string, string>> ImageBlurHashes { get; set; }
/// <summary>
/// Gets a value indicating whether this instance has primary image.
/// </summary>
/// <value><c>true</c> if this instance has primary image; otherwise, <c>false</c>.</value>
[JsonIgnore]
public bool HasPrimaryImage => PrimaryImageTag is not null;
}
}
@@ -0,0 +1,69 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions.Json.Converters;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Session;
namespace MediaBrowser.Model.Dto;
/// <summary>
/// Client capabilities dto.
/// </summary>
public class ClientCapabilitiesDto
{
/// <summary>
/// Gets or sets the list of playable media types.
/// </summary>
[JsonConverter(typeof(JsonCommaDelimitedCollectionConverterFactory))]
public IReadOnlyList<MediaType> PlayableMediaTypes { get; set; } = [];
/// <summary>
/// Gets or sets the list of supported commands.
/// </summary>
[JsonConverter(typeof(JsonCommaDelimitedCollectionConverterFactory))]
public IReadOnlyList<GeneralCommandType> SupportedCommands { get; set; } = [];
/// <summary>
/// Gets or sets a value indicating whether session supports media control.
/// </summary>
public bool SupportsMediaControl { get; set; }
/// <summary>
/// Gets or sets a value indicating whether session supports a persistent identifier.
/// </summary>
public bool SupportsPersistentIdentifier { get; set; }
/// <summary>
/// Gets or sets the device profile.
/// </summary>
public DeviceProfile? DeviceProfile { get; set; }
/// <summary>
/// Gets or sets the app store url.
/// </summary>
public string? AppStoreUrl { get; set; }
/// <summary>
/// Gets or sets the icon url.
/// </summary>
public string? IconUrl { get; set; }
/// <summary>
/// Convert the dto to the full <see cref="ClientCapabilities"/> model.
/// </summary>
/// <returns>The converted <see cref="ClientCapabilities"/> model.</returns>
public ClientCapabilities ToClientCapabilities()
{
return new ClientCapabilities
{
PlayableMediaTypes = PlayableMediaTypes,
SupportedCommands = SupportedCommands,
SupportsMediaControl = SupportsMediaControl,
SupportsPersistentIdentifier = SupportsPersistentIdentifier,
DeviceProfile = DeviceProfile,
AppStoreUrl = AppStoreUrl,
IconUrl = IconUrl
};
}
}
+83
View File
@@ -0,0 +1,83 @@
using System;
namespace MediaBrowser.Model.Dto;
/// <summary>
/// A DTO representing device information.
/// </summary>
public class DeviceInfoDto
{
/// <summary>
/// Initializes a new instance of the <see cref="DeviceInfoDto"/> class.
/// </summary>
public DeviceInfoDto()
{
Capabilities = new ClientCapabilitiesDto();
}
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string? Name { get; set; }
/// <summary>
/// Gets or sets the custom name.
/// </summary>
/// <value>The custom name.</value>
public string? CustomName { get; set; }
/// <summary>
/// Gets or sets the access token.
/// </summary>
/// <value>The access token.</value>
public string? AccessToken { get; set; }
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
public string? Id { get; set; }
/// <summary>
/// Gets or sets the last name of the user.
/// </summary>
/// <value>The last name of the user.</value>
public string? LastUserName { get; set; }
/// <summary>
/// Gets or sets the name of the application.
/// </summary>
/// <value>The name of the application.</value>
public string? AppName { get; set; }
/// <summary>
/// Gets or sets the application version.
/// </summary>
/// <value>The application version.</value>
public string? AppVersion { get; set; }
/// <summary>
/// Gets or sets the last user identifier.
/// </summary>
/// <value>The last user identifier.</value>
public Guid? LastUserId { get; set; }
/// <summary>
/// Gets or sets the date last modified.
/// </summary>
/// <value>The date last modified.</value>
public DateTime? DateLastActivity { get; set; }
/// <summary>
/// Gets or sets the capabilities.
/// </summary>
/// <value>The capabilities.</value>
public ClientCapabilitiesDto Capabilities { get; set; }
/// <summary>
/// Gets or sets the icon URL.
/// </summary>
/// <value>The icon URL.</value>
public string? IconUrl { get; set; }
}
@@ -0,0 +1,106 @@
using System.Collections.Generic;
using Jellyfin.Database.Implementations.Enums;
namespace MediaBrowser.Model.Dto
{
/// <summary>
/// Defines the display preferences for any item that supports them (usually Folders).
/// </summary>
public class DisplayPreferencesDto
{
/// <summary>
/// Initializes a new instance of the <see cref="DisplayPreferencesDto" /> class.
/// </summary>
public DisplayPreferencesDto()
{
RememberIndexing = false;
PrimaryImageHeight = 250;
PrimaryImageWidth = 250;
ShowBackdrop = true;
CustomPrefs = new Dictionary<string, string?>();
}
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
public string? Id { get; set; }
/// <summary>
/// Gets or sets the type of the view.
/// </summary>
/// <value>The type of the view.</value>
public string? ViewType { get; set; }
/// <summary>
/// Gets or sets the sort by.
/// </summary>
/// <value>The sort by.</value>
public string? SortBy { get; set; }
/// <summary>
/// Gets or sets the index by.
/// </summary>
/// <value>The index by.</value>
public string? IndexBy { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [remember indexing].
/// </summary>
/// <value><c>true</c> if [remember indexing]; otherwise, <c>false</c>.</value>
public bool RememberIndexing { get; set; }
/// <summary>
/// Gets or sets the height of the primary image.
/// </summary>
/// <value>The height of the primary image.</value>
public int PrimaryImageHeight { get; set; }
/// <summary>
/// Gets or sets the width of the primary image.
/// </summary>
/// <value>The width of the primary image.</value>
public int PrimaryImageWidth { get; set; }
/// <summary>
/// Gets or sets the custom prefs.
/// </summary>
/// <value>The custom prefs.</value>
public Dictionary<string, string?> CustomPrefs { get; set; }
/// <summary>
/// Gets or sets the scroll direction.
/// </summary>
/// <value>The scroll direction.</value>
public ScrollDirection ScrollDirection { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to show backdrops on this item.
/// </summary>
/// <value><c>true</c> if showing backdrops; otherwise, <c>false</c>.</value>
public bool ShowBackdrop { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [remember sorting].
/// </summary>
/// <value><c>true</c> if [remember sorting]; otherwise, <c>false</c>.</value>
public bool RememberSorting { get; set; }
/// <summary>
/// Gets or sets the sort order.
/// </summary>
/// <value>The sort order.</value>
public SortOrder SortOrder { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [show sidebar].
/// </summary>
/// <value><c>true</c> if [show sidebar]; otherwise, <c>false</c>.</value>
public bool ShowSidebar { get; set; }
/// <summary>
/// Gets or sets the client.
/// </summary>
public string? Client { get; set; }
}
}
+10
View File
@@ -0,0 +1,10 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dto
{
public interface IHasServerId
{
string ServerId { get; }
}
}
+14
View File
@@ -0,0 +1,14 @@
namespace MediaBrowser.Model.Dto
{
/// <summary>
/// Interface IItemDto.
/// </summary>
public interface IItemDto
{
/// <summary>
/// Gets or sets the primary image aspect ratio.
/// </summary>
/// <value>The primary image aspect ratio.</value>
double? PrimaryImageAspectRatio { get; set; }
}
}
+58
View File
@@ -0,0 +1,58 @@
#nullable disable
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Dto
{
/// <summary>
/// Class ImageInfo.
/// </summary>
public class ImageInfo
{
/// <summary>
/// Gets or sets the type of the image.
/// </summary>
/// <value>The type of the image.</value>
public ImageType ImageType { get; set; }
/// <summary>
/// Gets or sets the index of the image.
/// </summary>
/// <value>The index of the image.</value>
public int? ImageIndex { get; set; }
/// <summary>
/// Gets or sets the image tag.
/// </summary>
public string ImageTag { get; set; }
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public string Path { get; set; }
/// <summary>
/// Gets or sets the blurhash.
/// </summary>
/// <value>The blurhash.</value>
public string BlurHash { get; set; }
/// <summary>
/// Gets or sets the height.
/// </summary>
/// <value>The height.</value>
public int? Height { get; set; }
/// <summary>
/// Gets or sets the width.
/// </summary>
/// <value>The width.</value>
public int? Width { get; set; }
/// <summary>
/// Gets or sets the size.
/// </summary>
/// <value>The size.</value>
public long Size { get; set; }
}
}
+89
View File
@@ -0,0 +1,89 @@
namespace MediaBrowser.Model.Dto
{
/// <summary>
/// Class LibrarySummary.
/// </summary>
public class ItemCounts
{
/// <summary>
/// Gets or sets the movie count.
/// </summary>
/// <value>The movie count.</value>
public int MovieCount { get; set; }
/// <summary>
/// Gets or sets the series count.
/// </summary>
/// <value>The series count.</value>
public int SeriesCount { get; set; }
/// <summary>
/// Gets or sets the episode count.
/// </summary>
/// <value>The episode count.</value>
public int EpisodeCount { get; set; }
/// <summary>
/// Gets or sets the artist count.
/// </summary>
/// <value>The artist count.</value>
public int ArtistCount { get; set; }
/// <summary>
/// Gets or sets the program count.
/// </summary>
/// <value>The program count.</value>
public int ProgramCount { get; set; }
/// <summary>
/// Gets or sets the trailer count.
/// </summary>
/// <value>The trailer count.</value>
public int TrailerCount { get; set; }
/// <summary>
/// Gets or sets the song count.
/// </summary>
/// <value>The song count.</value>
public int SongCount { get; set; }
/// <summary>
/// Gets or sets the album count.
/// </summary>
/// <value>The album count.</value>
public int AlbumCount { get; set; }
/// <summary>
/// Gets or sets the music video count.
/// </summary>
/// <value>The music video count.</value>
public int MusicVideoCount { get; set; }
/// <summary>
/// Gets or sets the box set count.
/// </summary>
/// <value>The box set count.</value>
public int BoxSetCount { get; set; }
/// <summary>
/// Gets or sets the book count.
/// </summary>
/// <value>The book count.</value>
public int BookCount { get; set; }
/// <summary>
/// Gets or sets the item count.
/// </summary>
/// <value>The item count.</value>
public int ItemCount { get; set; }
/// <summary>
/// Adds all counts.
/// </summary>
/// <returns>The total of the counts.</returns>
public int TotalItemCount()
{
return MovieCount + SeriesCount + EpisodeCount + ArtistCount + ProgramCount + TrailerCount + SongCount + AlbumCount + MusicVideoCount + BoxSetCount + BookCount;
}
}
}
+263
View File
@@ -0,0 +1,263 @@
#nullable disable
#pragma warning disable CS1591
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.Json.Serialization;
using Jellyfin.Data.Enums;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Session;
namespace MediaBrowser.Model.Dto
{
public class MediaSourceInfo
{
public MediaSourceInfo()
{
Formats = [];
MediaStreams = [];
MediaAttachments = [];
RequiredHttpHeaders = [];
SupportsTranscoding = true;
SupportsDirectStream = true;
SupportsDirectPlay = true;
SupportsProbing = true;
UseMostCompatibleTranscodingProfile = false;
DefaultAudioIndexSource = AudioIndexSource.None;
}
public MediaProtocol Protocol { get; set; }
public string Id { get; set; }
public string Path { get; set; }
public string EncoderPath { get; set; }
public MediaProtocol? EncoderProtocol { get; set; }
public MediaSourceType Type { get; set; }
public string Container { get; set; }
public long? Size { get; set; }
public string Name { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the media is remote.
/// Differentiate internet url vs local network.
/// </summary>
public bool IsRemote { get; set; }
public string ETag { get; set; }
public long? RunTimeTicks { get; set; }
public bool ReadAtNativeFramerate { get; set; }
public bool IgnoreDts { get; set; }
public bool IgnoreIndex { get; set; }
public bool GenPtsInput { get; set; }
public bool SupportsTranscoding { get; set; }
public bool SupportsDirectStream { get; set; }
public bool SupportsDirectPlay { get; set; }
public bool IsInfiniteStream { get; set; }
[DefaultValue(false)]
public bool UseMostCompatibleTranscodingProfile { get; set; }
public bool RequiresOpening { get; set; }
public string OpenToken { get; set; }
public bool RequiresClosing { get; set; }
public string LiveStreamId { get; set; }
public int? BufferMs { get; set; }
public bool RequiresLooping { get; set; }
public bool SupportsProbing { get; set; }
public VideoType? VideoType { get; set; }
public IsoType? IsoType { get; set; }
public Video3DFormat? Video3DFormat { get; set; }
public IReadOnlyList<MediaStream> MediaStreams { get; set; }
public IReadOnlyList<MediaAttachment> MediaAttachments { get; set; }
public string[] Formats { get; set; }
public int? Bitrate { get; set; }
public int? FallbackMaxStreamingBitrate { get; set; }
public TransportStreamTimestamp? Timestamp { get; set; }
public Dictionary<string, string> RequiredHttpHeaders { get; set; }
public string TranscodingUrl { get; set; }
public MediaStreamProtocol TranscodingSubProtocol { get; set; }
public string TranscodingContainer { get; set; }
public int? AnalyzeDurationMs { get; set; }
[JsonIgnore]
public TranscodeReason TranscodeReasons { get; set; }
[JsonIgnore]
public AudioIndexSource DefaultAudioIndexSource { get; set; }
public int? DefaultAudioStreamIndex { get; set; }
public int? DefaultSubtitleStreamIndex { get; set; }
public bool HasSegments { get; set; }
[JsonIgnore]
public MediaStream VideoStream
{
get
{
foreach (var i in MediaStreams)
{
if (i.Type == MediaStreamType.Video)
{
return i;
}
}
return null;
}
}
public void InferTotalBitrate(bool force = false)
{
if (MediaStreams is null)
{
return;
}
if (!force && Bitrate.HasValue)
{
return;
}
var bitrate = 0;
foreach (var stream in MediaStreams)
{
if (!stream.IsExternal)
{
bitrate += stream.BitRate ?? 0;
}
}
if (bitrate > 0)
{
Bitrate = bitrate;
}
}
public MediaStream GetDefaultAudioStream(int? defaultIndex)
{
if (defaultIndex.HasValue && defaultIndex != -1)
{
var val = defaultIndex.Value;
foreach (var i in MediaStreams)
{
if (i.Type == MediaStreamType.Audio && i.Index == val)
{
return i;
}
}
}
foreach (var i in MediaStreams)
{
if (i.Type == MediaStreamType.Audio && i.IsDefault)
{
return i;
}
}
foreach (var i in MediaStreams)
{
if (i.Type == MediaStreamType.Audio)
{
return i;
}
}
return null;
}
public MediaStream GetMediaStream(MediaStreamType type, int index)
{
foreach (var i in MediaStreams)
{
if (i.Type == type && i.Index == index)
{
return i;
}
}
return null;
}
public int? GetStreamCount(MediaStreamType type)
{
int numMatches = 0;
int numStreams = 0;
foreach (var i in MediaStreams)
{
numStreams++;
if (i.Type == type)
{
numMatches++;
}
}
if (numStreams == 0)
{
return null;
}
return numMatches;
}
public bool? IsSecondaryAudio(MediaStream stream)
{
if (stream.IsExternal)
{
return false;
}
// Look for the first audio track
foreach (var currentStream in MediaStreams)
{
if (currentStream.Type == MediaStreamType.Audio && !currentStream.IsExternal)
{
return currentStream.Index != stream.Index;
}
}
return null;
}
}
}
+11
View File
@@ -0,0 +1,11 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dto
{
public enum MediaSourceType
{
Default = 0,
Grouping = 1,
Placeholder = 2
}
}
@@ -0,0 +1,55 @@
using System.Collections.Generic;
using Jellyfin.Data.Enums;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Providers;
namespace MediaBrowser.Model.Dto;
/// <summary>
/// A class representing metadata editor information.
/// </summary>
public class MetadataEditorInfo
{
/// <summary>
/// Initializes a new instance of the <see cref="MetadataEditorInfo"/> class.
/// </summary>
public MetadataEditorInfo()
{
ParentalRatingOptions = [];
Countries = [];
Cultures = [];
ExternalIdInfos = [];
ContentTypeOptions = [];
}
/// <summary>
/// Gets or sets the parental rating options.
/// </summary>
public IReadOnlyList<ParentalRating> ParentalRatingOptions { get; set; }
/// <summary>
/// Gets or sets the countries.
/// </summary>
public IReadOnlyList<CountryInfo> Countries { get; set; }
/// <summary>
/// Gets or sets the cultures.
/// </summary>
public IReadOnlyList<CultureDto> Cultures { get; set; }
/// <summary>
/// Gets or sets the external id infos.
/// </summary>
public IReadOnlyList<ExternalIdInfo> ExternalIdInfos { get; set; }
/// <summary>
/// Gets or sets the content type.
/// </summary>
public CollectionType? ContentType { get; set; }
/// <summary>
/// Gets or sets the content type options.
/// </summary>
public IReadOnlyList<NameValuePair> ContentTypeOptions { get; set; }
}
+14
View File
@@ -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; }
}
}
+20
View File
@@ -0,0 +1,20 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dto
{
public class NameIdPair
{
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
public string Id { get; set; }
}
}
+30
View File
@@ -0,0 +1,30 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dto
{
public class NameValuePair
{
public NameValuePair()
{
}
public NameValuePair(string name, string value)
{
Name = name;
Value = value;
}
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the value.
/// </summary>
/// <value>The value.</value>
public string Value { get; set; }
}
}
+26
View File
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Dto;
/// <summary>
/// DTO for playlists.
/// </summary>
public class PlaylistDto
{
/// <summary>
/// Gets or sets a value indicating whether the playlist is publicly readable.
/// </summary>
public bool OpenAccess { get; set; }
/// <summary>
/// Gets or sets the share permissions.
/// </summary>
public required IReadOnlyList<PlaylistUserPermissions> Shares { get; set; }
/// <summary>
/// Gets or sets the item ids.
/// </summary>
public required IReadOnlyList<Guid> ItemIds { get; set; }
}
+10
View File
@@ -0,0 +1,10 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dto
{
public enum RatingType
{
Score,
Likes
}
}
@@ -0,0 +1,19 @@
#nullable disable
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
namespace MediaBrowser.Model.Dto
{
public class RecommendationDto
{
public IReadOnlyCollection<BaseItemDto> Items { get; set; }
public RecommendationType RecommendationType { get; set; }
public string BaselineItemName { get; set; }
public Guid CategoryId { get; set; }
}
}
@@ -0,0 +1,19 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Dto
{
public enum RecommendationType
{
SimilarToRecentlyPlayed = 0,
SimilarToLikedItem = 1,
HasDirectorFromRecentlyPlayed = 2,
HasActorFromRecentlyPlayed = 3,
HasLikedDirector = 4,
HasLikedActor = 5
}
}
+186
View File
@@ -0,0 +1,186 @@
using System;
using System.Collections.Generic;
using Jellyfin.Data.Enums;
using MediaBrowser.Model.Session;
namespace MediaBrowser.Model.Dto;
/// <summary>
/// Session info DTO.
/// </summary>
public class SessionInfoDto
{
/// <summary>
/// Gets or sets the play state.
/// </summary>
/// <value>The play state.</value>
public PlayerStateInfo? PlayState { get; set; }
/// <summary>
/// Gets or sets the additional users.
/// </summary>
/// <value>The additional users.</value>
public IReadOnlyList<SessionUserInfo>? AdditionalUsers { get; set; }
/// <summary>
/// Gets or sets the client capabilities.
/// </summary>
/// <value>The client capabilities.</value>
public ClientCapabilitiesDto? Capabilities { get; set; }
/// <summary>
/// Gets or sets the remote end point.
/// </summary>
/// <value>The remote end point.</value>
public string? RemoteEndPoint { get; set; }
/// <summary>
/// Gets or sets the playable media types.
/// </summary>
/// <value>The playable media types.</value>
public IReadOnlyList<MediaType> PlayableMediaTypes { get; set; } = [];
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
public string? Id { get; set; }
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the username.
/// </summary>
/// <value>The username.</value>
public string? UserName { get; set; }
/// <summary>
/// Gets or sets the type of the client.
/// </summary>
/// <value>The type of the client.</value>
public string? Client { get; set; }
/// <summary>
/// Gets or sets the last activity date.
/// </summary>
/// <value>The last activity date.</value>
public DateTime LastActivityDate { get; set; }
/// <summary>
/// Gets or sets the last playback check in.
/// </summary>
/// <value>The last playback check in.</value>
public DateTime LastPlaybackCheckIn { get; set; }
/// <summary>
/// Gets or sets the last paused date.
/// </summary>
/// <value>The last paused date.</value>
public DateTime? LastPausedDate { get; set; }
/// <summary>
/// Gets or sets the name of the device.
/// </summary>
/// <value>The name of the device.</value>
public string? DeviceName { get; set; }
/// <summary>
/// Gets or sets the type of the device.
/// </summary>
/// <value>The type of the device.</value>
public string? DeviceType { get; set; }
/// <summary>
/// Gets or sets the now playing item.
/// </summary>
/// <value>The now playing item.</value>
public BaseItemDto? NowPlayingItem { get; set; }
/// <summary>
/// Gets or sets the now viewing item.
/// </summary>
/// <value>The now viewing item.</value>
public BaseItemDto? NowViewingItem { get; set; }
/// <summary>
/// Gets or sets the device id.
/// </summary>
/// <value>The device id.</value>
public string? DeviceId { get; set; }
/// <summary>
/// Gets or sets the application version.
/// </summary>
/// <value>The application version.</value>
public string? ApplicationVersion { get; set; }
/// <summary>
/// Gets or sets the transcoding info.
/// </summary>
/// <value>The transcoding info.</value>
public TranscodingInfo? TranscodingInfo { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this session is active.
/// </summary>
/// <value><c>true</c> if this session is active; otherwise, <c>false</c>.</value>
public bool IsActive { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the session supports media control.
/// </summary>
/// <value><c>true</c> if this session supports media control; otherwise, <c>false</c>.</value>
public bool SupportsMediaControl { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the session supports remote control.
/// </summary>
/// <value><c>true</c> if this session supports remote control; otherwise, <c>false</c>.</value>
public bool SupportsRemoteControl { get; set; }
/// <summary>
/// Gets or sets the now playing queue.
/// </summary>
/// <value>The now playing queue.</value>
public IReadOnlyList<QueueItem>? NowPlayingQueue { get; set; }
/// <summary>
/// Gets or sets the now playing queue full items.
/// </summary>
/// <value>The now playing queue full items.</value>
public IReadOnlyList<BaseItemDto>? NowPlayingQueueFullItems { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the session has a custom device name.
/// </summary>
/// <value><c>true</c> if this session has a custom device name; otherwise, <c>false</c>.</value>
public bool HasCustomDeviceName { get; set; }
/// <summary>
/// Gets or sets the playlist item id.
/// </summary>
/// <value>The playlist item id.</value>
public string? PlaylistItemId { get; set; }
/// <summary>
/// Gets or sets the server id.
/// </summary>
/// <value>The server id.</value>
public string? ServerId { get; set; }
/// <summary>
/// Gets or sets the user primary image tag.
/// </summary>
/// <value>The user primary image tag.</value>
public string? UserPrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets the supported commands.
/// </summary>
/// <value>The supported commands.</value>
public IReadOnlyList<GeneralCommandType> SupportedCommands { get; set; } = [];
}
@@ -0,0 +1,62 @@
using System;
using Jellyfin.Database.Implementations.Entities;
namespace MediaBrowser.Model.Dto;
/// <summary>
/// The trickplay api model.
/// </summary>
public record TrickplayInfoDto
{
/// <summary>
/// Initializes a new instance of the <see cref="TrickplayInfoDto"/> class.
/// </summary>
/// <param name="info">The trickplay info.</param>
public TrickplayInfoDto(TrickplayInfo info)
{
ArgumentNullException.ThrowIfNull(info);
Width = info.Width;
Height = info.Height;
TileWidth = info.TileWidth;
TileHeight = info.TileHeight;
ThumbnailCount = info.ThumbnailCount;
Interval = info.Interval;
Bandwidth = info.Bandwidth;
}
/// <summary>
/// Gets the width of an individual thumbnail.
/// </summary>
public int Width { get; init; }
/// <summary>
/// Gets the height of an individual thumbnail.
/// </summary>
public int Height { get; init; }
/// <summary>
/// Gets the amount of thumbnails per row.
/// </summary>
public int TileWidth { get; init; }
/// <summary>
/// Gets the amount of thumbnails per column.
/// </summary>
public int TileHeight { get; init; }
/// <summary>
/// Gets the total amount of non-black thumbnails.
/// </summary>
public int ThumbnailCount { get; init; }
/// <summary>
/// Gets the interval in milliseconds between each trickplay thumbnail.
/// </summary>
public int Interval { get; init; }
/// <summary>
/// Gets the peak bandwidth usage in bits per second.
/// </summary>
public int Bandwidth { get; init; }
}
@@ -0,0 +1,76 @@
using System;
namespace MediaBrowser.Model.Dto
{
/// <summary>
/// This is used by the api to get information about a item user data.
/// </summary>
public class UpdateUserItemDataDto
{
/// <summary>
/// Gets or sets the rating.
/// </summary>
/// <value>The rating.</value>
public double? Rating { get; set; }
/// <summary>
/// Gets or sets the played percentage.
/// </summary>
/// <value>The played percentage.</value>
public double? PlayedPercentage { get; set; }
/// <summary>
/// Gets or sets the unplayed item count.
/// </summary>
/// <value>The unplayed item count.</value>
public int? UnplayedItemCount { get; set; }
/// <summary>
/// Gets or sets the playback position ticks.
/// </summary>
/// <value>The playback position ticks.</value>
public long? PlaybackPositionTicks { get; set; }
/// <summary>
/// Gets or sets the play count.
/// </summary>
/// <value>The play count.</value>
public int? PlayCount { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is favorite.
/// </summary>
/// <value><c>true</c> if this instance is favorite; otherwise, <c>false</c>.</value>
public bool? IsFavorite { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="UpdateUserItemDataDto" /> is likes.
/// </summary>
/// <value><c>null</c> if [likes] contains no value, <c>true</c> if [likes]; otherwise, <c>false</c>.</value>
public bool? Likes { get; set; }
/// <summary>
/// Gets or sets the last played date.
/// </summary>
/// <value>The last played date.</value>
public DateTime? LastPlayedDate { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="UserItemDataDto" /> is played.
/// </summary>
/// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
public bool? Played { get; set; }
/// <summary>
/// Gets or sets the key.
/// </summary>
/// <value>The key.</value>
public string? Key { get; set; }
/// <summary>
/// Gets or sets the item identifier.
/// </summary>
/// <value>The item identifier.</value>
public string? ItemId { get; set; }
}
}
+116
View File
@@ -0,0 +1,116 @@
#nullable disable
using System;
using System.ComponentModel;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Users;
namespace MediaBrowser.Model.Dto
{
/// <summary>
/// Class UserDto.
/// </summary>
public class UserDto : IItemDto, IHasServerId
{
/// <summary>
/// Initializes a new instance of the <see cref="UserDto"/> class.
/// </summary>
public UserDto()
{
Configuration = new UserConfiguration();
Policy = new UserPolicy();
}
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the server identifier.
/// </summary>
/// <value>The server identifier.</value>
public string ServerId { get; set; }
/// <summary>
/// Gets or sets the name of the server.
/// This is not used by the server and is for client-side usage only.
/// </summary>
/// <value>The name of the server.</value>
public string ServerName { get; set; }
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
public Guid Id { get; set; }
/// <summary>
/// Gets or sets the primary image tag.
/// </summary>
/// <value>The primary image tag.</value>
public string PrimaryImageTag { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance has password.
/// </summary>
/// <value><c>true</c> if this instance has password; otherwise, <c>false</c>.</value>
[Obsolete("This information is no longer provided")]
public bool? HasPassword { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether this instance has configured password.
/// </summary>
/// <value><c>true</c> if this instance has configured password; otherwise, <c>false</c>.</value>
[Obsolete("This is always true")]
public bool? HasConfiguredPassword { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether this instance has configured easy password.
/// </summary>
/// <value><c>true</c> if this instance has configured easy password; otherwise, <c>false</c>.</value>
[Obsolete("Easy Password has been replaced with Quick Connect")]
public bool? HasConfiguredEasyPassword { get; set; } = false;
/// <summary>
/// Gets or sets whether async login is enabled or not.
/// </summary>
public bool? EnableAutoLogin { get; set; }
/// <summary>
/// Gets or sets the last login date.
/// </summary>
/// <value>The last login date.</value>
public DateTime? LastLoginDate { get; set; }
/// <summary>
/// Gets or sets the last activity date.
/// </summary>
/// <value>The last activity date.</value>
public DateTime? LastActivityDate { get; set; }
/// <summary>
/// Gets or sets the configuration.
/// </summary>
/// <value>The configuration.</value>
public UserConfiguration Configuration { get; set; }
/// <summary>
/// Gets or sets the policy.
/// </summary>
/// <value>The policy.</value>
public UserPolicy Policy { get; set; }
/// <summary>
/// Gets or sets the primary image aspect ratio.
/// </summary>
/// <value>The primary image aspect ratio.</value>
public double? PrimaryImageAspectRatio { get; set; }
/// <inheritdoc />
public override string ToString()
{
return Name ?? base.ToString();
}
}
}
+76
View File
@@ -0,0 +1,76 @@
using System;
namespace MediaBrowser.Model.Dto
{
/// <summary>
/// Class UserItemDataDto.
/// </summary>
public class UserItemDataDto
{
/// <summary>
/// Gets or sets the rating.
/// </summary>
/// <value>The rating.</value>
public double? Rating { get; set; }
/// <summary>
/// Gets or sets the played percentage.
/// </summary>
/// <value>The played percentage.</value>
public double? PlayedPercentage { get; set; }
/// <summary>
/// Gets or sets the unplayed item count.
/// </summary>
/// <value>The unplayed item count.</value>
public int? UnplayedItemCount { get; set; }
/// <summary>
/// Gets or sets the playback position ticks.
/// </summary>
/// <value>The playback position ticks.</value>
public long PlaybackPositionTicks { get; set; }
/// <summary>
/// Gets or sets the play count.
/// </summary>
/// <value>The play count.</value>
public int PlayCount { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is favorite.
/// </summary>
/// <value><c>true</c> if this instance is favorite; otherwise, <c>false</c>.</value>
public bool IsFavorite { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="UserItemDataDto" /> is likes.
/// </summary>
/// <value><c>null</c> if [likes] contains no value, <c>true</c> if [likes]; otherwise, <c>false</c>.</value>
public bool? Likes { get; set; }
/// <summary>
/// Gets or sets the last played date.
/// </summary>
/// <value>The last played date.</value>
public DateTime? LastPlayedDate { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="UserItemDataDto" /> is played.
/// </summary>
/// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
public bool Played { get; set; }
/// <summary>
/// Gets or sets the key.
/// </summary>
/// <value>The key.</value>
public required string Key { get; set; }
/// <summary>
/// Gets or sets the item identifier.
/// </summary>
/// <value>The item identifier.</value>
public Guid ItemId { get; set; }
}
}
@@ -0,0 +1,34 @@
#pragma warning disable CS1591
using System;
namespace MediaBrowser.Model.Entities
{
/// <summary>
/// Class ChapterInfo.
/// </summary>
public class ChapterInfo
{
/// <summary>
/// Gets or sets the start position ticks.
/// </summary>
/// <value>The start position ticks.</value>
public long StartPositionTicks { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string? Name { get; set; }
/// <summary>
/// Gets or sets the image path.
/// </summary>
/// <value>The image path.</value>
public string? ImagePath { get; set; }
public DateTime ImageDateModified { get; set; }
public string? ImageTag { get; set; }
}
}
@@ -0,0 +1,49 @@
#pragma warning disable SA1300 // Lowercase required for backwards compat.
namespace MediaBrowser.Model.Entities;
/// <summary>
/// The collection type options.
/// </summary>
public enum CollectionTypeOptions
{
/// <summary>
/// Movies.
/// </summary>
movies = 0,
/// <summary>
/// TV Shows.
/// </summary>
tvshows = 1,
/// <summary>
/// Music.
/// </summary>
music = 2,
/// <summary>
/// Music Videos.
/// </summary>
musicvideos = 3,
/// <summary>
/// Home Videos (and Photos).
/// </summary>
homevideos = 4,
/// <summary>
/// Box Sets.
/// </summary>
boxsets = 5,
/// <summary>
/// Books.
/// </summary>
books = 6,
/// <summary>
/// Mixed Movies and TV Shows.
/// </summary>
mixed = 7
}
@@ -0,0 +1,19 @@
#pragma warning disable SA1300 // Lowercase required for backwards compat.
namespace MediaBrowser.Model.Entities;
/// <summary>
/// Enum containing deinterlace methods.
/// </summary>
public enum DeinterlaceMethod
{
/// <summary>
/// YADIF.
/// </summary>
yadif = 0,
/// <summary>
/// BWDIF.
/// </summary>
bwdif = 1
}
@@ -0,0 +1,35 @@
namespace MediaBrowser.Model.Entities;
/// <summary>
/// An enum representing an algorithm to downmix surround sound to stereo.
/// </summary>
public enum DownMixStereoAlgorithms
{
/// <summary>
/// No special algorithm.
/// </summary>
None = 0,
/// <summary>
/// Algorithm by Dave_750.
/// Sourced from https://superuser.com/questions/852400/properly-downmix-5-1-to-stereo-using-ffmpeg/1410620#1410620.
/// </summary>
Dave750 = 1,
/// <summary>
/// Nightmode Dialogue algorithm.
/// Sourced from https://superuser.com/questions/852400/properly-downmix-5-1-to-stereo-using-ffmpeg/1410620#1410620.
/// </summary>
NightmodeDialogue = 2,
/// <summary>
/// RFC7845 Section 5.1.1.5 defined algorithm.
/// </summary>
Rfc7845 = 3,
/// <summary>
/// AC-4 standard algorithm with its default gain values.
/// Defined in ETSI TS 103 190 Section 6.2.17.
/// </summary>
Ac4 = 4
}
@@ -0,0 +1,64 @@
#pragma warning disable SA1300 // Lowercase required for backwards compat.
namespace MediaBrowser.Model.Entities;
/// <summary>
/// Enum containing encoder presets.
/// </summary>
public enum EncoderPreset
{
/// <summary>
/// Auto preset.
/// </summary>
auto = 0,
/// <summary>
/// Placebo preset.
/// </summary>
placebo = 1,
/// <summary>
/// Veryslow preset.
/// </summary>
veryslow = 2,
/// <summary>
/// Slower preset.
/// </summary>
slower = 3,
/// <summary>
/// Slow preset.
/// </summary>
slow = 4,
/// <summary>
/// Medium preset.
/// </summary>
medium = 5,
/// <summary>
/// Fast preset.
/// </summary>
fast = 6,
/// <summary>
/// Faster preset.
/// </summary>
faster = 7,
/// <summary>
/// Veryfast preset.
/// </summary>
veryfast = 8,
/// <summary>
/// Superfast preset.
/// </summary>
superfast = 9,
/// <summary>
/// Ultrafast preset.
/// </summary>
ultrafast = 10
}
+20
View File
@@ -0,0 +1,20 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Entities
{
public enum ExtraType
{
Unknown = 0,
Clip = 1,
Trailer = 2,
BehindTheScenes = 3,
DeletedScene = 4,
Interview = 5,
Scene = 6,
Sample = 7,
ThemeSong = 8,
ThemeVideo = 9,
Featurette = 10,
Short = 11
}
}
@@ -0,0 +1,49 @@
#pragma warning disable SA1300 // Lowercase required for backwards compat.
namespace MediaBrowser.Model.Entities;
/// <summary>
/// Enum containing hardware acceleration types.
/// </summary>
public enum HardwareAccelerationType
{
/// <summary>
/// Software acceleration.
/// </summary>
none = 0,
/// <summary>
/// AMD AMF.
/// </summary>
amf = 1,
/// <summary>
/// Intel Quick Sync Video.
/// </summary>
qsv = 2,
/// <summary>
/// NVIDIA NVENC.
/// </summary>
nvenc = 3,
/// <summary>
/// Video4Linux2 V4L2M2M.
/// </summary>
v4l2m2m = 4,
/// <summary>
/// Video Acceleration API (VAAPI).
/// </summary>
vaapi = 5,
/// <summary>
/// Video ToolBox.
/// </summary>
videotoolbox = 6,
/// <summary>
/// Rockchip Media Process Platform (RKMPP).
/// </summary>
rkmpp = 7
}
@@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace MediaBrowser.Model.Entities
{
/// <summary>
/// Since BaseItem and DTOBaseItem both have ProviderIds, this interface helps avoid code repetition by using extension methods.
/// </summary>
public interface IHasProviderIds
{
/// <summary>
/// Gets or sets the provider ids.
/// </summary>
/// <value>The provider ids.</value>
Dictionary<string, string> ProviderIds { get; set; }
}
}
+14
View File
@@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace MediaBrowser.Model.Entities;
/// <summary>
/// Interface for access to shares.
/// </summary>
public interface IHasShares
{
/// <summary>
/// Gets or sets the shares.
/// </summary>
IReadOnlyList<PlaylistUserPermissions> Shares { get; set; }
}
+77
View File
@@ -0,0 +1,77 @@
namespace MediaBrowser.Model.Entities
{
/// <summary>
/// Enum ImageType.
/// </summary>
public enum ImageType
{
/// <summary>
/// The primary.
/// </summary>
Primary = 0,
/// <summary>
/// The art.
/// </summary>
Art = 1,
/// <summary>
/// The backdrop.
/// </summary>
Backdrop = 2,
/// <summary>
/// The banner.
/// </summary>
Banner = 3,
/// <summary>
/// The logo.
/// </summary>
Logo = 4,
/// <summary>
/// The thumb.
/// </summary>
Thumb = 5,
/// <summary>
/// The disc.
/// </summary>
Disc = 6,
/// <summary>
/// The box.
/// </summary>
Box = 7,
/// <summary>
/// The screenshot.
/// </summary>
/// <remarks>
/// This enum value is obsolete.
/// XmlSerializer does not serialize/deserialize objects that are marked as [Obsolete].
/// </remarks>
Screenshot = 8,
/// <summary>
/// The menu.
/// </summary>
Menu = 9,
/// <summary>
/// The chapter image.
/// </summary>
Chapter = 10,
/// <summary>
/// The box rear.
/// </summary>
BoxRear = 11,
/// <summary>
/// The user profile image.
/// </summary>
Profile = 12
}
}

Some files were not shown because too many files have changed in this diff Show More