diff options
| author | adrez99 <59739805+adrez99@users.noreply.github.com> | 2022-10-11 18:15:28 +0200 |
|---|---|---|
| committer | adrez99 <adrez99@gmail.com> | 2022-10-11 18:18:21 +0200 |
| commit | 3736e360e76fdc44d8069905ba76aec03e69473f (patch) | |
| tree | 1626fd7da50abf0350ab1b644d6699bd39590dd6 /MediaBrowser.Controller | |
| parent | b8afdd892af01fd99011a6dc3df65cfb762084d6 (diff) | |
| parent | d50c1b2d4bc0c85428671b288adef1b336da1156 (diff) | |
Merge branch 'jellyfin:master' into gzip
Diffstat (limited to 'MediaBrowser.Controller')
32 files changed, 313 insertions, 177 deletions
diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 77a857b78..e671e5c71 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -171,10 +171,7 @@ namespace MediaBrowser.Controller.Entities /// <exception cref="ArgumentNullException">Throws if child is null.</exception> public void AddVirtualChild(BaseItem child) { - if (child == null) - { - throw new ArgumentNullException(nameof(child)); - } + ArgumentNullException.ThrowIfNull(child); _virtualChildren.Add(child); } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index bd397bdd1..6555de855 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -54,7 +54,7 @@ namespace MediaBrowser.Controller.Entities.Audio public string AlbumArtist => AlbumArtists.FirstOrDefault(); [JsonIgnore] - public override bool SupportsPeople => false; + public override bool SupportsPeople => true; /// <summary> /// Gets the tracks. diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 5cee6ce40..41fce67fa 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1101,10 +1101,7 @@ namespace MediaBrowser.Controller.Entities private MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, BaseItem item, MediaSourceType type) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); var protocol = item.PathProtocol; @@ -1544,10 +1541,7 @@ namespace MediaBrowser.Controller.Entities /// <exception cref="ArgumentNullException">If user is null.</exception> public bool IsParentalAllowed(User user) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); if (!IsVisibleViaTags(user)) { @@ -1667,10 +1661,7 @@ namespace MediaBrowser.Controller.Entities /// <exception cref="ArgumentNullException"><paramref name="user" /> is <c>null</c>.</exception> public virtual bool IsVisible(User user) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); return IsParentalAllowed(user); } @@ -1842,10 +1833,7 @@ namespace MediaBrowser.Controller.Entities DateTime? datePlayed, bool resetPosition) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); var data = UserDataManager.GetUserData(user, this); @@ -1876,10 +1864,7 @@ namespace MediaBrowser.Controller.Entities /// <exception cref="ArgumentNullException">Throws if user is null.</exception> public virtual void MarkUnplayed(User user) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); var data = UserDataManager.GetUserData(user, this); @@ -2110,10 +2095,7 @@ namespace MediaBrowser.Controller.Entities /// <returns>Image index.</returns> public int GetImageIndex(ItemImageInfo image) { - if (image == null) - { - throw new ArgumentNullException(nameof(image)); - } + ArgumentNullException.ThrowIfNull(image); if (image.Type == ImageType.Chapter) { @@ -2320,10 +2302,7 @@ namespace MediaBrowser.Controller.Entities public virtual bool IsUnplayed(User user) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); var userdata = UserDataManager.GetUserData(user, this); @@ -2616,7 +2595,8 @@ namespace MediaBrowser.Controller.Entities return ExtraIds .Select(LibraryManager.GetItemById) .Where(i => i != null) - .Where(i => i.ExtraType.HasValue && extraTypes.Contains(i.ExtraType.Value)); + .Where(i => i.ExtraType.HasValue && extraTypes.Contains(i.ExtraType.Value)) + .OrderBy(i => i.SortName); } public virtual long GetRunTimeTicksForPlayState() diff --git a/MediaBrowser.Controller/Entities/BaseItemExtensions.cs b/MediaBrowser.Controller/Entities/BaseItemExtensions.cs index e0583e630..948eb4375 100644 --- a/MediaBrowser.Controller/Entities/BaseItemExtensions.cs +++ b/MediaBrowser.Controller/Entities/BaseItemExtensions.cs @@ -71,15 +71,9 @@ namespace MediaBrowser.Controller.Entities where T : BaseItem where TU : BaseItem { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } + ArgumentNullException.ThrowIfNull(source); - if (dest == null) - { - throw new ArgumentNullException(nameof(dest)); - } + ArgumentNullException.ThrowIfNull(dest); var destProps = typeof(TU).GetProperties().Where(x => x.CanWrite).ToList(); diff --git a/MediaBrowser.Controller/Entities/BasePluginFolder.cs b/MediaBrowser.Controller/Entities/BasePluginFolder.cs index 272a37df1..afafaf1c2 100644 --- a/MediaBrowser.Controller/Entities/BasePluginFolder.cs +++ b/MediaBrowser.Controller/Entities/BasePluginFolder.cs @@ -1,5 +1,3 @@ -#nullable disable - #pragma warning disable CS1591 using System.Text.Json.Serialization; @@ -13,7 +11,7 @@ namespace MediaBrowser.Controller.Entities public abstract class BasePluginFolder : Folder, ICollectionFolder { [JsonIgnore] - public virtual string CollectionType => null; + public virtual string? CollectionType => null; [JsonIgnore] public override bool SupportsInheritedParentImages => false; diff --git a/MediaBrowser.Controller/Entities/Extensions.cs b/MediaBrowser.Controller/Entities/Extensions.cs index 9ce8eebe3..1acb92fdc 100644 --- a/MediaBrowser.Controller/Entities/Extensions.cs +++ b/MediaBrowser.Controller/Entities/Extensions.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Linq; using Jellyfin.Extensions; @@ -19,9 +17,11 @@ namespace MediaBrowser.Controller.Entities /// <param name="url">Trailer URL.</param> public static void AddTrailerUrl(this BaseItem item, string url) { - if (string.IsNullOrEmpty(url)) + ArgumentNullException.ThrowIfNull(url); + + if (url.Length == 0) { - throw new ArgumentNullException(nameof(url)); + throw new ArgumentException("String can't be empty", nameof(url)); } var current = item.RemoteTrailers.FirstOrDefault(i => string.Equals(i.Url, url, StringComparison.OrdinalIgnoreCase)); diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index b6983b73e..808f91810 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -860,7 +860,7 @@ namespace MediaBrowser.Controller.Entities return true; } - if (!string.IsNullOrEmpty(query.AdjacentTo)) + if (query.AdjacentTo.HasValue && !query.AdjacentTo.Value.Equals(default)) { Logger.LogDebug("Query requires post-filtering due to AdjacentTo"); return true; @@ -892,29 +892,7 @@ namespace MediaBrowser.Controller.Entities private static BaseItem[] SortItemsByRequest(InternalItemsQuery query, IReadOnlyList<BaseItem> items) { - var ids = query.ItemIds; - int size = items.Count; - - // ids can potentially contain non-unique guids, but query result cannot, - // so we include only first occurrence of each guid - var positions = new Dictionary<Guid, int>(size); - int index = 0; - for (int i = 0; i < ids.Length; i++) - { - if (positions.TryAdd(ids[i], index)) - { - index++; - } - } - - var newItems = new BaseItem[size]; - for (int i = 0; i < size; i++) - { - var item = items[i]; - newItems[positions[item.Id]] = item; - } - - return newItems; + return items.OrderBy(i => Array.IndexOf(query.ItemIds, i.Id)).ToArray(); } public QueryResult<BaseItem> GetItems(InternalItemsQuery query) @@ -1029,9 +1007,9 @@ namespace MediaBrowser.Controller.Entities #pragma warning restore CA1309 // This must be the last filter - if (!string.IsNullOrEmpty(query.AdjacentTo)) + if (query.AdjacentTo.HasValue && !query.AdjacentTo.Value.Equals(default)) { - items = UserViewBuilder.FilterForAdjacency(items.ToList(), query.AdjacentTo); + items = UserViewBuilder.FilterForAdjacency(items.ToList(), query.AdjacentTo.Value); } return UserViewBuilder.SortAndPage(items, null, query, LibraryManager, enableSorting); @@ -1045,10 +1023,7 @@ namespace MediaBrowser.Controller.Entities IServerConfigurationManager configurationManager, ICollectionManager collectionManager) { - if (items == null) - { - throw new ArgumentNullException(nameof(items)); - } + ArgumentNullException.ThrowIfNull(items); if (CollapseBoxSetItems(query, queryParent, user, configurationManager)) { @@ -1295,20 +1270,14 @@ namespace MediaBrowser.Controller.Entities public List<BaseItem> GetChildren(User user, bool includeLinkedChildren) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); return GetChildren(user, includeLinkedChildren, null); } public virtual List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); // the true root should return our users root folder children if (IsPhysicalRoot) @@ -1389,10 +1358,7 @@ namespace MediaBrowser.Controller.Entities public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); var result = new Dictionary<Guid, BaseItem>(); diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index db1697c79..13bfd07c3 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -129,7 +129,7 @@ namespace MediaBrowser.Controller.Entities public Guid[] ExcludeItemIds { get; set; } - public string? AdjacentTo { get; set; } + public Guid? AdjacentTo { get; set; } public string[] PersonTypes { get; set; } diff --git a/MediaBrowser.Controller/Entities/PeopleHelper.cs b/MediaBrowser.Controller/Entities/PeopleHelper.cs index 687ce1ec8..8571bfcea 100644 --- a/MediaBrowser.Controller/Entities/PeopleHelper.cs +++ b/MediaBrowser.Controller/Entities/PeopleHelper.cs @@ -11,10 +11,7 @@ namespace MediaBrowser.Controller.Entities { public static void AddPerson(List<PersonInfo> people, PersonInfo person) { - if (person == null) - { - throw new ArgumentNullException(nameof(person)); - } + ArgumentNullException.ThrowIfNull(person); if (string.IsNullOrEmpty(person.Name)) { diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index bd8df2fac..599d35da6 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -244,7 +244,7 @@ namespace MediaBrowser.Controller.Entities.TV /// <summary> /// This is called before any metadata refresh and returns true or false indicating if changes were made. /// </summary> - /// <param name="replaceAllMetadata"><c>true</c> to replace metdata, <c>false</c> to not.</param> + /// <param name="replaceAllMetadata"><c>true</c> to replace metadata, <c>false</c> to not.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> public override bool BeforeMetadataRefresh(bool replaceAllMetadata) { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index b4e213e1c..d66802a64 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -263,10 +263,14 @@ namespace MediaBrowser.Controller.Entities.TV SeriesPresentationUniqueKey = seriesKey, IncludeItemTypes = new[] { BaseItemKind.Episode, BaseItemKind.Season }, OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }, - DtoOptions = options, - IsMissing = user?.DisplayMissingEpisodes + DtoOptions = options }; + if (user == null || !user.DisplayMissingEpisodes) + { + query.IsMissing = false; + } + var allItems = LibraryManager.GetItemList(query); var allSeriesEpisodes = allItems.OfType<Episode>().ToList(); diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 2996104e7..f467a6038 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -433,9 +433,9 @@ namespace MediaBrowser.Controller.Entities var user = query.User; // This must be the last filter - if (!string.IsNullOrEmpty(query.AdjacentTo)) + if (query.AdjacentTo.HasValue && !query.AdjacentTo.Value.Equals(default)) { - items = FilterForAdjacency(items.ToList(), query.AdjacentTo); + items = FilterForAdjacency(items.ToList(), query.AdjacentTo.Value); } return SortAndPage(items, totalRecordLimit, query, libraryManager, true); @@ -985,10 +985,9 @@ namespace MediaBrowser.Controller.Entities return _userViewManager.GetUserSubView(parent.Id, type, localizationKey, sortName); } - public static IEnumerable<BaseItem> FilterForAdjacency(List<BaseItem> list, string adjacentToId) + public static IEnumerable<BaseItem> FilterForAdjacency(List<BaseItem> list, Guid adjacentTo) { - var adjacentToIdGuid = new Guid(adjacentToId); - var adjacentToItem = list.FirstOrDefault(i => i.Id.Equals(adjacentToIdGuid)); + var adjacentToItem = list.FirstOrDefault(i => i.Id.Equals(adjacentTo)); var index = list.IndexOf(adjacentToItem); @@ -1005,7 +1004,7 @@ namespace MediaBrowser.Controller.Entities nextId = list[index + 1].Id; } - return list.Where(i => i.Id.Equals(previousId) || i.Id.Equals(nextId) || i.Id.Equals(adjacentToIdGuid)); + return list.Where(i => i.Id.Equals(previousId) || i.Id.Equals(nextId) || i.Id.Equals(adjacentTo)); } } } diff --git a/MediaBrowser.Controller/IDisplayPreferencesManager.cs b/MediaBrowser.Controller/IDisplayPreferencesManager.cs index 1678d5067..10c0f56e0 100644 --- a/MediaBrowser.Controller/IDisplayPreferencesManager.cs +++ b/MediaBrowser.Controller/IDisplayPreferencesManager.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Collections.Generic; using Jellyfin.Data.Entities; @@ -50,7 +48,7 @@ namespace MediaBrowser.Controller /// <param name="itemId">The item id.</param> /// <param name="client">The client string.</param> /// <returns>The dictionary of custom item display preferences.</returns> - Dictionary<string, string> ListCustomItemDisplayPreferences(Guid userId, Guid itemId, string client); + Dictionary<string, string?> ListCustomItemDisplayPreferences(Guid userId, Guid itemId, string client); /// <summary> /// Sets the custom item display preference for the user and client. @@ -59,7 +57,7 @@ namespace MediaBrowser.Controller /// <param name="itemId">The item id.</param> /// <param name="client">The client id.</param> /// <param name="customPreferences">A dictionary of custom item display preferences.</param> - void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary<string, string> customPreferences); + void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary<string, string?> customPreferences); /// <summary> /// Saves changes made to the database. diff --git a/MediaBrowser.Controller/IO/FileData.cs b/MediaBrowser.Controller/IO/FileData.cs index 2429ac42d..71feae536 100644 --- a/MediaBrowser.Controller/IO/FileData.cs +++ b/MediaBrowser.Controller/IO/FileData.cs @@ -40,10 +40,7 @@ namespace MediaBrowser.Controller.IO throw new ArgumentNullException(nameof(path)); } - if (args == null) - { - throw new ArgumentNullException(nameof(args)); - } + ArgumentNullException.ThrowIfNull(args); var entries = directoryService.GetFileSystemEntries(path); diff --git a/MediaBrowser.Controller/Lyrics/ILyricManager.cs b/MediaBrowser.Controller/Lyrics/ILyricManager.cs new file mode 100644 index 000000000..bb93e1e4c --- /dev/null +++ b/MediaBrowser.Controller/Lyrics/ILyricManager.cs @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using MediaBrowser.Controller.Entities; + +namespace MediaBrowser.Controller.Lyrics; + +/// <summary> +/// Interface ILyricManager. +/// </summary> +public interface ILyricManager +{ + /// <summary> + /// Gets the lyrics. + /// </summary> + /// <param name="item">The media item.</param> + /// <returns>A task representing found lyrics the passed item.</returns> + Task<LyricResponse?> GetLyrics(BaseItem item); + + /// <summary> + /// Checks if requested item has a matching local lyric file. + /// </summary> + /// <param name="item">The media item.</param> + /// <returns>True if item has a matching lyric file; otherwise false.</returns> + bool HasLyricFile(BaseItem item); +} diff --git a/MediaBrowser.Controller/Lyrics/ILyricProvider.cs b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs new file mode 100644 index 000000000..2a04c6152 --- /dev/null +++ b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Resolvers; + +namespace MediaBrowser.Controller.Lyrics; + +/// <summary> +/// Interface ILyricsProvider. +/// </summary> +public interface ILyricProvider +{ + /// <summary> + /// Gets a value indicating the provider name. + /// </summary> + string Name { get; } + + /// <summary> + /// Gets the priority. + /// </summary> + /// <value>The priority.</value> + ResolverPriority Priority { get; } + + /// <summary> + /// Gets the supported media types for this provider. + /// </summary> + /// <value>The supported media types.</value> + IReadOnlyCollection<string> SupportedMediaTypes { get; } + + /// <summary> + /// Gets the lyrics. + /// </summary> + /// <param name="item">The media item.</param> + /// <returns>A task representing found lyrics.</returns> + Task<LyricResponse?> GetLyrics(BaseItem item); +} diff --git a/MediaBrowser.Controller/Lyrics/LyricInfo.cs b/MediaBrowser.Controller/Lyrics/LyricInfo.cs new file mode 100644 index 000000000..6ec6df582 --- /dev/null +++ b/MediaBrowser.Controller/Lyrics/LyricInfo.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using Jellyfin.Extensions; + +namespace MediaBrowser.Controller.Lyrics; + +/// <summary> +/// Lyric helper methods. +/// </summary> +public static class LyricInfo +{ + /// <summary> + /// Gets matching lyric file for a requested item. + /// </summary> + /// <param name="lyricProvider">The lyricProvider interface to use.</param> + /// <param name="itemPath">Path of requested item.</param> + /// <returns>Lyric file path if passed lyric provider's supported media type is found; otherwise, null.</returns> + public static string? GetLyricFilePath(this ILyricProvider lyricProvider, string itemPath) + { + // Ensure we have a provider + if (lyricProvider is null) + { + return null; + } + + // Ensure the path to the item is not null + string? itemDirectoryPath = Path.GetDirectoryName(itemPath); + if (itemDirectoryPath is null) + { + return null; + } + + // Ensure the directory path exists + if (!Directory.Exists(itemDirectoryPath)) + { + return null; + } + + foreach (var lyricFilePath in Directory.GetFiles(itemDirectoryPath, $"{Path.GetFileNameWithoutExtension(itemPath)}.*")) + { + if (lyricProvider.SupportedMediaTypes.Contains(Path.GetExtension(lyricFilePath.AsSpan())[1..], StringComparison.OrdinalIgnoreCase)) + { + return lyricFilePath; + } + } + + return null; + } +} diff --git a/MediaBrowser.Controller/Lyrics/LyricLine.cs b/MediaBrowser.Controller/Lyrics/LyricLine.cs new file mode 100644 index 000000000..c406f92fc --- /dev/null +++ b/MediaBrowser.Controller/Lyrics/LyricLine.cs @@ -0,0 +1,28 @@ +namespace MediaBrowser.Controller.Lyrics; + +/// <summary> +/// Lyric model. +/// </summary> +public class LyricLine +{ + /// <summary> + /// Initializes a new instance of the <see cref="LyricLine"/> class. + /// </summary> + /// <param name="text">The lyric text.</param> + /// <param name="start">The lyric start time in ticks.</param> + public LyricLine(string text, long? start = null) + { + Text = text; + Start = start; + } + + /// <summary> + /// Gets the text of this lyric line. + /// </summary> + public string Text { get; } + + /// <summary> + /// Gets the start time in ticks. + /// </summary> + public long? Start { get; } +} diff --git a/MediaBrowser.Controller/Lyrics/LyricMetadata.cs b/MediaBrowser.Controller/Lyrics/LyricMetadata.cs new file mode 100644 index 000000000..6091ede52 --- /dev/null +++ b/MediaBrowser.Controller/Lyrics/LyricMetadata.cs @@ -0,0 +1,54 @@ +using System; + +namespace MediaBrowser.Controller.Lyrics; + +/// <summary> +/// LyricMetadata model. +/// </summary> +public class LyricMetadata +{ + /// <summary> + /// Gets or sets the song artist. + /// </summary> + public string? Artist { get; set; } + + /// <summary> + /// Gets or sets the album this song is on. + /// </summary> + public string? Album { get; set; } + + /// <summary> + /// Gets or sets the title of the song. + /// </summary> + public string? Title { get; set; } + + /// <summary> + /// Gets or sets the author of the lyric data. + /// </summary> + public string? Author { get; set; } + + /// <summary> + /// Gets or sets the length of the song in ticks. + /// </summary> + public long? Length { get; set; } + + /// <summary> + /// Gets or sets who the LRC file was created by. + /// </summary> + public string? By { get; set; } + + /// <summary> + /// Gets or sets the lyric offset compared to audio in ticks. + /// </summary> + public long? Offset { get; set; } + + /// <summary> + /// Gets or sets the software used to create the LRC file. + /// </summary> + public string? Creator { get; set; } + + /// <summary> + /// Gets or sets the version of the creator used. + /// </summary> + public string? Version { get; set; } +} diff --git a/MediaBrowser.Controller/Lyrics/LyricResponse.cs b/MediaBrowser.Controller/Lyrics/LyricResponse.cs new file mode 100644 index 000000000..0d52b5ec5 --- /dev/null +++ b/MediaBrowser.Controller/Lyrics/LyricResponse.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Lyrics; + +/// <summary> +/// LyricResponse model. +/// </summary> +public class LyricResponse +{ + /// <summary> + /// Gets or sets Metadata for the lyrics. + /// </summary> + public LyricMetadata Metadata { get; set; } = new(); + + /// <summary> + /// Gets or sets a collection of individual lyric lines. + /// </summary> + public IReadOnlyList<LyricLine> Lyrics { get; set; } = Array.Empty<LyricLine>(); +} diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 7c59fa300..d0362b128 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -194,7 +194,7 @@ namespace MediaBrowser.Controller.MediaEncoding /// <summary> /// Gets the name of the output video codec. /// </summary> - /// <param name="state">Encording state.</param> + /// <param name="state">Encoding state.</param> /// <param name="encodingOptions">Encoding options.</param> /// <returns>Encoder string.</returns> public string GetVideoEncoder(EncodingJobInfo state, EncodingOptions encodingOptions) @@ -256,6 +256,21 @@ namespace MediaBrowser.Controller.MediaEncoding return string.Empty; } + /// <summary> + /// Gets the referer param. + /// </summary> + /// <param name="state">The state.</param> + /// <returns>System.String.</returns> + public string GetRefererParam(EncodingJobInfo state) + { + if (state.RemoteHttpHeaders.TryGetValue("Referer", out string referer)) + { + return "-referer \"" + referer + "\""; + } + + return string.Empty; + } + public static string GetInputFormat(string container) { if (string.IsNullOrEmpty(container)) @@ -1152,16 +1167,15 @@ namespace MediaBrowser.Controller.MediaEncoding if (state.SubtitleStream.IsExternal) { - var subtitlePath = state.SubtitleStream.Path; var charsetParam = string.Empty; if (!string.IsNullOrEmpty(state.SubtitleStream.Language)) { var charenc = _subtitleEncoder.GetSubtitleFileCharacterSet( - subtitlePath, - state.SubtitleStream.Language, - state.MediaSource.Protocol, - CancellationToken.None).GetAwaiter().GetResult(); + state.SubtitleStream, + state.SubtitleStream.Language, + state.MediaSource, + CancellationToken.None).GetAwaiter().GetResult(); if (!string.IsNullOrEmpty(charenc)) { @@ -1173,7 +1187,7 @@ namespace MediaBrowser.Controller.MediaEncoding return string.Format( CultureInfo.InvariantCulture, "subtitles=f='{0}'{1}{2}{3}{4}{5}", - _mediaEncoder.EscapeSubtitleFilterPath(subtitlePath), + _mediaEncoder.EscapeSubtitleFilterPath(state.SubtitleStream.Path), charsetParam, alphaParam, sub2videoParam, @@ -1981,7 +1995,7 @@ namespace MediaBrowser.Controller.MediaEncoding } } - // Cap the max target bitrate to intMax/2 to satisify the bufsize=bitrate*2. + // Cap the max target bitrate to intMax/2 to satisfy the bufsize=bitrate*2. return Math.Min(bitrate ?? 0, int.MaxValue / 2); } @@ -4977,13 +4991,13 @@ namespace MediaBrowser.Controller.MediaEncoding // The default value of -probesize is more than enough, so leave it as is. var ffmpegAnalyzeDuration = _config.GetFFmpegAnalyzeDuration() ?? string.Empty; - if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration)) + if (state.MediaSource.AnalyzeDurationMs > 0) { - analyzeDurationArgument = "-analyzeduration " + ffmpegAnalyzeDuration; + analyzeDurationArgument = "-analyzeduration " + (state.MediaSource.AnalyzeDurationMs.Value * 1000).ToString(CultureInfo.InvariantCulture); } - else if (state.MediaSource.AnalyzeDurationMs.HasValue) + else if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration)) { - analyzeDurationArgument = "-analyzeduration " + (state.MediaSource.AnalyzeDurationMs.Value * 1000).ToString(CultureInfo.InvariantCulture); + analyzeDurationArgument = "-analyzeduration " + ffmpegAnalyzeDuration; } if (!string.IsNullOrEmpty(analyzeDurationArgument)) @@ -5002,6 +5016,15 @@ namespace MediaBrowser.Controller.MediaEncoding inputModifier = inputModifier.Trim(); + var refererParam = GetRefererParam(state); + + if (!string.IsNullOrEmpty(refererParam)) + { + inputModifier += " " + refererParam; + } + + inputModifier = inputModifier.Trim(); + inputModifier += " " + GetFastSeekCommandLineParameter(state, encodingOptions, segmentContainer); inputModifier = inputModifier.Trim(); @@ -5082,15 +5105,9 @@ namespace MediaBrowser.Controller.MediaEncoding MediaSourceInfo mediaSource, string requestedUrl) { - if (state == null) - { - throw new ArgumentNullException(nameof(state)); - } + ArgumentNullException.ThrowIfNull(state); - if (mediaSource == null) - { - throw new ArgumentNullException(nameof(mediaSource)); - } + ArgumentNullException.ThrowIfNull(mediaSource); var path = mediaSource.Path; var protocol = mediaSource.Protocol; @@ -5536,7 +5553,7 @@ namespace MediaBrowser.Controller.MediaEncoding return index; } - if (string.Equals(currentMediaStream.Path, streamToFind.Path, StringComparison.Ordinal)) + if (string.Equals(currentMediaStream.Path, streamToFind.Path, StringComparison.Ordinal)) { index++; } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index 491662861..c9625cf1d 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Text.Json.Serialization; using Jellyfin.Data.Entities; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Drawing; diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index dae30cd8b..69d0bf45c 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -38,6 +38,12 @@ namespace MediaBrowser.Controller.MediaEncoding Version EncoderVersion { get; } /// <summary> + /// Whether p key pausing is supported. + /// </summary> + /// <value><c>true</c> if p key pausing is supported, <c>false</c> otherwise.</value> + bool IsPkeyPauseSupported { get; } + + /// <summary> /// Gets a value indicating whether the configured Vaapi device is from AMD(radeonsi/r600 Mesa driver). /// </summary> /// <value><c>true</c> if the Vaapi device is an AMD(radeonsi/r600 Mesa driver) GPU, <c>false</c> otherwise.</value> diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs index 4483cf708..5bf83a9e3 100644 --- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs @@ -6,7 +6,8 @@ using System.IO; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.MediaEncoding { @@ -37,11 +38,11 @@ namespace MediaBrowser.Controller.MediaEncoding /// <summary> /// Gets the subtitle language encoding parameter. /// </summary> - /// <param name="path">The path.</param> + /// <param name="subtitleStream">The subtitle stream.</param> /// <param name="language">The language.</param> - /// <param name="protocol">The protocol.</param> + /// <param name="mediaSource">The media source.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>System.String.</returns> - Task<string> GetSubtitleFileCharacterSet(string path, string language, MediaProtocol protocol, CancellationToken cancellationToken); + Task<string> GetSubtitleFileCharacterSet(MediaStream subtitleStream, string language, MediaSourceInfo mediaSource, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs index eadc09fd4..647de5003 100644 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -38,10 +38,7 @@ namespace MediaBrowser.Controller.Net protected BasePeriodicWebSocketListener(ILogger<BasePeriodicWebSocketListener<TReturnDataType, TStateType>> logger) { - if (logger == null) - { - throw new ArgumentNullException(nameof(logger)); - } + ArgumentNullException.ThrowIfNull(logger); Logger = logger; } @@ -77,10 +74,7 @@ namespace MediaBrowser.Controller.Net /// <returns>Task.</returns> public Task ProcessMessageAsync(WebSocketMessageInfo message) { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } + ArgumentNullException.ThrowIfNull(message); if (message.MessageType == StartType) { diff --git a/MediaBrowser.Controller/Net/ISessionContext.cs b/MediaBrowser.Controller/Net/ISessionContext.cs deleted file mode 100644 index b48181b3f..000000000 --- a/MediaBrowser.Controller/Net/ISessionContext.cs +++ /dev/null @@ -1,20 +0,0 @@ -#pragma warning disable CS1591 - -using System.Threading.Tasks; -using Jellyfin.Data.Entities; -using MediaBrowser.Controller.Session; -using Microsoft.AspNetCore.Http; - -namespace MediaBrowser.Controller.Net -{ - public interface ISessionContext - { - Task<SessionInfo> GetSession(object requestContext); - - Task<User?> GetUser(object requestContext); - - Task<SessionInfo> GetSession(HttpContext requestContext); - - Task<User?> GetUser(HttpContext requestContext); - } -} diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs index 43c7ce370..4f2492b89 100644 --- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -6,7 +6,6 @@ using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Net; -using Microsoft.AspNetCore.Http; namespace MediaBrowser.Controller.Net { diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 828ecb2c5..7ae9ff746 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; using System.Text.Json.Serialization; diff --git a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs index 32a9cbef2..14428df5b 100644 --- a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs @@ -18,9 +18,9 @@ namespace MediaBrowser.Controller.Providers /// Fetches the metadata asynchronously. /// </summary> /// <param name="item">The item.</param> - /// <param name="options">The options.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ItemUpdateType}.</returns> + /// <param name="options">The <see cref="MetadataRefreshOptions"/>.</param> + /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> + /// <returns>A <see cref="Task"/> fetching the <see cref="ItemUpdateType"/>.</returns> Task<ItemUpdateType> FetchAsync(TItemType item, MetadataRefreshOptions options, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs b/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs index a0c38b309..216494556 100644 --- a/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs +++ b/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs @@ -549,7 +549,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates if (InitialState.Equals(GroupStateType.Playing)) { - // Group went from playing to waiting state and a pause request occured while waiting. + // Group went from playing to waiting state and a pause request occurred while waiting. var pauseRequest = new PauseGroupRequest(); pausedState.HandleRequest(pauseRequest, context, Type, session, cancellationToken); } diff --git a/MediaBrowser.Controller/SyncPlay/PlaybackRequests/RemoveFromPlaylistGroupRequest.cs b/MediaBrowser.Controller/SyncPlay/PlaybackRequests/RemoveFromPlaylistGroupRequest.cs index 2f38d6adc..619294e95 100644 --- a/MediaBrowser.Controller/SyncPlay/PlaybackRequests/RemoveFromPlaylistGroupRequest.cs +++ b/MediaBrowser.Controller/SyncPlay/PlaybackRequests/RemoveFromPlaylistGroupRequest.cs @@ -27,9 +27,9 @@ namespace MediaBrowser.Controller.SyncPlay.PlaybackRequests } /// <summary> - /// Gets the playlist identifiers ot the items. + /// Gets the playlist identifiers of the items. /// </summary> - /// <value>The playlist identifiers ot the items.</value> + /// <value>The playlist identifiers of the items.</value> public IReadOnlyList<Guid> PlaylistItemIds { get; } /// <summary> diff --git a/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs b/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs index f49876cca..3a7685f34 100644 --- a/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs +++ b/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs @@ -102,7 +102,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue } /// <summary> - /// Appends new items to the playlist. The specified order is mantained. + /// Appends new items to the playlist. The specified order is maintained. /// </summary> /// <param name="items">The items to add to the playlist.</param> public void Queue(IReadOnlyList<Guid> items) @@ -197,7 +197,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue } /// <summary> - /// Adds new items to the playlist right after the playing item. The specified order is mantained. + /// Adds new items to the playlist right after the playing item. The specified order is maintained. /// </summary> /// <param name="items">The items to add to the playlist.</param> public void QueueNext(IReadOnlyList<Guid> items) |
