123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- #pragma warning disable CS1591
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using MediaBrowser.Controller.Entities;
- using MediaBrowser.Controller.Providers;
- using MediaBrowser.Model.Entities;
- using MediaBrowser.Model.Globalization;
- namespace MediaBrowser.Providers.MediaInfo
- {
- public class SubtitleResolver
- {
- private readonly ILocalizationManager _localization;
- private static readonly HashSet<string> SubtitleExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
- {
- ".srt",
- ".ssa",
- ".ass",
- ".sub",
- ".smi",
- ".sami",
- ".vtt"
- };
- public SubtitleResolver(ILocalizationManager localization)
- {
- _localization = localization;
- }
- public List<MediaStream> GetExternalSubtitleStreams(
- Video video,
- int startIndex,
- IDirectoryService directoryService,
- bool clearCache)
- {
- var streams = new List<MediaStream>();
- if (!video.IsFileProtocol)
- {
- return streams;
- }
- AddExternalSubtitleStreams(streams, video.ContainingFolderPath, video.Path, startIndex, directoryService, clearCache);
- startIndex += streams.Count;
- string folder = video.GetInternalMetadataPath();
- if (!Directory.Exists(folder))
- {
- return streams;
- }
- try
- {
- AddExternalSubtitleStreams(streams, folder, video.Path, startIndex, directoryService, clearCache);
- }
- catch (IOException)
- {
- }
- return streams;
- }
- public List<string> GetExternalSubtitleFiles(
- Video video,
- IDirectoryService directoryService,
- bool clearCache)
- {
- var list = new List<string>();
- if (!video.IsFileProtocol)
- {
- return list;
- }
- var streams = GetExternalSubtitleStreams(video, 0, directoryService, clearCache);
- foreach (var stream in streams)
- {
- list.Add(stream.Path);
- }
- return list;
- }
- private void AddExternalSubtitleStreams(
- List<MediaStream> streams,
- string folder,
- string videoPath,
- int startIndex,
- IDirectoryService directoryService,
- bool clearCache)
- {
- var files = directoryService.GetFilePaths(folder, clearCache).OrderBy(i => i).ToArray();
- AddExternalSubtitleStreams(streams, videoPath, startIndex, files);
- }
- public void AddExternalSubtitleStreams(
- List<MediaStream> streams,
- string videoPath,
- int startIndex,
- string[] files)
- {
- var videoFileNameWithoutExtension = Path.GetFileNameWithoutExtension(videoPath);
- videoFileNameWithoutExtension = NormalizeFilenameForSubtitleComparison(videoFileNameWithoutExtension);
- foreach (var fullName in files)
- {
- var extension = Path.GetExtension(fullName);
- if (!SubtitleExtensions.Contains(extension))
- {
- continue;
- }
- var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fullName);
- fileNameWithoutExtension = NormalizeFilenameForSubtitleComparison(fileNameWithoutExtension);
- if (!string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase) &&
- !fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase))
- {
- continue;
- }
- var codec = Path.GetExtension(fullName).ToLowerInvariant().TrimStart('.');
- if (string.Equals(codec, "txt", StringComparison.OrdinalIgnoreCase))
- {
- codec = "srt";
- }
- // If the subtitle file matches the video file name
- if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
- {
- streams.Add(new MediaStream
- {
- Index = startIndex++,
- Type = MediaStreamType.Subtitle,
- IsExternal = true,
- Path = fullName,
- Codec = codec
- });
- }
- else if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase))
- {
- var isForced = fullName.IndexOf(".forced.", StringComparison.OrdinalIgnoreCase) != -1 ||
- fullName.IndexOf(".foreign.", StringComparison.OrdinalIgnoreCase) != -1;
- var isDefault = fullName.IndexOf(".default.", StringComparison.OrdinalIgnoreCase) != -1;
- // Support xbmc naming conventions - 300.spanish.srt
- var language = fileNameWithoutExtension
- .Replace(".forced", string.Empty, StringComparison.OrdinalIgnoreCase)
- .Replace(".foreign", string.Empty, StringComparison.OrdinalIgnoreCase)
- .Replace(".default", string.Empty, StringComparison.OrdinalIgnoreCase)
- .Split('.')
- .LastOrDefault();
- // Try to translate to three character code
- // Be flexible and check against both the full and three character versions
- var culture = _localization.FindLanguageInfo(language);
- if (culture != null)
- {
- language = culture.ThreeLetterISOLanguageName;
- }
- streams.Add(new MediaStream
- {
- Index = startIndex++,
- Type = MediaStreamType.Subtitle,
- IsExternal = true,
- Path = fullName,
- Codec = codec,
- Language = language,
- IsForced = isForced,
- IsDefault = isDefault
- });
- }
- }
- }
- private string NormalizeFilenameForSubtitleComparison(string filename)
- {
- // Try to account for sloppy file naming
- filename = filename.Replace("_", string.Empty, StringComparison.Ordinal);
- filename = filename.Replace(" ", string.Empty, StringComparison.Ordinal);
- // can't normalize this due to languages such as pt-br
- // filename = filename.Replace("-", string.Empty);
- // filename = filename.Replace(".", string.Empty);
- return filename;
- }
- }
- }
|