jellyfin-server/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs

225 lines
8.1 KiB
C#
Raw Normal View History

#nullable disable
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
2021-12-12 02:31:30 +00:00
using Jellyfin.Data.Enums;
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;
2020-09-07 11:20:39 +00:00
using MediaBrowser.Model.Globalization;
2015-03-31 16:24:16 +00:00
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Providers.MediaInfo
{
public class SubtitleScheduledTask : IScheduledTask
{
private readonly ILibraryManager _libraryManager;
private readonly IServerConfigurationManager _config;
private readonly ISubtitleManager _subtitleManager;
2020-06-06 00:15:56 +00:00
private readonly ILogger<SubtitleScheduledTask> _logger;
2020-03-26 21:49:54 +00:00
private readonly ILocalizationManager _localization;
public SubtitleScheduledTask(
ILibraryManager libraryManager,
IServerConfigurationManager config,
ISubtitleManager subtitleManager,
ILogger<SubtitleScheduledTask> logger,
2020-03-26 21:49:54 +00:00
ILocalizationManager localization)
{
_libraryManager = libraryManager;
_config = config;
_subtitleManager = subtitleManager;
_logger = logger;
2020-03-26 21:49:54 +00:00
_localization = localization;
}
2020-09-07 11:20:39 +00:00
public string Name => _localization.GetLocalizedString("TaskDownloadMissingSubtitles");
public string Description => _localization.GetLocalizedString("TaskDownloadMissingSubtitlesDescription");
public string Category => _localization.GetLocalizedString("TasksLibraryCategory");
public string Key => "DownloadSubtitles";
public bool IsHidden => false;
public bool IsEnabled => true;
public bool IsLogged => true;
2014-08-10 22:13:17 +00:00
private SubtitleOptions GetOptions()
{
return _config.GetConfiguration<SubtitleOptions>("subtitles");
}
2022-02-15 17:59:46 +00:00
/// <inheritdoc />
public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
{
2014-08-10 22:13:17 +00:00
var options = GetOptions();
2021-12-12 02:31:30 +00:00
var types = new[] { BaseItemKind.Episode, BaseItemKind.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;
2020-09-07 11:20:39 +00:00
bool skipIfEmbeddedSubtitlesPresent;
bool skipIfAudioTrackMatches;
2018-09-12 17:26:21 +00:00
2022-12-05 14:00:20 +00:00
if (libraryOptions.SubtitleDownloadLanguages is null)
2017-09-10 03:18:23 +00:00
{
2018-09-12 17:26:21 +00:00
subtitleDownloadLanguages = options.DownloadLanguages;
2020-09-07 11:20:39 +00:00
skipIfEmbeddedSubtitlesPresent = options.SkipIfEmbeddedSubtitlesPresent;
skipIfAudioTrackMatches = options.SkipIfAudioTrackMatches;
2017-09-10 03:18:23 +00:00
}
else
{
2018-09-12 17:26:21 +00:00
subtitleDownloadLanguages = libraryOptions.SubtitleDownloadLanguages;
2020-09-07 11:20:39 +00:00
skipIfEmbeddedSubtitlesPresent = libraryOptions.SkipSubtitlesIfEmbeddedSubtitlesPresent;
skipIfAudioTrackMatches = libraryOptions.SkipSubtitlesIfAudioTrackMatches;
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
};
2020-09-07 11:20:39 +00:00
if (skipIfAudioTrackMatches)
2018-09-12 17:26:21 +00:00
{
query.HasNoAudioTrackWithLanguage = lang;
}
2020-09-07 11:20:39 +00:00
if (skipIfEmbeddedSubtitlesPresent)
2018-09-12 17:26:21 +00:00
{
// 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;
2020-09-07 11:20:39 +00:00
bool skipIfEmbeddedSubtitlesPresent;
bool skipIfAudioTrackMatches;
bool requirePerfectMatch;
2018-09-12 17:26:21 +00:00
2022-12-05 14:00:20 +00:00
if (libraryOptions.SubtitleDownloadLanguages is null)
{
2018-09-12 17:26:21 +00:00
subtitleDownloadLanguages = options.DownloadLanguages;
2020-09-07 11:20:39 +00:00
skipIfEmbeddedSubtitlesPresent = options.SkipIfEmbeddedSubtitlesPresent;
skipIfAudioTrackMatches = options.SkipIfAudioTrackMatches;
requirePerfectMatch = options.RequirePerfectMatch;
2018-09-12 17:26:21 +00:00
}
else
{
subtitleDownloadLanguages = libraryOptions.SubtitleDownloadLanguages;
2020-09-07 11:20:39 +00:00
skipIfEmbeddedSubtitlesPresent = libraryOptions.SkipSubtitlesIfEmbeddedSubtitlesPresent;
skipIfAudioTrackMatches = libraryOptions.SkipSubtitlesIfAudioTrackMatches;
requirePerfectMatch = libraryOptions.RequirePerfectSubtitleMatch;
2018-09-12 17:26:21 +00:00
}
2016-10-05 07:15:29 +00:00
2020-09-07 11:20:39 +00:00
var downloadedLanguages = await new SubtitleDownloader(
_logger,
_subtitleManager).DownloadSubtitles(
video,
mediaStreams,
skipIfEmbeddedSubtitlesPresent,
skipIfAudioTrackMatches,
requirePerfectMatch,
subtitleDownloadLanguages,
libraryOptions.DisabledSubtitleFetchers,
libraryOptions.SubtitleFetcherOrder,
true,
2020-09-07 11:20:39 +00:00
cancellationToken).ConfigureAwait(false);
2018-09-12 17:26:21 +00:00
// 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;
}
2022-02-15 17:59:46 +00:00
/// <inheritdoc />
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
2020-09-07 11:20:39 +00:00
return new[]
{
// Every so often
2020-10-12 17:22:33 +00:00
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks }
};
}
}
}