diff options
| author | Bond-009 <bond.009@outlook.com> | 2023-01-07 19:30:55 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-07 11:30:55 -0700 |
| commit | 769c48c629bae859ba713d66b1a55f35aca708b6 (patch) | |
| tree | c8b342a54559b711fcaacd88a1fc05a24decfdd3 | |
| parent | 770c8c89028ee9774d00eb385bae56cfceb212e6 (diff) | |
Deduplicate media stream ordering code (#9014)
| -rw-r--r-- | Emby.Server.Implementations/Library/MediaStreamSelector.cs | 54 | ||||
| -rw-r--r-- | jellyfin.ruleset | 2 | ||||
| -rw-r--r-- | tests/Jellyfin.Server.Implementations.Tests/Library/MediaStreamSelectorTests.cs | 64 |
3 files changed, 78 insertions, 42 deletions
diff --git a/Emby.Server.Implementations/Library/MediaStreamSelector.cs b/Emby.Server.Implementations/Library/MediaStreamSelector.cs index 74c53b2da..6aef87c52 100644 --- a/Emby.Server.Implementations/Library/MediaStreamSelector.cs +++ b/Emby.Server.Implementations/Library/MediaStreamSelector.cs @@ -89,17 +89,7 @@ namespace Emby.Server.Implementations.Library // Give some preference to external text subs for better performance return streams .Where(i => i.Type == type) - .OrderBy(i => - { - 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); + .OrderByDescending(i => GetStreamScore(i, languagePreferences)); } public static void SetSubtitleStreamScores( @@ -113,9 +103,9 @@ namespace Emby.Server.Implementations.Library return; } - var sortedStreams = GetSortedStreams(streams, MediaStreamType.Subtitle, preferredLanguages); + var sortedStreams = GetSortedStreams(streams, MediaStreamType.Subtitle, preferredLanguages).ToList(); - var filteredStreams = new List<MediaStream>(); + List<MediaStream>? filteredStreams = null; if (mode == SubtitlePlaybackMode.Default) { @@ -144,46 +134,26 @@ namespace Emby.Server.Implementations.Library } // load forced subs if we have found no suitable full subtitles - var iterStreams = filteredStreams.Count == 0 + var iterStreams = filteredStreams is null || filteredStreams.Count == 0 ? sortedStreams.Where(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase)) : filteredStreams; foreach (var stream in iterStreams) { - stream.Score = GetSubtitleScore(stream, preferredLanguages); + stream.Score = GetStreamScore(stream, preferredLanguages); } } - private static int GetSubtitleScore(MediaStream stream, IReadOnlyList<string> languagePreferences) + internal static int GetStreamScore(MediaStream stream, IReadOnlyList<string> languagePreferences) { - var values = new List<int>(); - var index = languagePreferences.FindIndex(x => string.Equals(x, stream.Language, StringComparison.OrdinalIgnoreCase)); - - values.Add(index == -1 ? 0 : 100 - index); - - values.Add(stream.IsForced ? 1 : 0); - values.Add(stream.IsDefault ? 1 : 0); - values.Add(stream.SupportsExternalStream ? 1 : 0); - values.Add(stream.IsTextSubtitleStream ? 1 : 0); - values.Add(stream.IsExternal ? 1 : 0); - - values.Reverse(); - var scale = 1; - var score = 0; - - foreach (var value in values) - { - score += scale * (value + 1); - scale *= 10; - } - + var score = index == -1 ? 1 : 101 - index; + score = (score * 10) + (stream.IsForced ? 2 : 1); + score = (score * 10) + (stream.IsDefault ? 2 : 1); + score = (score * 10) + (stream.SupportsExternalStream ? 2 : 1); + score = (score * 10) + (stream.IsTextSubtitleStream ? 2 : 1); + score = (score * 10) + (stream.IsExternal ? 2 : 1); return score; } - - private static int GetBooleanOrderBy(bool value) - { - return value ? 0 : 1; - } } } diff --git a/jellyfin.ruleset b/jellyfin.ruleset index 3fda774b8..b611caa11 100644 --- a/jellyfin.ruleset +++ b/jellyfin.ruleset @@ -93,6 +93,8 @@ <Rule Id="CA1845" Action="Error" /> <!-- error on CA1849: Call async methods when in an async method --> <Rule Id="CA1849" Action="Error" /> + <!-- error on CA1851: Possible multiple enumerations of IEnumerable collection --> + <Rule Id="CA1851" Action="Error" /> <!-- error on CA2016: Forward the CancellationToken parameter to methods that take one or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token --> <Rule Id="CA2016" Action="Error" /> diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/MediaStreamSelectorTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/MediaStreamSelectorTests.cs index 538010f6c..07feae587 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/MediaStreamSelectorTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/MediaStreamSelectorTests.cs @@ -51,4 +51,68 @@ public class MediaStreamSelectorTests Assert.Equal(expectedIndex, MediaStreamSelector.GetDefaultAudioStreamIndex(streams, preferredLanguages, preferDefaultTrack)); } + + public static TheoryData<MediaStream, int> GetStreamScore_MediaStream_TestData() + { + var data = new TheoryData<MediaStream, int>(); + + data.Add(new MediaStream(), 111111); + data.Add( + new MediaStream() + { + Language = "eng" + }, + 10111111); + data.Add( + new MediaStream() + { + Language = "fre" + }, + 10011111); + data.Add( + new MediaStream() + { + IsForced = true + }, + 121111); + data.Add( + new MediaStream() + { + IsDefault = true + }, + 112111); + data.Add( + new MediaStream() + { + SupportsExternalStream = true + }, + 111211); + data.Add( + new MediaStream() + { + IsExternal = true + }, + 111112); + data.Add( + new MediaStream() + { + Language = "eng", + IsForced = true, + IsDefault = true, + SupportsExternalStream = true, + IsExternal = true + }, + 10122212); + + return data; + } + + [Theory] + [MemberData(nameof(GetStreamScore_MediaStream_TestData))] + public void GetStreamScore_MediaStream_CorrectScore(MediaStream stream, int expectedScore) + { + var languagePref = new[] { "eng", "fre" }; + + Assert.Equal(expectedScore, MediaStreamSelector.GetStreamScore(stream, languagePref)); + } } |
