diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs
index dd4a5f061c..ba284187ed 100644
--- a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs
+++ b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs
@@ -1,7 +1,3 @@
-#nullable disable
-
-#pragma warning disable CA1002, CS1591
-
using System;
using System.Collections.Generic;
using System.IO;
@@ -12,15 +8,30 @@ using MediaBrowser.Model.Globalization;
namespace MediaBrowser.Providers.MediaInfo
{
+ ///
+ /// Resolves external subtitles for videos.
+ ///
public class SubtitleResolver
{
private readonly ILocalizationManager _localization;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The localization manager.
public SubtitleResolver(ILocalizationManager localization)
{
_localization = localization;
}
+ ///
+ /// Retrieves the external subtitle streams for the provided video.
+ ///
+ /// The video to search from.
+ /// The stream index to start adding subtitle streams at.
+ /// The directory service to search for files.
+ /// True if the directory service cache should be cleared before searching.
+ /// The external subtitle streams located.
public List GetExternalSubtitleStreams(
Video video,
int startIndex,
@@ -56,6 +67,13 @@ namespace MediaBrowser.Providers.MediaInfo
return streams;
}
+ ///
+ /// Locates the external subtitle files for the provided video.
+ ///
+ /// The video to search from.
+ /// The directory service to search for files.
+ /// True if the directory service cache should be cleared before searching.
+ /// The external subtitle file paths located.
public IEnumerable GetExternalSubtitleFiles(
Video video,
IDirectoryService directoryService,
@@ -74,6 +92,13 @@ namespace MediaBrowser.Providers.MediaInfo
}
}
+ ///
+ /// Extracts the subtitle files from the provided list and adds them to the list of streams.
+ ///
+ /// The list of streams to add external subtitles to.
+ /// The path to the video file.
+ /// The stream index to start adding subtitle streams at.
+ /// The files to add if they are subtitles.
public void AddExternalSubtitleStreams(
List streams,
string videoPath,
@@ -120,6 +145,12 @@ namespace MediaBrowser.Providers.MediaInfo
while (languageSpan.Length > 0)
{
var lastDot = languageSpan.LastIndexOf('.');
+ if (lastDot < videoFileNameWithoutExtension.Length)
+ {
+ languageSpan = ReadOnlySpan.Empty;
+ break;
+ }
+
var currentSlice = languageSpan[lastDot..];
if (currentSlice.Equals(".default", StringComparison.OrdinalIgnoreCase)
|| currentSlice.Equals(".forced", StringComparison.OrdinalIgnoreCase)
@@ -133,12 +164,19 @@ namespace MediaBrowser.Providers.MediaInfo
break;
}
- // Try to translate to three character code
- // Be flexible and check against both the full and three character versions
var language = languageSpan.ToString();
- var culture = _localization.FindLanguageInfo(language);
+ if (string.IsNullOrWhiteSpace(language))
+ {
+ language = null;
+ }
+ else
+ {
+ // Try to translate to three character code
+ // Be flexible and check against both the full and three character versions
+ var culture = _localization.FindLanguageInfo(language);
- language = culture == null ? language : culture.ThreeLetterISOLanguageName;
+ language = culture == null ? language : culture.ThreeLetterISOLanguageName;
+ }
mediaStream = new MediaStream
{
diff --git a/tests/Jellyfin.Providers.Tests/MediaInfo/SubtitleResolverTests.cs b/tests/Jellyfin.Providers.Tests/MediaInfo/SubtitleResolverTests.cs
index c289a71129..33da277e35 100644
--- a/tests/Jellyfin.Providers.Tests/MediaInfo/SubtitleResolverTests.cs
+++ b/tests/Jellyfin.Providers.Tests/MediaInfo/SubtitleResolverTests.cs
@@ -80,6 +80,37 @@ namespace Jellyfin.Providers.Tests.MediaInfo
}
}
+ [Theory]
+ [InlineData("/video/My Video.mkv", "/video/My Video.srt", "srt", null, false, false)]
+ [InlineData("/video/My.Video.mkv", "/video/My.Video.srt", "srt", null, false, false)]
+ [InlineData("/video/My.Video.mkv", "/video/My.Video.foreign.srt", "srt", null, true, false)]
+ [InlineData("/video/My Video.mkv", "/video/My Video.forced.srt", "srt", null, true, false)]
+ [InlineData("/video/My.Video.mkv", "/video/My.Video.default.srt", "srt", null, false, true)]
+ [InlineData("/video/My.Video.mkv", "/video/My.Video.forced.default.srt", "srt", null, true, true)]
+ [InlineData("/video/My.Video.mkv", "/video/My.Video.en.srt", "srt", "en", false, false)]
+ [InlineData("/video/My.Video.mkv", "/video/My.Video.default.en.srt", "srt", "en", false, true)]
+ [InlineData("/video/My.Video.mkv", "/video/My.Video.default.forced.en.srt", "srt", "en", true, true)]
+ [InlineData("/video/My.Video.mkv", "/video/My.Video.en.default.forced.srt", "srt", "en", true, true)]
+ public void AddExternalSubtitleStreams_GivenSingleFile_ReturnsExpectedSubtitle(string videoPath, string file, string codec, string? language, bool isForced, bool isDefault)
+ {
+ var streams = new List();
+ var expected = CreateMediaStream(file, codec, language, 0, isForced, isDefault);
+
+ new SubtitleResolver(Mock.Of()).AddExternalSubtitleStreams(streams, videoPath, 0, new[] { file });
+
+ Assert.Single(streams);
+
+ var actual = streams[0];
+
+ Assert.Equal(expected.Index, actual.Index);
+ Assert.Equal(expected.Type, actual.Type);
+ Assert.Equal(expected.IsExternal, actual.IsExternal);
+ Assert.Equal(expected.Path, actual.Path);
+ Assert.Equal(expected.IsDefault, actual.IsDefault);
+ Assert.Equal(expected.IsForced, actual.IsForced);
+ Assert.Equal(expected.Language, actual.Language);
+ }
+
private static MediaStream CreateMediaStream(string path, string codec, string? language, int index, bool isForced = false, bool isDefault = false)
{
return new ()