< 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
12%
Covered lines: 6
Uncovered lines: 44
Coverable lines: 50
Total lines: 107
Line coverage: 12%
Branch coverage
0%
Covered branches: 0
Total branches: 10
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%110100%
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.Globalization;
 13using MediaBrowser.Model.Tasks;
 14
 15namespace Jellyfin.MediaEncoding.Hls.ScheduledTasks;
 16
 17/// <inheritdoc />
 18public class KeyframeExtractionScheduledTask : IScheduledTask
 19{
 20    private const int Pagesize = 1000;
 21
 22    private readonly ILocalizationManager _localizationManager;
 23    private readonly ILibraryManager _libraryManager;
 24    private readonly IKeyframeExtractor[] _keyframeExtractors;
 025    private static readonly BaseItemKind[] _itemTypes = [BaseItemKind.Episode, BaseItemKind.Movie];
 26
 27    /// <summary>
 28    /// Initializes a new instance of the <see cref="KeyframeExtractionScheduledTask"/> class.
 29    /// </summary>
 30    /// <param name="localizationManager">An instance of the <see cref="ILocalizationManager"/> interface.</param>
 31    /// <param name="libraryManager">An instance of the <see cref="ILibraryManager"/> interface.</param>
 32    /// <param name="keyframeExtractors">The keyframe extractors.</param>
 33    public KeyframeExtractionScheduledTask(ILocalizationManager localizationManager, ILibraryManager libraryManager, IEn
 2134    {
 2135        _localizationManager = localizationManager;
 2136        _libraryManager = libraryManager;
 2137        _keyframeExtractors = keyframeExtractors.OrderByDescending(e => e.IsMetadataBased).ToArray();
 2138    }
 39
 40    /// <inheritdoc />
 041    public string Name => _localizationManager.GetLocalizedString("TaskKeyframeExtractor");
 42
 43    /// <inheritdoc />
 044    public string Key => "KeyframeExtraction";
 45
 46    /// <inheritdoc />
 047    public string Description => _localizationManager.GetLocalizedString("TaskKeyframeExtractorDescription");
 48
 49    /// <inheritdoc />
 050    public string Category => _localizationManager.GetLocalizedString("TasksLibraryCategory");
 51
 52    /// <inheritdoc />
 53    public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
 054    {
 055        var query = new InternalItemsQuery
 056        {
 057            MediaTypes = [MediaType.Video],
 058            IsVirtualItem = false,
 059            IncludeItemTypes = _itemTypes,
 060            DtoOptions = new DtoOptions(true),
 061            SourceTypes = [SourceType.Library],
 062            Recursive = true,
 063            Limit = Pagesize
 064        };
 65
 066        var numberOfVideos = _libraryManager.GetCount(query);
 67
 068        var startIndex = 0;
 069        var numComplete = 0;
 70
 071        while (startIndex < numberOfVideos)
 072        {
 073            query.StartIndex = startIndex;
 74
 075            var videos = _libraryManager.GetItemList(query);
 076            foreach (var video in videos)
 077            {
 78                // Only local files supported
 079                var path = video.Path;
 080                if (File.Exists(path))
 081                {
 082                    foreach (var extractor in _keyframeExtractors)
 083                    {
 84                        // The cache decorator will make sure to save the keyframes
 085                        if (extractor.TryExtractKeyframes(video.Id, path, out _))
 086                        {
 087                            break;
 88                        }
 089                    }
 090                }
 91
 92                // Update progress
 093                numComplete++;
 094                double percent = (double)numComplete / numberOfVideos;
 095                progress.Report(100 * percent);
 096            }
 97
 098            startIndex += Pagesize;
 099        }
 100
 0101        progress.Report(100);
 0102        return Task.CompletedTask;
 0103    }
 104
 105    /// <inheritdoc />
 21106    public IEnumerable<TaskTriggerInfo> GetDefaultTriggers() => [];
 107}