aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs')
-rw-r--r--MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs160
1 files changed, 160 insertions, 0 deletions
diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs b/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs
new file mode 100644
index 000000000..cf14cfadc
--- /dev/null
+++ b/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs
@@ -0,0 +1,160 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Controller.Subtitles;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.MediaInfo
+{
+ public class SubtitleDownloader
+ {
+ private readonly ILogger _logger;
+ private readonly ISubtitleManager _subtitleManager;
+
+ public SubtitleDownloader(ILogger logger, ISubtitleManager subtitleManager)
+ {
+ _logger = logger;
+ _subtitleManager = subtitleManager;
+ }
+
+ public async Task<List<string>> DownloadSubtitles(Video video,
+ List<MediaStream> internalMediaStreams,
+ List<MediaStream> externalSubtitleStreams,
+ bool skipIfGraphicalSubtitlesPresent,
+ bool skipIfAudioTrackMatches,
+ IEnumerable<string> languages,
+ CancellationToken cancellationToken)
+ {
+ if (video.LocationType != LocationType.FileSystem ||
+ video.VideoType != VideoType.VideoFile)
+ {
+ return new List<string>();
+ }
+
+ VideoContentType mediaType;
+
+ if (video is Episode)
+ {
+ mediaType = VideoContentType.Episode;
+ }
+ else if (video is Movie)
+ {
+ mediaType = VideoContentType.Movie;
+ }
+ else
+ {
+ // These are the only supported types
+ return new List<string>();
+ }
+
+ var downloadedLanguages = new List<string>();
+
+ foreach (var lang in languages)
+ {
+ try
+ {
+ var downloaded = await DownloadSubtitles(video, internalMediaStreams, externalSubtitleStreams, skipIfGraphicalSubtitlesPresent, skipIfAudioTrackMatches, lang, mediaType, cancellationToken)
+ .ConfigureAwait(false);
+
+ if (downloaded)
+ {
+ downloadedLanguages.Add(lang);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error downloading subtitles", ex);
+ }
+ }
+
+ return downloadedLanguages;
+ }
+
+ private async Task<bool> DownloadSubtitles(Video video,
+ List<MediaStream> internalMediaStreams,
+ IEnumerable<MediaStream> externalSubtitleStreams,
+ bool skipIfGraphicalSubtitlesPresent,
+ bool skipIfAudioTrackMatches,
+ string language,
+ VideoContentType mediaType,
+ CancellationToken cancellationToken)
+ {
+ // There's already subtitles for this language
+ if (externalSubtitleStreams.Any(i => string.Equals(i.Language, language, StringComparison.OrdinalIgnoreCase)))
+ {
+ return false;
+ }
+
+ var audioStreams = internalMediaStreams.Where(i => i.Type == MediaStreamType.Audio).ToList();
+ var defaultAudioStreams = audioStreams.Where(i => i.IsDefault).ToList();
+
+ // If none are marked as default, just take a guess
+ if (defaultAudioStreams.Count == 0)
+ {
+ defaultAudioStreams = audioStreams.Take(1).ToList();
+ }
+
+ // There's already a default audio stream for this language
+ if (skipIfAudioTrackMatches &&
+ defaultAudioStreams.Any(i => string.Equals(i.Language, language, StringComparison.OrdinalIgnoreCase)))
+ {
+ return false;
+ }
+
+ // There's an internal subtitle stream for this language
+ if (skipIfGraphicalSubtitlesPresent &&
+ internalMediaStreams.Any(i => i.Type == MediaStreamType.Subtitle && i.IsGraphicalSubtitleStream && string.Equals(i.Language, language, StringComparison.OrdinalIgnoreCase)))
+ {
+ return false;
+ }
+
+ var request = new SubtitleSearchRequest
+ {
+ ContentType = mediaType,
+ IndexNumber = video.IndexNumber,
+ Language = language,
+ MediaPath = video.Path,
+ Name = video.Name,
+ ParentIndexNumber = video.ParentIndexNumber,
+ ProductionYear = video.ProductionYear,
+ ProviderIds = video.ProviderIds
+ };
+
+ var episode = video as Episode;
+
+ if (episode != null)
+ {
+ request.IndexNumberEnd = episode.IndexNumberEnd;
+ request.SeriesName = episode.SeriesName;
+ }
+
+ try
+ {
+ var searchResults = await _subtitleManager.SearchSubtitles(request, cancellationToken).ConfigureAwait(false);
+
+ var result = searchResults.FirstOrDefault();
+
+ if (result != null)
+ {
+ await _subtitleManager.DownloadSubtitles(video, result.Id, result.ProviderName, cancellationToken)
+ .ConfigureAwait(false);
+
+ return true;
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error downloading subtitles", ex);
+ }
+
+ return false;
+ }
+ }
+}