SubtitleResolver.cs 5.4 KB

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