Merge pull request #6915 from 1337joe/subtitle-parsing-fix

pull/6914/head
Cody Robibero 3 years ago committed by GitHub
commit 80c7119537
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,7 +1,3 @@
#nullable disable
#pragma warning disable CA1002, CS1591
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -12,15 +8,30 @@ using MediaBrowser.Model.Globalization;
namespace MediaBrowser.Providers.MediaInfo namespace MediaBrowser.Providers.MediaInfo
{ {
/// <summary>
/// Resolves external subtitles for videos.
/// </summary>
public class SubtitleResolver public class SubtitleResolver
{ {
private readonly ILocalizationManager _localization; private readonly ILocalizationManager _localization;
/// <summary>
/// Initializes a new instance of the <see cref="SubtitleResolver"/> class.
/// </summary>
/// <param name="localization">The localization manager.</param>
public SubtitleResolver(ILocalizationManager localization) public SubtitleResolver(ILocalizationManager localization)
{ {
_localization = localization; _localization = localization;
} }
/// <summary>
/// Retrieves the external subtitle streams for the provided video.
/// </summary>
/// <param name="video">The video to search from.</param>
/// <param name="startIndex">The stream index to start adding subtitle streams at.</param>
/// <param name="directoryService">The directory service to search for files.</param>
/// <param name="clearCache">True if the directory service cache should be cleared before searching.</param>
/// <returns>The external subtitle streams located.</returns>
public List<MediaStream> GetExternalSubtitleStreams( public List<MediaStream> GetExternalSubtitleStreams(
Video video, Video video,
int startIndex, int startIndex,
@ -56,6 +67,13 @@ namespace MediaBrowser.Providers.MediaInfo
return streams; return streams;
} }
/// <summary>
/// Locates the external subtitle files for the provided video.
/// </summary>
/// <param name="video">The video to search from.</param>
/// <param name="directoryService">The directory service to search for files.</param>
/// <param name="clearCache">True if the directory service cache should be cleared before searching.</param>
/// <returns>The external subtitle file paths located.</returns>
public IEnumerable<string> GetExternalSubtitleFiles( public IEnumerable<string> GetExternalSubtitleFiles(
Video video, Video video,
IDirectoryService directoryService, IDirectoryService directoryService,
@ -74,6 +92,13 @@ namespace MediaBrowser.Providers.MediaInfo
} }
} }
/// <summary>
/// Extracts the subtitle files from the provided list and adds them to the list of streams.
/// </summary>
/// <param name="streams">The list of streams to add external subtitles to.</param>
/// <param name="videoPath">The path to the video file.</param>
/// <param name="startIndex">The stream index to start adding subtitle streams at.</param>
/// <param name="files">The files to add if they are subtitles.</param>
public void AddExternalSubtitleStreams( public void AddExternalSubtitleStreams(
List<MediaStream> streams, List<MediaStream> streams,
string videoPath, string videoPath,
@ -120,6 +145,12 @@ namespace MediaBrowser.Providers.MediaInfo
while (languageSpan.Length > 0) while (languageSpan.Length > 0)
{ {
var lastDot = languageSpan.LastIndexOf('.'); var lastDot = languageSpan.LastIndexOf('.');
if (lastDot < videoFileNameWithoutExtension.Length)
{
languageSpan = ReadOnlySpan<char>.Empty;
break;
}
var currentSlice = languageSpan[lastDot..]; var currentSlice = languageSpan[lastDot..];
if (currentSlice.Equals(".default", StringComparison.OrdinalIgnoreCase) if (currentSlice.Equals(".default", StringComparison.OrdinalIgnoreCase)
|| currentSlice.Equals(".forced", StringComparison.OrdinalIgnoreCase) || currentSlice.Equals(".forced", StringComparison.OrdinalIgnoreCase)
@ -133,12 +164,19 @@ namespace MediaBrowser.Providers.MediaInfo
break; 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 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 mediaStream = new MediaStream
{ {

@ -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<MediaStream>();
var expected = CreateMediaStream(file, codec, language, 0, isForced, isDefault);
new SubtitleResolver(Mock.Of<ILocalizationManager>()).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) private static MediaStream CreateMediaStream(string path, string codec, string? language, int index, bool isForced = false, bool isDefault = false)
{ {
return new () return new ()

Loading…
Cancel
Save