aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Providers
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-05-17 00:24:10 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-05-17 00:24:10 -0400
commitc8e4889ac72b4b6fa01ffd0ccf293363ca5ce744 (patch)
treed5e9f5400fc6282aeb0061280e0cfd6d51456c78 /MediaBrowser.Providers
parent26aa47eefddf89a00ad64ab19af31b511142040d (diff)
add subtitle management page
Diffstat (limited to 'MediaBrowser.Providers')
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs2
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs16
-rw-r--r--MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs7
-rw-r--r--MediaBrowser.Providers/Subtitles/SubtitleManager.cs148
4 files changed, 154 insertions, 19 deletions
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
index 9041d5a92..bbbcaeedf 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
@@ -142,7 +142,7 @@ namespace MediaBrowser.Providers.MediaInfo
var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json, _encodingManager, _fileSystem, _config, _subtitleManager);
- return prober.ProbeVideo(item, directoryService, cancellationToken);
+ return prober.ProbeVideo(item, directoryService, true, cancellationToken);
}
public Task<ItemUpdateType> FetchAudioInfo<T>(T item, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
index 5ce53378c..1cc04ed2a 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
@@ -60,7 +60,7 @@ namespace MediaBrowser.Providers.MediaInfo
_subtitleManager = subtitleManager;
}
- public async Task<ItemUpdateType> ProbeVideo<T>(T item, IDirectoryService directoryService, CancellationToken cancellationToken)
+ public async Task<ItemUpdateType> ProbeVideo<T>(T item, IDirectoryService directoryService, bool enableSubtitleDownloading, CancellationToken cancellationToken)
where T : Video
{
var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false);
@@ -105,7 +105,7 @@ namespace MediaBrowser.Providers.MediaInfo
cancellationToken.ThrowIfCancellationRequested();
- await Fetch(item, cancellationToken, result, isoMount, blurayDiscInfo, directoryService).ConfigureAwait(false);
+ await Fetch(item, cancellationToken, result, isoMount, blurayDiscInfo, directoryService, enableSubtitleDownloading).ConfigureAwait(false);
}
finally
@@ -160,7 +160,7 @@ namespace MediaBrowser.Providers.MediaInfo
return result;
}
- protected async Task Fetch(Video video, CancellationToken cancellationToken, InternalMediaInfoResult data, IIsoMount isoMount, BlurayDiscInfo blurayInfo, IDirectoryService directoryService)
+ protected async Task Fetch(Video video, CancellationToken cancellationToken, InternalMediaInfoResult data, IIsoMount isoMount, BlurayDiscInfo blurayInfo, IDirectoryService directoryService, bool enableSubtitleDownloading)
{
var mediaInfo = MediaEncoderHelpers.GetMediaInfo(data);
var mediaStreams = mediaInfo.MediaStreams;
@@ -208,7 +208,7 @@ namespace MediaBrowser.Providers.MediaInfo
FetchBdInfo(video, chapters, mediaStreams, blurayInfo);
}
- await AddExternalSubtitles(video, mediaStreams, directoryService, cancellationToken).ConfigureAwait(false);
+ await AddExternalSubtitles(video, mediaStreams, directoryService, enableSubtitleDownloading, cancellationToken).ConfigureAwait(false);
FetchWtvInfo(video, data);
@@ -416,13 +416,17 @@ namespace MediaBrowser.Providers.MediaInfo
/// </summary>
/// <param name="video">The video.</param>
/// <param name="currentStreams">The current streams.</param>
- private async Task AddExternalSubtitles(Video video, List<MediaStream> currentStreams, IDirectoryService directoryService, CancellationToken cancellationToken)
+ /// <param name="directoryService">The directory service.</param>
+ /// <param name="enableSubtitleDownloading">if set to <c>true</c> [enable subtitle downloading].</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task.</returns>
+ private async Task AddExternalSubtitles(Video video, List<MediaStream> currentStreams, IDirectoryService directoryService, bool enableSubtitleDownloading, CancellationToken cancellationToken)
{
var subtitleResolver = new SubtitleResolver(_localization);
var externalSubtitleStreams = subtitleResolver.GetExternalSubtitleStreams(video, currentStreams.Count, directoryService, false).ToList();
- if ((_config.Configuration.SubtitleOptions.DownloadEpisodeSubtitles &&
+ if (enableSubtitleDownloading && (_config.Configuration.SubtitleOptions.DownloadEpisodeSubtitles &&
video is Episode) ||
(_config.Configuration.SubtitleOptions.DownloadMovieSubtitles &&
video is Movie))
diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs b/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs
index cf14cfadc..0df2b24f5 100644
--- a/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs
+++ b/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs
@@ -124,7 +124,10 @@ namespace MediaBrowser.Providers.MediaInfo
Name = video.Name,
ParentIndexNumber = video.ParentIndexNumber,
ProductionYear = video.ProductionYear,
- ProviderIds = video.ProviderIds
+ ProviderIds = video.ProviderIds,
+
+ // Stop as soon as we find something
+ SearchAllProviders = false
};
var episode = video as Episode;
@@ -143,7 +146,7 @@ namespace MediaBrowser.Providers.MediaInfo
if (result != null)
{
- await _subtitleManager.DownloadSubtitles(video, result.Id, result.ProviderName, cancellationToken)
+ await _subtitleManager.DownloadSubtitles(video, result.Id, cancellationToken)
.ConfigureAwait(false);
return true;
diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs
index 2d5445653..08499a20b 100644
--- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs
+++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs
@@ -1,8 +1,10 @@
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Model.Entities;
@@ -23,12 +25,16 @@ namespace MediaBrowser.Providers.Subtitles
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly ILibraryMonitor _monitor;
+ private readonly ILibraryManager _libraryManager;
+ private readonly IItemRepository _itemRepo;
- public SubtitleManager(ILogger logger, IFileSystem fileSystem, ILibraryMonitor monitor)
+ public SubtitleManager(ILogger logger, IFileSystem fileSystem, ILibraryMonitor monitor, ILibraryManager libraryManager, IItemRepository itemRepo)
{
_logger = logger;
_fileSystem = fileSystem;
_monitor = monitor;
+ _libraryManager = libraryManager;
+ _itemRepo = itemRepo;
}
public void AddParts(IEnumerable<ISubtitleProvider> subtitleProviders)
@@ -38,15 +44,45 @@ namespace MediaBrowser.Providers.Subtitles
public async Task<IEnumerable<RemoteSubtitleInfo>> SearchSubtitles(SubtitleSearchRequest request, CancellationToken cancellationToken)
{
+ var contentType = request.ContentType;
var providers = _subtitleProviders
- .Where(i => i.SupportedMediaTypes.Contains(request.ContentType))
+ .Where(i => i.SupportedMediaTypes.Contains(contentType))
.ToList();
+ // If not searching all, search one at a time until something is found
+ if (!request.SearchAllProviders)
+ {
+ foreach (var provider in providers)
+ {
+ try
+ {
+ var searchResults = await provider.Search(request, cancellationToken).ConfigureAwait(false);
+
+ var list = searchResults.ToList();
+
+ if (list.Count > 0)
+ {
+ Normalize(list);
+ return list;
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error downloading subtitles from {0}", ex, provider.Name);
+ }
+ }
+ return new List<RemoteSubtitleInfo>();
+ }
+
var tasks = providers.Select(async i =>
{
try
{
- return await i.Search(request, cancellationToken).ConfigureAwait(false);
+ var searchResults = await i.Search(request, cancellationToken).ConfigureAwait(false);
+
+ var list = searchResults.ToList();
+ Normalize(list);
+ return list;
}
catch (Exception ex)
{
@@ -62,17 +98,21 @@ namespace MediaBrowser.Providers.Subtitles
public async Task DownloadSubtitles(Video video,
string subtitleId,
- string providerName,
CancellationToken cancellationToken)
{
- var provider = _subtitleProviders.First(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase));
-
- var response = await provider.GetSubtitles(subtitleId, cancellationToken).ConfigureAwait(false);
+ var response = await GetRemoteSubtitles(subtitleId, cancellationToken).ConfigureAwait(false);
using (var stream = response.Stream)
{
- var savePath = Path.Combine(Path.GetDirectoryName(video.Path),
- Path.GetFileNameWithoutExtension(video.Path) + "." + response.Language.ToLower() + "." + response.Format.ToLower());
+ var savePath = Path.Combine(Path.GetDirectoryName(video.Path),
+ Path.GetFileNameWithoutExtension(video.Path) + "." + response.Language.ToLower());
+
+ if (response.IsForced)
+ {
+ savePath += ".forced";
+ }
+
+ savePath += "." + response.Format.ToLower();
_logger.Info("Saving subtitles to {0}", savePath);
@@ -139,5 +179,93 @@ namespace MediaBrowser.Providers.Subtitles
return SearchSubtitles(request, cancellationToken);
}
+
+ private void Normalize(IEnumerable<RemoteSubtitleInfo> subtitles)
+ {
+ foreach (var sub in subtitles)
+ {
+ sub.Id = GetProviderId(sub.ProviderName) + "_" + sub.Id;
+ }
+ }
+
+ private string GetProviderId(string name)
+ {
+ return name.ToLower().GetMD5().ToString("N");
+ }
+
+ private ISubtitleProvider GetProvider(string id)
+ {
+ return _subtitleProviders.First(i => string.Equals(id, GetProviderId(i.Name)));
+ }
+
+ public Task DeleteSubtitles(string itemId, int index)
+ {
+ var stream = _itemRepo.GetMediaStreams(new MediaStreamQuery
+ {
+ Index = index,
+ ItemId = new Guid(itemId),
+ Type = MediaStreamType.Subtitle
+
+ }).First();
+
+ var path = stream.Path;
+ _monitor.ReportFileSystemChangeBeginning(path);
+
+ try
+ {
+ File.Delete(path);
+ }
+ finally
+ {
+ _monitor.ReportFileSystemChangeComplete(path, false);
+ }
+
+ return _libraryManager.GetItemById(itemId).RefreshMetadata(new MetadataRefreshOptions
+ {
+ ImageRefreshMode = ImageRefreshMode.ValidationOnly,
+ MetadataRefreshMode = MetadataRefreshMode.ValidationOnly
+
+ }, CancellationToken.None);
+ }
+
+ public Task<SubtitleResponse> GetRemoteSubtitles(string id, CancellationToken cancellationToken)
+ {
+ var parts = id.Split(new[] { '_' }, 2);
+
+ var provider = GetProvider(parts.First());
+ id = parts.Last();
+
+ return provider.GetSubtitles(id, cancellationToken);
+ }
+
+ public IEnumerable<SubtitleProviderInfo> GetProviders(string itemId)
+ {
+ var video = _libraryManager.GetItemById(itemId) as Video;
+ 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<SubtitleProviderInfo>();
+ }
+
+ var providers = _subtitleProviders
+ .Where(i => i.SupportedMediaTypes.Contains(mediaType))
+ .ToList();
+
+ return providers.Select(i => new SubtitleProviderInfo
+ {
+ Name = i.Name,
+ Id = GetProviderId(i.Name)
+ });
+ }
}
}