< Summary - Jellyfin

Information
Class: Jellyfin.MediaEncoding.Hls.ScheduledTasks.KeyframeExtractionScheduledTask
Assembly: Jellyfin.MediaEncoding.Hls
File(s): /srv/git/jellyfin/src/Jellyfin.MediaEncoding.Hls/ScheduledTasks/KeyframeExtractionScheduledTask.cs
Line coverage
11%
Covered lines: 6
Uncovered lines: 46
Coverable lines: 52
Total lines: 111
Line coverage: 11.5%
Branch coverage
0%
Covered branches: 0
Total branches: 12
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%210%
.ctor(...)100%11100%
get_Name()100%210%
get_Key()100%210%
get_Description()100%210%
get_Category()100%210%
ExecuteAsync(...)0%156120%
GetDefaultTriggers()100%11100%

File(s)

/srv/git/jellyfin/src/Jellyfin.MediaEncoding.Hls/ScheduledTasks/KeyframeExtractionScheduledTask.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.IO;
 4using System.Linq;
 5using System.Threading;
 6using System.Threading.Tasks;
 7using Jellyfin.Data.Enums;
 8using Jellyfin.MediaEncoding.Hls.Extractors;
 9using MediaBrowser.Controller.Dto;
 10using MediaBrowser.Controller.Entities;
 11using MediaBrowser.Controller.Library;
 12using MediaBrowser.Model.Entities;
 13using MediaBrowser.Model.Globalization;
 14using MediaBrowser.Model.Tasks;
 15
 16namespace Jellyfin.MediaEncoding.Hls.ScheduledTasks;
 17
 18/// <inheritdoc />
 19public class KeyframeExtractionScheduledTask : IScheduledTask
 20{
 21    private const int Pagesize = 1000;
 22
 23    private readonly ILocalizationManager _localizationManager;
 24    private readonly ILibraryManager _libraryManager;
 25    private readonly IKeyframeExtractor[] _keyframeExtractors;
 026    private static readonly BaseItemKind[] _itemTypes = { BaseItemKind.Episode, BaseItemKind.Movie };
 27
 28    /// <summary>
 29    /// Initializes a new instance of the <see cref="KeyframeExtractionScheduledTask"/> class.
 30    /// </summary>
 31    /// <param name="localizationManager">An instance of the <see cref="ILocalizationManager"/> interface.</param>
 32    /// <param name="libraryManager">An instance of the <see cref="ILibraryManager"/> interface.</param>
 33    /// <param name="keyframeExtractors">The keyframe extractors.</param>
 34    public KeyframeExtractionScheduledTask(ILocalizationManager localizationManager, ILibraryManager libraryManager, IEn
 2235    {
 2236        _localizationManager = localizationManager;
 2237        _libraryManager = libraryManager;
 2238        _keyframeExtractors = keyframeExtractors.OrderByDescending(e => e.IsMetadataBased).ToArray();
 2239    }
 40
 41    /// <inheritdoc />
 042    public string Name => _localizationManager.GetLocalizedString("TaskKeyframeExtractor");
 43
 44    /// <inheritdoc />
 045    public string Key => "KeyframeExtraction";
 46
 47    /// <inheritdoc />
 048    public string Description => _localizationManager.GetLocalizedString("TaskKeyframeExtractorDescription");
 49
 50    /// <inheritdoc />
 051    public string Category => _localizationManager.GetLocalizedString("TasksLibraryCategory");
 52
 53    /// <inheritdoc />
 54    public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
 055    {
 056        var query = new InternalItemsQuery
 057        {
 058            MediaTypes = new[] { MediaType.Video },
 059            IsVirtualItem = false,
 060            IncludeItemTypes = _itemTypes,
 061            DtoOptions = new DtoOptions(true),
 062            SourceTypes = new[] { SourceType.Library },
 063            Recursive = true,
 064            Limit = Pagesize
 065        };
 66
 067        var numberOfVideos = _libraryManager.GetCount(query);
 68
 069        var startIndex = 0;
 070        var numComplete = 0;
 71
 072        while (startIndex < numberOfVideos)
 073        {
 074            query.StartIndex = startIndex;
 75
 076            var videos = _libraryManager.GetItemList(query);
 077            var currentPageCount = videos.Count;
 78            // TODO parallelize with Parallel.ForEach?
 079            for (var i = 0; i < currentPageCount; i++)
 080            {
 081                var video = videos[i];
 82                // Only local files supported
 083                if (video.IsFileProtocol && File.Exists(video.Path))
 084                {
 085                    for (var j = 0; j < _keyframeExtractors.Length; j++)
 086                    {
 087                        var extractor = _keyframeExtractors[j];
 88                        // The cache decorator will make sure to save them in the data dir
 089                        if (extractor.TryExtractKeyframes(video.Path, out _))
 090                        {
 091                            break;
 92                        }
 093                    }
 094                }
 95
 96                // Update progress
 097                numComplete++;
 098                double percent = (double)numComplete / numberOfVideos;
 099                progress.Report(100 * percent);
 0100            }
 101
 0102            startIndex += Pagesize;
 0103        }
 104
 0105        progress.Report(100);
 0106        return Task.CompletedTask;
 0107    }
 108
 109    /// <inheritdoc />
 22110    public IEnumerable<TaskTriggerInfo> GetDefaultTriggers() => Enumerable.Empty<TaskTriggerInfo>();
 111}