SubtitleResolver.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using MediaBrowser.Model.Extensions;
  2. using MediaBrowser.Common.IO;
  3. using MediaBrowser.Controller.Entities;
  4. using MediaBrowser.Controller.Localization;
  5. using MediaBrowser.Controller.Providers;
  6. using MediaBrowser.Model.Entities;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Linq;
  11. using CommonIO;
  12. namespace MediaBrowser.Providers.MediaInfo
  13. {
  14. public class SubtitleResolver
  15. {
  16. private readonly ILocalizationManager _localization;
  17. private readonly IFileSystem _fileSystem;
  18. public SubtitleResolver(ILocalizationManager localization, IFileSystem fileSystem)
  19. {
  20. _localization = localization;
  21. _fileSystem = fileSystem;
  22. }
  23. public IEnumerable<MediaStream> GetExternalSubtitleStreams(Video video,
  24. int startIndex,
  25. IDirectoryService directoryService,
  26. bool clearCache)
  27. {
  28. var files = GetSubtitleFiles(video, directoryService, _fileSystem, clearCache);
  29. var streams = new List<MediaStream>();
  30. var videoFileNameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(video.Path);
  31. foreach (var file in files)
  32. {
  33. var fullName = file.FullName;
  34. var fileNameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(file);
  35. var codec = Path.GetExtension(fullName).ToLower().TrimStart('.');
  36. // If the subtitle file matches the video file name
  37. if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
  38. {
  39. streams.Add(new MediaStream
  40. {
  41. Index = startIndex++,
  42. Type = MediaStreamType.Subtitle,
  43. IsExternal = true,
  44. Path = fullName,
  45. Codec = codec
  46. });
  47. }
  48. else if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase))
  49. {
  50. var isForced = fullName.IndexOf(".forced.", StringComparison.OrdinalIgnoreCase) != -1 ||
  51. fullName.IndexOf(".foreign.", StringComparison.OrdinalIgnoreCase) != -1;
  52. // Support xbmc naming conventions - 300.spanish.srt
  53. var language = fileNameWithoutExtension
  54. .Replace(".forced", string.Empty, StringComparison.OrdinalIgnoreCase)
  55. .Replace(".foreign", string.Empty, StringComparison.OrdinalIgnoreCase)
  56. .Split('.')
  57. .LastOrDefault();
  58. // Try to translate to three character code
  59. // Be flexible and check against both the full and three character versions
  60. var culture = _localization.GetCultures()
  61. .FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.ThreeLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase));
  62. if (culture != null)
  63. {
  64. language = culture.ThreeLetterISOLanguageName;
  65. }
  66. streams.Add(new MediaStream
  67. {
  68. Index = startIndex++,
  69. Type = MediaStreamType.Subtitle,
  70. IsExternal = true,
  71. Path = fullName,
  72. Codec = codec,
  73. Language = language,
  74. IsForced = isForced
  75. });
  76. }
  77. }
  78. return streams;
  79. }
  80. private static IEnumerable<string> SubtitleExtensions
  81. {
  82. get
  83. {
  84. return new[] { ".srt", ".ssa", ".ass", ".sub" };
  85. }
  86. }
  87. public static IEnumerable<FileSystemMetadata> GetSubtitleFiles(Video video, IDirectoryService directoryService, IFileSystem fileSystem, bool clearCache)
  88. {
  89. var containingPath = video.ContainingFolderPath;
  90. if (string.IsNullOrEmpty(containingPath))
  91. {
  92. throw new ArgumentException(string.Format("Cannot search for items that don't have a path: {0} {1}", video.Name, video.Id));
  93. }
  94. var files = directoryService.GetFiles(containingPath, clearCache);
  95. var videoFileNameWithoutExtension = fileSystem.GetFileNameWithoutExtension(video.Path);
  96. return files.Where(i =>
  97. {
  98. if (!i.Attributes.HasFlag(FileAttributes.Directory) &&
  99. SubtitleExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase))
  100. {
  101. var fileNameWithoutExtension = fileSystem.GetFileNameWithoutExtension(i);
  102. if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
  103. {
  104. return true;
  105. }
  106. if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase))
  107. {
  108. return true;
  109. }
  110. }
  111. return false;
  112. });
  113. }
  114. }
  115. }