diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-05-17 00:24:10 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-05-17 00:24:10 -0400 |
| commit | c8e4889ac72b4b6fa01ffd0ccf293363ca5ce744 (patch) | |
| tree | d5e9f5400fc6282aeb0061280e0cfd6d51456c78 /MediaBrowser.Providers | |
| parent | 26aa47eefddf89a00ad64ab19af31b511142040d (diff) | |
add subtitle management page
Diffstat (limited to 'MediaBrowser.Providers')
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) + }); + } } } |
