diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 23f2456ac..e147cb977 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -569,7 +569,7 @@ namespace Emby.Dlna.PlayTo streamInfo.TargetVideoCodecTag, streamInfo.IsTargetAVC); - return list.Count == 0 ? null : list[0]; + return list.FirstOrDefault(); } return null; @@ -883,7 +883,7 @@ namespace Emby.Dlna.PlayTo private class StreamParams { - private MediaSourceInfo mediaSource; + private MediaSourceInfo _mediaSource; private IMediaSourceManager _mediaSourceManager; public Guid ItemId { get; set; } @@ -908,24 +908,22 @@ namespace Emby.Dlna.PlayTo public async Task GetMediaSource(CancellationToken cancellationToken) { - if (mediaSource != null) + if (_mediaSource != null) { - return mediaSource; + return _mediaSource; } - var hasMediaSources = Item as IHasMediaSources; - - if (hasMediaSources == null) + if (Item is not IHasMediaSources) { return null; } if (_mediaSourceManager != null) { - mediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false); + _mediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false); } - return mediaSource; + return _mediaSource; } private static Guid GetItemId(string url) diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 1da9b4650..662bca508 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -5914,7 +5914,7 @@ AND Type = @InternalPersonType)"); } } - public void SaveMediaStreams(Guid id, List streams, CancellationToken cancellationToken) + public void SaveMediaStreams(Guid id, IReadOnlyList streams, CancellationToken cancellationToken) { CheckDisposed(); @@ -5946,7 +5946,7 @@ AND Type = @InternalPersonType)"); } } - private void InsertMediaStreams(byte[] idBlob, List streams, IDatabaseConnection db) + private void InsertMediaStreams(byte[] idBlob, IReadOnlyList streams, IDatabaseConnection db) { const int Limit = 10; var startIndex = 0; diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 5c86dbbb7..4f8a52f41 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -581,7 +581,7 @@ namespace Emby.Server.Implementations.IO } /// - public virtual List GetDrives() + public virtual IEnumerable GetDrives() { // check for ready state to avoid waiting for drives to timeout // some drives on linux have no actual size or are used for other purposes @@ -595,7 +595,7 @@ namespace Emby.Server.Implementations.IO Name = d.Name, FullName = d.RootDirectory.FullName, IsDirectory = true - }).ToList(); + }); } /// diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index a414e7e16..eb95977ef 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -344,7 +344,7 @@ namespace Emby.Server.Implementations.Library return sources; } - private string[] NormalizeLanguage(string language) + private IReadOnlyList NormalizeLanguage(string language) { if (string.IsNullOrEmpty(language)) { diff --git a/Emby.Server.Implementations/Library/MediaStreamSelector.cs b/Emby.Server.Implementations/Library/MediaStreamSelector.cs index da0c89c13..c5abb9a0a 100644 --- a/Emby.Server.Implementations/Library/MediaStreamSelector.cs +++ b/Emby.Server.Implementations/Library/MediaStreamSelector.cs @@ -1,5 +1,3 @@ -#nullable disable - #pragma warning disable CS1591 using System; @@ -13,10 +11,9 @@ namespace Emby.Server.Implementations.Library { public static class MediaStreamSelector { - public static int? GetDefaultAudioStreamIndex(List streams, string[] preferredLanguages, bool preferDefaultTrack) + public static int? GetDefaultAudioStreamIndex(IReadOnlyList streams, IReadOnlyList preferredLanguages, bool preferDefaultTrack) { - streams = GetSortedStreams(streams, MediaStreamType.Audio, preferredLanguages) - .ToList(); + var sortedStreams = GetSortedStreams(streams, MediaStreamType.Audio, preferredLanguages); if (preferDefaultTrack) { @@ -28,24 +25,15 @@ namespace Emby.Server.Implementations.Library } } - var stream = streams.FirstOrDefault(); - - if (stream != null) - { - return stream.Index; - } - - return null; + return sortedStreams.FirstOrDefault()?.Index; } public static int? GetDefaultSubtitleStreamIndex( IEnumerable streams, - string[] preferredLanguages, + IReadOnlyList preferredLanguages, SubtitlePlaybackMode mode, string audioTrackLanguage) { - MediaStream stream = null; - if (mode == SubtitlePlaybackMode.None) { return null; @@ -59,6 +47,7 @@ namespace Emby.Server.Implementations.Library .ThenByDescending(x => x.IsDefault) .ToList(); + MediaStream? stream = null; if (mode == SubtitlePlaybackMode.Default) { // Prefer embedded metadata over smart logic @@ -95,26 +84,27 @@ namespace Emby.Server.Implementations.Library return stream?.Index; } - private static IEnumerable GetSortedStreams(IEnumerable streams, MediaStreamType type, string[] languagePreferences) + private static IEnumerable GetSortedStreams(IEnumerable streams, MediaStreamType type, IReadOnlyList languagePreferences) { // Give some preference to external text subs for better performance - return streams.Where(i => i.Type == type) + return streams + .Where(i => i.Type == type) .OrderBy(i => - { - var index = FindIndex(languagePreferences, i.Language); + { + var index = languagePreferences.FindIndex(x => string.Equals(x, i.Language, StringComparison.OrdinalIgnoreCase)); - return index == -1 ? 100 : index; - }) - .ThenBy(i => GetBooleanOrderBy(i.IsDefault)) - .ThenBy(i => GetBooleanOrderBy(i.SupportsExternalStream)) - .ThenBy(i => GetBooleanOrderBy(i.IsTextSubtitleStream)) - .ThenBy(i => GetBooleanOrderBy(i.IsExternal)) - .ThenBy(i => i.Index); + return index == -1 ? 100 : index; + }) + .ThenBy(i => GetBooleanOrderBy(i.IsDefault)) + .ThenBy(i => GetBooleanOrderBy(i.SupportsExternalStream)) + .ThenBy(i => GetBooleanOrderBy(i.IsTextSubtitleStream)) + .ThenBy(i => GetBooleanOrderBy(i.IsExternal)) + .ThenBy(i => i.Index); } public static void SetSubtitleStreamScores( - List streams, - string[] preferredLanguages, + IReadOnlyList streams, + IReadOnlyList preferredLanguages, SubtitlePlaybackMode mode, string audioTrackLanguage) { @@ -123,15 +113,14 @@ namespace Emby.Server.Implementations.Library return; } - streams = GetSortedStreams(streams, MediaStreamType.Subtitle, preferredLanguages) - .ToList(); + var sortedStreams = GetSortedStreams(streams, MediaStreamType.Subtitle, preferredLanguages); var filteredStreams = new List(); if (mode == SubtitlePlaybackMode.Default) { // Prefer embedded metadata over smart logic - filteredStreams = streams.Where(s => s.IsForced || s.IsDefault) + filteredStreams = sortedStreams.Where(s => s.IsForced || s.IsDefault) .ToList(); } else if (mode == SubtitlePlaybackMode.Smart) @@ -139,54 +128,37 @@ namespace Emby.Server.Implementations.Library // Prefer smart logic over embedded metadata if (!preferredLanguages.Contains(audioTrackLanguage, StringComparison.OrdinalIgnoreCase)) { - filteredStreams = streams.Where(s => !s.IsForced && preferredLanguages.Contains(s.Language, StringComparison.OrdinalIgnoreCase)) + filteredStreams = sortedStreams.Where(s => !s.IsForced && preferredLanguages.Contains(s.Language, StringComparison.OrdinalIgnoreCase)) .ToList(); } } else if (mode == SubtitlePlaybackMode.Always) { // always load the most suitable full subtitles - filteredStreams = streams.Where(s => !s.IsForced) - .ToList(); + filteredStreams = sortedStreams.Where(s => !s.IsForced).ToList(); } else if (mode == SubtitlePlaybackMode.OnlyForced) { // always load the most suitable full subtitles - filteredStreams = streams.Where(s => s.IsForced).ToList(); + filteredStreams = sortedStreams.Where(s => s.IsForced).ToList(); } // load forced subs if we have found no suitable full subtitles - if (filteredStreams.Count == 0) - { - filteredStreams = streams - .Where(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase)) - .ToList(); - } + var iterStreams = filteredStreams.Count == 0 + ? sortedStreams.Where(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase)) + : filteredStreams; - foreach (var stream in filteredStreams) + foreach (var stream in iterStreams) { stream.Score = GetSubtitleScore(stream, preferredLanguages); } } - private static int FindIndex(string[] list, string value) - { - for (var i = 0; i < list.Length; i++) - { - if (string.Equals(list[i], value, StringComparison.OrdinalIgnoreCase)) - { - return i; - } - } - - return -1; - } - - private static int GetSubtitleScore(MediaStream stream, string[] languagePreferences) + private static int GetSubtitleScore(MediaStream stream, IReadOnlyList languagePreferences) { var values = new List(); - var index = FindIndex(languagePreferences, stream.Language); + var index = languagePreferences.FindIndex(x => string.Equals(x, stream.Language, StringComparison.OrdinalIgnoreCase)); values.Add(index == -1 ? 0 : 100 - index); diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 6a9a3077c..5df18f6de 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -312,7 +312,7 @@ namespace Emby.Server.Implementations.LiveTv { if (isVideo) { - mediaSource.MediaStreams.AddRange(new List + mediaSource.MediaStreams = new MediaStream[] { new MediaStream { @@ -329,11 +329,11 @@ namespace Emby.Server.Implementations.LiveTv // Set the index to -1 because we don't know the exact index of the audio stream within the container Index = -1 } - }); + }; } else { - mediaSource.MediaStreams.AddRange(new List + mediaSource.MediaStreams = new MediaStream[] { new MediaStream { @@ -341,7 +341,7 @@ namespace Emby.Server.Implementations.LiveTv // Set the index to -1 because we don't know the exact index of the audio stream within the container Index = -1 } - }); + }; } } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 532790019..e0eaa8e58 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -446,7 +446,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Path = url, Protocol = MediaProtocol.Udp, - MediaStreams = new List + MediaStreams = new MediaStream[] { new MediaStream { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index dd83f9a53..2a468e14d 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -170,7 +170,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { Path = path, Protocol = protocol, - MediaStreams = new List + MediaStreams = new MediaStream[] { new MediaStream { diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index dbd70342a..281dbb00b 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -147,13 +147,7 @@ namespace Emby.Server.Implementations.Localization threeletterNames = new[] { parts[0], parts[1] }; } - list.Add(new CultureDto - { - DisplayName = name, - Name = name, - ThreeLetterISOLanguageNames = threeletterNames, - TwoLetterISOLanguageName = twoCharName - }); + list.Add(new CultureDto(name, name, twoCharName, threeletterNames)); } } diff --git a/Jellyfin.Api/Controllers/SearchController.cs b/Jellyfin.Api/Controllers/SearchController.cs index 26acb4cdc..6fcd2ae40 100644 --- a/Jellyfin.Api/Controllers/SearchController.cs +++ b/Jellyfin.Api/Controllers/SearchController.cs @@ -121,11 +121,7 @@ namespace Jellyfin.Api.Controllers IsSports = isSports }); - return new SearchHintResult - { - TotalRecordCount = result.TotalRecordCount, - SearchHints = result.Items.Select(GetSearchHintResult).ToArray() - }; + return new SearchHintResult(result.Items.Select(GetSearchHintResult).ToArray(), result.TotalRecordCount); } /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index e63874f21..335222da9 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -134,7 +134,7 @@ namespace MediaBrowser.Controller.LiveTv { Id = Id.ToString("N", CultureInfo.InvariantCulture), Protocol = PathProtocol ?? MediaProtocol.File, - MediaStreams = new List(), + MediaStreams = Array.Empty(), Name = Name, Path = Path, RunTimeTicks = RunTimeTicks, diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 837bf0bb2..f7cc7841f 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -81,7 +81,7 @@ namespace MediaBrowser.Controller.Persistence /// The identifier. /// The streams. /// The cancellation token. - void SaveMediaStreams(Guid id, List streams, CancellationToken cancellationToken); + void SaveMediaStreams(Guid id, IReadOnlyList streams, CancellationToken cancellationToken); /// /// Gets the media attachments. diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs index 58b06ca1d..6e129246b 100644 --- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -115,7 +115,7 @@ namespace MediaBrowser.Model.Dlna return "DLNA.ORG_PN=" + orgPn + orgOp + orgCi + dlnaflags; } - public static List BuildVideoHeader( + public static IEnumerable BuildVideoHeader( DeviceProfile profile, string container, string videoCodec, diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index cf8465067..a678c54e7 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -675,7 +675,7 @@ namespace MediaBrowser.Model.Dlna return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString); } - private static List BuildParams(StreamInfo item, string accessToken) + private static IEnumerable BuildParams(StreamInfo item, string accessToken) { var list = new List(); @@ -805,34 +805,12 @@ namespace MediaBrowser.Model.Dlna return list; } - public List GetExternalSubtitles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, string baseUrl, string accessToken) - { - return GetExternalSubtitles(transcoderSupport, includeSelectedTrackOnly, false, baseUrl, accessToken); - } - - public List GetExternalSubtitles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, bool enableAllProfiles, string baseUrl, string accessToken) - { - var list = GetSubtitleProfiles(transcoderSupport, includeSelectedTrackOnly, enableAllProfiles, baseUrl, accessToken); - var newList = new List(); - - // First add the selected track - foreach (SubtitleStreamInfo stream in list) - { - if (stream.DeliveryMethod == SubtitleDeliveryMethod.External) - { - newList.Add(stream); - } - } - - return newList; - } - - public List GetSubtitleProfiles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, string baseUrl, string accessToken) + public IEnumerable GetSubtitleProfiles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, string baseUrl, string accessToken) { return GetSubtitleProfiles(transcoderSupport, includeSelectedTrackOnly, false, baseUrl, accessToken); } - public List GetSubtitleProfiles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, bool enableAllProfiles, string baseUrl, string accessToken) + public IEnumerable GetSubtitleProfiles(ITranscoderSupport transcoderSupport, bool includeSelectedTrackOnly, bool enableAllProfiles, string baseUrl, string accessToken) { var list = new List(); diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs index ec3b37efa..049e14333 100644 --- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs +++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Model.Dto public MediaSourceInfo() { Formats = Array.Empty(); - MediaStreams = new List(); + MediaStreams = Array.Empty(); MediaAttachments = Array.Empty(); RequiredHttpHeaders = new Dictionary(); SupportsTranscoding = true; @@ -88,7 +88,7 @@ namespace MediaBrowser.Model.Dto public Video3DFormat? Video3DFormat { get; set; } - public List MediaStreams { get; set; } + public IReadOnlyList MediaStreams { get; set; } public IReadOnlyList MediaAttachments { get; set; } diff --git a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs index e0e889f7d..d098669ba 100644 --- a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs +++ b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs @@ -1,7 +1,7 @@ -#nullable disable #pragma warning disable CS1591 using System; +using System.Collections.Generic; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Providers; @@ -19,16 +19,16 @@ namespace MediaBrowser.Model.Dto ContentTypeOptions = Array.Empty(); } - public ParentalRating[] ParentalRatingOptions { get; set; } + public IReadOnlyList ParentalRatingOptions { get; set; } - public CountryInfo[] Countries { get; set; } + public IReadOnlyList Countries { get; set; } - public CultureDto[] Cultures { get; set; } + public IReadOnlyList Cultures { get; set; } - public ExternalIdInfo[] ExternalIdInfos { get; set; } + public IReadOnlyList ExternalIdInfos { get; set; } - public string ContentType { get; set; } + public string? ContentType { get; set; } - public NameValuePair[] ContentTypeOptions { get; set; } + public IReadOnlyList ContentTypeOptions { get; set; } } } diff --git a/MediaBrowser.Model/Globalization/CultureDto.cs b/MediaBrowser.Model/Globalization/CultureDto.cs index 5246f87d9..d0cf2aad0 100644 --- a/MediaBrowser.Model/Globalization/CultureDto.cs +++ b/MediaBrowser.Model/Globalization/CultureDto.cs @@ -1,7 +1,6 @@ -#nullable disable #pragma warning disable CS1591 -using System; +using System.Collections.Generic; namespace MediaBrowser.Model.Globalization { @@ -10,39 +9,42 @@ namespace MediaBrowser.Model.Globalization /// public class CultureDto { - public CultureDto() + public CultureDto(string name, string displayName, string twoLetterISOLanguageName, IReadOnlyList threeLetterISOLanguageNames) { - ThreeLetterISOLanguageNames = Array.Empty(); + Name = name; + DisplayName = displayName; + TwoLetterISOLanguageName = twoLetterISOLanguageName; + ThreeLetterISOLanguageNames = threeLetterISOLanguageNames; } /// - /// Gets or sets the name. + /// Gets the name. /// /// The name. - public string Name { get; set; } + public string Name { get; } /// - /// Gets or sets the display name. + /// Gets the display name. /// /// The display name. - public string DisplayName { get; set; } + public string DisplayName { get; } /// - /// Gets or sets the name of the two letter ISO language. + /// Gets the name of the two letter ISO language. /// /// The name of the two letter ISO language. - public string TwoLetterISOLanguageName { get; set; } + public string TwoLetterISOLanguageName { get; } /// /// Gets the name of the three letter ISO language. /// /// The name of the three letter ISO language. - public string ThreeLetterISOLanguageName + public string? ThreeLetterISOLanguageName { get { var vals = ThreeLetterISOLanguageNames; - if (vals.Length > 0) + if (vals.Count > 0) { return vals[0]; } @@ -51,6 +53,6 @@ namespace MediaBrowser.Model.Globalization } } - public string[] ThreeLetterISOLanguageNames { get; set; } + public IReadOnlyList ThreeLetterISOLanguageNames { get; } } } diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs index 0f77d6b5b..7207795b0 100644 --- a/MediaBrowser.Model/IO/IFileSystem.cs +++ b/MediaBrowser.Model/IO/IFileSystem.cs @@ -199,6 +199,6 @@ namespace MediaBrowser.Model.IO void SetAttributes(string path, bool isHidden, bool readOnly); - List GetDrives(); + IEnumerable GetDrives(); } } diff --git a/MediaBrowser.Model/Search/SearchHintResult.cs b/MediaBrowser.Model/Search/SearchHintResult.cs index 92ba4139e..762a9a078 100644 --- a/MediaBrowser.Model/Search/SearchHintResult.cs +++ b/MediaBrowser.Model/Search/SearchHintResult.cs @@ -1,4 +1,5 @@ -#nullable disable +using System.Collections.Generic; + namespace MediaBrowser.Model.Search { /// @@ -7,15 +8,26 @@ namespace MediaBrowser.Model.Search public class SearchHintResult { /// - /// Gets or sets the search hints. + /// Initializes a new instance of the class. /// - /// The search hints. - public SearchHint[] SearchHints { get; set; } + /// The search hints. + /// The total record count. + public SearchHintResult(IReadOnlyList searchHints, int totalRecordCount) + { + SearchHints = searchHints; + TotalRecordCount = totalRecordCount; + } /// - /// Gets or sets the total record count. + /// Gets the search hints. + /// + /// The search hints. + public IReadOnlyList SearchHints { get; } + + /// + /// Gets the total record count. /// /// The total record count. - public int TotalRecordCount { get; set; } + public int TotalRecordCount { get; } } } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs index 9eb79c39d..f22965436 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs @@ -84,8 +84,6 @@ namespace MediaBrowser.Providers.MediaInfo /// The cancellation token. protected void Fetch(Audio audio, Model.MediaInfo.MediaInfo mediaInfo, CancellationToken cancellationToken) { - var mediaStreams = mediaInfo.MediaStreams; - audio.Container = mediaInfo.Container; audio.TotalBitrate = mediaInfo.Bitrate; @@ -97,7 +95,7 @@ namespace MediaBrowser.Providers.MediaInfo FetchDataFromTags(audio, mediaInfo); - _itemRepo.SaveMediaStreams(audio.Id, mediaStreams, cancellationToken); + _itemRepo.SaveMediaStreams(audio.Id, mediaInfo.MediaStreams, cancellationToken); } /// diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index d67e83ab4..77a849d00 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -172,7 +172,7 @@ namespace MediaBrowser.Providers.MediaInfo if (mediaInfo != null) { - mediaStreams = mediaInfo.MediaStreams; + mediaStreams = mediaInfo.MediaStreams.ToList(); mediaAttachments = mediaInfo.MediaAttachments; video.TotalBitrate = mediaInfo.Bitrate; @@ -202,7 +202,7 @@ namespace MediaBrowser.Providers.MediaInfo video.Container = mediaInfo.Container; - chapters = mediaInfo.Chapters == null ? Array.Empty() : mediaInfo.Chapters; + chapters = mediaInfo.Chapters ?? Array.Empty(); if (blurayInfo != null) { FetchBdInfo(video, ref chapters, mediaStreams, blurayInfo); @@ -246,7 +246,7 @@ namespace MediaBrowser.Providers.MediaInfo video.Height = videoStream?.Height ?? 0; video.Width = videoStream?.Width ?? 0; - video.DefaultVideoStreamIndex = videoStream == null ? (int?)null : videoStream.Index; + video.DefaultVideoStreamIndex = videoStream?.Index; video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle); diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/MediaStreamSelectorTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/MediaStreamSelectorTests.cs new file mode 100644 index 000000000..d59f2f4e5 --- /dev/null +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/MediaStreamSelectorTests.cs @@ -0,0 +1,30 @@ +using System; +using Emby.Server.Implementations.Library; +using MediaBrowser.Model.Entities; +using Xunit; + +namespace Jellyfin.Server.Implementations.Tests.Library; + +public class MediaStreamSelectorTests +{ + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetDefaultAudioStreamIndex_EmptyStreams_Null(bool preferDefaultTrack) + { + Assert.Null(MediaStreamSelector.GetDefaultAudioStreamIndex(Array.Empty(), Array.Empty(), preferDefaultTrack)); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetDefaultAudioStreamIndex_WithoutDefault_NotNull(bool preferDefaultTrack) + { + var streams = new[] + { + new MediaStream() + }; + + Assert.NotNull(MediaStreamSelector.GetDefaultAudioStreamIndex(streams, Array.Empty(), preferDefaultTrack)); + } +}