SubtitleResolver.cs 5.5 KB

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