jellyfin/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs

228 lines
8.4 KiB
C#
Raw Normal View History

#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Model.Entities;
2015-03-31 16:24:16 +00:00
using MediaBrowser.Model.Providers;
2016-10-05 07:15:29 +00:00
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
2020-03-26 21:49:54 +00:00
using MediaBrowser.Model.Globalization;
namespace MediaBrowser.Providers.MediaInfo
{
public class SubtitleScheduledTask : IScheduledTask
{
private readonly ILibraryManager _libraryManager;
private readonly IServerConfigurationManager _config;
private readonly ISubtitleManager _subtitleManager;
2015-03-31 16:24:16 +00:00
private readonly IMediaSourceManager _mediaSourceManager;
2020-06-06 00:15:56 +00:00
private readonly ILogger<SubtitleScheduledTask> _logger;
2016-10-22 14:50:45 +00:00
private readonly IJsonSerializer _json;
2020-03-26 21:49:54 +00:00
private readonly ILocalizationManager _localization;
public SubtitleScheduledTask(
ILibraryManager libraryManager,
IJsonSerializer json,
IServerConfigurationManager config,
ISubtitleManager subtitleManager,
ILogger<SubtitleScheduledTask> logger,
2020-03-26 21:49:54 +00:00
IMediaSourceManager mediaSourceManager,
ILocalizationManager localization)
{
_libraryManager = libraryManager;
_config = config;
_subtitleManager = subtitleManager;
_logger = logger;
2015-03-31 16:24:16 +00:00
_mediaSourceManager = mediaSourceManager;
2016-10-05 07:15:29 +00:00
_json = json;
2020-03-26 21:49:54 +00:00
_localization = localization;
}
2014-08-10 22:13:17 +00:00
private SubtitleOptions GetOptions()
{
return _config.GetConfiguration<SubtitleOptions>("subtitles");
}
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{
2014-08-10 22:13:17 +00:00
var options = GetOptions();
2018-09-12 17:26:21 +00:00
var types = new[] { "Episode", "Movie" };
2016-10-05 07:15:29 +00:00
2017-09-10 03:18:23 +00:00
var dict = new Dictionary<Guid, BaseItem>();
2018-09-12 17:26:21 +00:00
foreach (var library in _libraryManager.RootFolder.Children.ToList())
2016-10-05 07:15:29 +00:00
{
2018-09-12 17:26:21 +00:00
var libraryOptions = _libraryManager.GetLibraryOptions(library);
2016-10-05 07:15:29 +00:00
2018-09-12 17:26:21 +00:00
string[] subtitleDownloadLanguages;
bool SkipIfEmbeddedSubtitlesPresent;
bool SkipIfAudioTrackMatches;
bool RequirePerfectMatch;
if (libraryOptions.SubtitleDownloadLanguages == null)
2017-09-10 03:18:23 +00:00
{
2018-09-12 17:26:21 +00:00
subtitleDownloadLanguages = options.DownloadLanguages;
SkipIfEmbeddedSubtitlesPresent = options.SkipIfEmbeddedSubtitlesPresent;
SkipIfAudioTrackMatches = options.SkipIfAudioTrackMatches;
RequirePerfectMatch = options.RequirePerfectMatch;
2017-09-10 03:18:23 +00:00
}
else
{
2018-09-12 17:26:21 +00:00
subtitleDownloadLanguages = libraryOptions.SubtitleDownloadLanguages;
SkipIfEmbeddedSubtitlesPresent = libraryOptions.SkipSubtitlesIfEmbeddedSubtitlesPresent;
SkipIfAudioTrackMatches = libraryOptions.SkipSubtitlesIfAudioTrackMatches;
RequirePerfectMatch = libraryOptions.RequirePerfectSubtitleMatch;
2017-09-10 03:18:23 +00:00
}
2018-09-12 17:26:21 +00:00
foreach (var lang in subtitleDownloadLanguages)
2017-09-10 03:18:23 +00:00
{
2018-09-12 17:26:21 +00:00
var query = new InternalItemsQuery
{
MediaTypes = new string[] { MediaType.Video },
IsVirtualItem = false,
IncludeItemTypes = types,
DtoOptions = new DtoOptions(true),
SourceTypes = new[] { SourceType.Library },
Parent = library,
Recursive = true
};
if (SkipIfAudioTrackMatches)
{
query.HasNoAudioTrackWithLanguage = lang;
}
if (SkipIfEmbeddedSubtitlesPresent)
{
// Exclude if it already has any subtitles of the same language
query.HasNoSubtitleTrackWithLanguage = lang;
}
else
{
// Exclude if it already has external subtitles of the same language
query.HasNoExternalSubtitleTrackWithLanguage = lang;
}
var videosByLanguage = _libraryManager.GetItemList(query);
foreach (var video in videosByLanguage)
{
dict[video.Id] = video;
}
2017-09-10 03:18:23 +00:00
}
}
var videos = dict.Values.ToList();
2016-10-25 19:02:04 +00:00
if (videos.Count == 0)
{
return;
}
var numComplete = 0;
foreach (var video in videos)
{
2017-09-10 03:18:23 +00:00
cancellationToken.ThrowIfCancellationRequested();
try
{
2017-09-10 03:18:23 +00:00
await DownloadSubtitles(video as Video, options, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
2018-12-20 12:11:26 +00:00
_logger.LogError(ex, "Error downloading subtitles for {Path}", video.Path);
}
// Update progress
numComplete++;
double percent = numComplete;
percent /= videos.Count;
progress.Report(100 * percent);
}
2016-10-05 07:15:29 +00:00
}
private async Task<bool> DownloadSubtitles(Video video, SubtitleOptions options, CancellationToken cancellationToken)
{
2018-09-12 17:26:21 +00:00
var mediaStreams = video.GetMediaStreams();
var libraryOptions = _libraryManager.GetLibraryOptions(video);
string[] subtitleDownloadLanguages;
bool SkipIfEmbeddedSubtitlesPresent;
bool SkipIfAudioTrackMatches;
bool RequirePerfectMatch;
if (libraryOptions.SubtitleDownloadLanguages == null)
{
2018-09-12 17:26:21 +00:00
subtitleDownloadLanguages = options.DownloadLanguages;
SkipIfEmbeddedSubtitlesPresent = options.SkipIfEmbeddedSubtitlesPresent;
SkipIfAudioTrackMatches = options.SkipIfAudioTrackMatches;
RequirePerfectMatch = options.RequirePerfectMatch;
}
else
{
subtitleDownloadLanguages = libraryOptions.SubtitleDownloadLanguages;
SkipIfEmbeddedSubtitlesPresent = libraryOptions.SkipSubtitlesIfEmbeddedSubtitlesPresent;
SkipIfAudioTrackMatches = libraryOptions.SkipSubtitlesIfAudioTrackMatches;
RequirePerfectMatch = libraryOptions.RequirePerfectSubtitleMatch;
}
2016-10-05 07:15:29 +00:00
2018-09-12 17:26:21 +00:00
var downloadedLanguages = await new SubtitleDownloader(_logger,
_subtitleManager)
.DownloadSubtitles(video,
mediaStreams,
SkipIfEmbeddedSubtitlesPresent,
SkipIfAudioTrackMatches,
RequirePerfectMatch,
subtitleDownloadLanguages,
libraryOptions.DisabledSubtitleFetchers,
libraryOptions.SubtitleFetcherOrder,
cancellationToken).ConfigureAwait(false);
// Rescan
if (downloadedLanguages.Count > 0)
{
await video.RefreshMetadata(cancellationToken).ConfigureAwait(false);
return false;
}
2016-10-05 07:15:29 +00:00
2018-09-12 17:26:21 +00:00
return true;
}
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
2019-01-07 23:27:46 +00:00
return new[] {
// Every so often
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
};
}
2020-03-26 21:49:54 +00:00
public string Name => _localization.GetLocalizedString("TaskDownloadMissingSubtitles");
2020-03-26 21:49:54 +00:00
public string Description => _localization.GetLocalizedString("TaskDownloadMissingSubtitlesDescription");
2020-03-29 21:46:19 +00:00
public string Category => _localization.GetLocalizedString("TasksLibraryCategory");
public string Key => "DownloadSubtitles";
public bool IsHidden => false;
public bool IsEnabled => true;
public bool IsLogged => true;
}
}