diff options
Diffstat (limited to 'MediaBrowser.Model')
| -rw-r--r-- | MediaBrowser.Model/Configuration/ServerConfiguration.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/ResolutionNormalizer.cs | 7 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dto/BaseItemDto.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dto/ItemCounts.cs | 9 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dto/TrickplayInfoDto.cs | 62 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dto/UserDto.cs | 9 | ||||
| -rw-r--r-- | MediaBrowser.Model/Entities/MediaStream.cs | 54 | ||||
| -rw-r--r-- | MediaBrowser.Model/Extensions/EnumerableExtensions.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Model/IO/AsyncFile.cs | 8 | ||||
| -rw-r--r-- | MediaBrowser.Model/Lyrics/LyricLineCue.cs | 13 | ||||
| -rw-r--r-- | MediaBrowser.Model/MediaBrowser.Model.csproj | 2 | ||||
| -rw-r--r-- | MediaBrowser.Model/MediaSegments/MediaSegmentGenerationRequest.cs | 8 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/MimeTypes.cs | 1 | ||||
| -rw-r--r-- | MediaBrowser.Model/Session/QueueItem.cs | 11 | ||||
| -rw-r--r-- | MediaBrowser.Model/Users/ForgotPasswordAction.cs | 4 |
15 files changed, 167 insertions, 27 deletions
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index a58c01c96..ac5c12304 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -287,5 +287,5 @@ public class ServerConfiguration : BaseApplicationConfiguration /// <summary> /// Gets or sets a value indicating whether old authorization methods are allowed. /// </summary> - public bool EnableLegacyAuthorization { get; set; } = true; + public bool EnableLegacyAuthorization { get; set; } } diff --git a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs index 1a636b240..88c378d66 100644 --- a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs +++ b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs @@ -43,7 +43,12 @@ namespace MediaBrowser.Model.Dlna } } - var referenceBitrate = h264EquivalentOutputBitrate * (30.0f / (targetFps ?? 30.0f)); + // 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) { diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 937409111..8f223c12a 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -569,7 +569,7 @@ namespace MediaBrowser.Model.Dto /// Gets or sets the trickplay manifest. /// </summary> /// <value>The trickplay manifest.</value> - public Dictionary<string, Dictionary<int, TrickplayInfo>> Trickplay { get; set; } + public Dictionary<string, Dictionary<int, TrickplayInfoDto>> Trickplay { get; set; } /// <summary> /// Gets or sets the type of the location. diff --git a/MediaBrowser.Model/Dto/ItemCounts.cs b/MediaBrowser.Model/Dto/ItemCounts.cs index 95f4a3d77..a15a0c82a 100644 --- a/MediaBrowser.Model/Dto/ItemCounts.cs +++ b/MediaBrowser.Model/Dto/ItemCounts.cs @@ -76,5 +76,14 @@ namespace MediaBrowser.Model.Dto /// </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; + } } } diff --git a/MediaBrowser.Model/Dto/TrickplayInfoDto.cs b/MediaBrowser.Model/Dto/TrickplayInfoDto.cs new file mode 100644 index 000000000..0c5f6e817 --- /dev/null +++ b/MediaBrowser.Model/Dto/TrickplayInfoDto.cs @@ -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; } +} diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs index 05019741e..c6b4a4d14 100644 --- a/MediaBrowser.Model/Dto/UserDto.cs +++ b/MediaBrowser.Model/Dto/UserDto.cs @@ -1,5 +1,6 @@ #nullable disable using System; +using System.ComponentModel; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Users; @@ -54,20 +55,22 @@ namespace MediaBrowser.Model.Dto /// 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> - public bool HasPassword { get; set; } + [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> - public bool HasConfiguredPassword { get; set; } + [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; } + public bool? HasConfiguredEasyPassword { get; set; } = false; /// <summary> /// Gets or sets whether async login is enabled or not. diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 5c8f37fcd..b1626e2c9 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -273,11 +273,28 @@ namespace MediaBrowser.Model.Entities // Do not display the language code in display titles if unset or set to a special code. Show it in all other cases (possibly expanded). if (!string.IsNullOrEmpty(Language) && !_specialCodes.Contains(Language, StringComparison.OrdinalIgnoreCase)) { - // Get full language string i.e. eng -> English. - string fullLanguage = CultureInfo - .GetCultures(CultureTypes.NeutralCultures) - .FirstOrDefault(r => r.ThreeLetterISOLanguageName.Equals(Language, StringComparison.OrdinalIgnoreCase)) - ?.DisplayName; + // Get full language string i.e. eng -> English, zh-Hans -> Chinese (Simplified). + var cultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures); + CultureInfo match = null; + if (Language.Contains('-', StringComparison.OrdinalIgnoreCase)) + { + match = cultures.FirstOrDefault(r => + r.Name.Equals(Language, StringComparison.OrdinalIgnoreCase)); + + if (match is null) + { + string baseLang = Language.AsSpan().LeftPart('-').ToString(); + match = cultures.FirstOrDefault(r => + r.TwoLetterISOLanguageName.Equals(baseLang, StringComparison.OrdinalIgnoreCase)); + } + } + else + { + match = cultures.FirstOrDefault(r => + r.ThreeLetterISOLanguageName.Equals(Language, StringComparison.OrdinalIgnoreCase)); + } + + string fullLanguage = match?.DisplayName; attributes.Add(StringHelper.FirstToUpper(fullLanguage ?? Language)); } @@ -376,11 +393,28 @@ namespace MediaBrowser.Model.Entities if (!string.IsNullOrEmpty(Language)) { - // Get full language string i.e. eng -> English. - string fullLanguage = CultureInfo - .GetCultures(CultureTypes.NeutralCultures) - .FirstOrDefault(r => r.ThreeLetterISOLanguageName.Equals(Language, StringComparison.OrdinalIgnoreCase)) - ?.DisplayName; + // Get full language string i.e. eng -> English, zh-Hans -> Chinese (Simplified). + var cultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures); + CultureInfo match = null; + if (Language.Contains('-', StringComparison.OrdinalIgnoreCase)) + { + match = cultures.FirstOrDefault(r => + r.Name.Equals(Language, StringComparison.OrdinalIgnoreCase)); + + if (match is null) + { + string baseLang = Language.AsSpan().LeftPart('-').ToString(); + match = cultures.FirstOrDefault(r => + r.TwoLetterISOLanguageName.Equals(baseLang, StringComparison.OrdinalIgnoreCase)); + } + } + else + { + match = cultures.FirstOrDefault(r => + r.ThreeLetterISOLanguageName.Equals(Language, StringComparison.OrdinalIgnoreCase)); + } + + string fullLanguage = match?.DisplayName; attributes.Add(StringHelper.FirstToUpper(fullLanguage ?? Language)); } else diff --git a/MediaBrowser.Model/Extensions/EnumerableExtensions.cs b/MediaBrowser.Model/Extensions/EnumerableExtensions.cs index 8963bdb73..94f425229 100644 --- a/MediaBrowser.Model/Extensions/EnumerableExtensions.cs +++ b/MediaBrowser.Model/Extensions/EnumerableExtensions.cs @@ -50,7 +50,7 @@ namespace MediaBrowser.Model.Extensions return 0; }) - .ThenByDescending(i => i.CommunityRating ?? 0) + .ThenByDescending(i => Math.Round(i.CommunityRating ?? 0, 1) ) .ThenByDescending(i => i.VoteCount ?? 0); } } diff --git a/MediaBrowser.Model/IO/AsyncFile.cs b/MediaBrowser.Model/IO/AsyncFile.cs index 3c8007d1c..a9db6b81c 100644 --- a/MediaBrowser.Model/IO/AsyncFile.cs +++ b/MediaBrowser.Model/IO/AsyncFile.cs @@ -27,6 +27,14 @@ namespace MediaBrowser.Model.IO }; /// <summary> + /// Creates, or truncates and overwrites, a file in the specified path. + /// </summary> + /// <param name="path">The path and name of the file to create.</param> + /// <returns>A <see cref="FileStream" /> that provides read/write access to the file specified in path.</returns> + public static FileStream Create(string path) + => new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous); + + /// <summary> /// Opens an existing file for reading. /// </summary> /// <param name="path">The file to be opened for reading.</param> diff --git a/MediaBrowser.Model/Lyrics/LyricLineCue.cs b/MediaBrowser.Model/Lyrics/LyricLineCue.cs index 1172a0231..291553361 100644 --- a/MediaBrowser.Model/Lyrics/LyricLineCue.cs +++ b/MediaBrowser.Model/Lyrics/LyricLineCue.cs @@ -8,22 +8,29 @@ public class LyricLineCue /// <summary> /// Initializes a new instance of the <see cref="LyricLineCue"/> class. /// </summary> - /// <param name="position">The start of the character index of the lyric.</param> + /// <param name="position">The start character index of the cue.</param> + /// <param name="endPosition">The end character index of the cue.</param> /// <param name="start">The start of the timestamp the lyric is synced to in ticks.</param> /// <param name="end">The end of the timestamp the lyric is synced to in ticks.</param> - public LyricLineCue(int position, long start, long? end) + public LyricLineCue(int position, int endPosition, long start, long? end) { Position = position; + EndPosition = endPosition; Start = start; End = end; } /// <summary> - /// Gets the character index of the lyric. + /// Gets the start character index of the cue. /// </summary> public int Position { get; } /// <summary> + /// Gets the end character index of the cue. + /// </summary> + public int EndPosition { get; } + + /// <summary> /// Gets the timestamp the lyric is synced to in ticks. /// </summary> public long Start { get; } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index e9dab6bc8..ef025d02d 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -8,7 +8,7 @@ <PropertyGroup> <Authors>Jellyfin Contributors</Authors> <PackageId>Jellyfin.Model</PackageId> - <VersionPrefix>10.11.0</VersionPrefix> + <VersionPrefix>10.12.0</VersionPrefix> <RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl> <PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression> </PropertyGroup> diff --git a/MediaBrowser.Model/MediaSegments/MediaSegmentGenerationRequest.cs b/MediaBrowser.Model/MediaSegments/MediaSegmentGenerationRequest.cs index 8c1f44de8..53d017375 100644 --- a/MediaBrowser.Model/MediaSegments/MediaSegmentGenerationRequest.cs +++ b/MediaBrowser.Model/MediaSegments/MediaSegmentGenerationRequest.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Generic; +using Jellyfin.Database.Implementations.Entities; +using MediaBrowser.Model.MediaSegments; namespace MediaBrowser.Model; @@ -11,4 +14,9 @@ public record MediaSegmentGenerationRequest /// Gets the Id to the BaseItem the segments should be extracted from. /// </summary> public Guid ItemId { get; init; } + + /// <summary> + /// Gets existing media segments generated on an earlier scan by this provider. + /// </summary> + public required IReadOnlyList<MediaSegmentDto> ExistingSegments { get; init; } } diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index de087d0e7..79f8675cb 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -56,6 +56,7 @@ namespace MediaBrowser.Model.Net ".rec", ".ts", ".rmvb", + ".vob", ".webm", ".wmv", ".wtv", diff --git a/MediaBrowser.Model/Session/QueueItem.cs b/MediaBrowser.Model/Session/QueueItem.cs index 32b19101b..43920a846 100644 --- a/MediaBrowser.Model/Session/QueueItem.cs +++ b/MediaBrowser.Model/Session/QueueItem.cs @@ -3,12 +3,11 @@ using System; -namespace MediaBrowser.Model.Session +namespace MediaBrowser.Model.Session; + +public record QueueItem { - public class QueueItem - { - public Guid Id { get; set; } + public Guid Id { get; set; } - public string PlaylistItemId { get; set; } - } + public string PlaylistItemId { get; set; } } diff --git a/MediaBrowser.Model/Users/ForgotPasswordAction.cs b/MediaBrowser.Model/Users/ForgotPasswordAction.cs index f198476e3..55907e6c8 100644 --- a/MediaBrowser.Model/Users/ForgotPasswordAction.cs +++ b/MediaBrowser.Model/Users/ForgotPasswordAction.cs @@ -1,11 +1,15 @@ #pragma warning disable CS1591 +using System; + namespace MediaBrowser.Model.Users { public enum ForgotPasswordAction { + [Obsolete("Returning different actions represents a security concern.")] ContactAdmin = 0, PinCode = 1, + [Obsolete("Returning different actions represents a security concern.")] InNetworkRequired = 2 } } |
