aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs8
-rw-r--r--Jellyfin.Server/Migrations/Routines/MoveTrickplayFiles.cs57
-rw-r--r--MediaBrowser.Controller/Trickplay/ITrickplayManager.cs4
-rw-r--r--MediaBrowser.Providers/Trickplay/TrickplayMoveImagesTask.cs51
4 files changed, 82 insertions, 38 deletions
diff --git a/Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs b/Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs
index 861037c1f..73e31279f 100644
--- a/Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs
+++ b/Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs
@@ -455,16 +455,18 @@ public class TrickplayManager : ITrickplayManager
}
/// <inheritdoc />
- public async Task<IReadOnlyList<Guid>> GetTrickplayItemsAsync()
+ public async Task<IReadOnlyList<TrickplayInfo>> GetTrickplayItemsAsync(int limit, int offset)
{
- List<Guid> trickplayItems;
+ IReadOnlyList<TrickplayInfo> trickplayItems;
var dbContext = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
{
trickplayItems = await dbContext.TrickplayInfos
.AsNoTracking()
- .Select(i => i.ItemId)
+ .OrderBy(i => i.ItemId)
+ .Skip(offset)
+ .Take(limit)
.ToListAsync()
.ConfigureAwait(false);
}
diff --git a/Jellyfin.Server/Migrations/Routines/MoveTrickplayFiles.cs b/Jellyfin.Server/Migrations/Routines/MoveTrickplayFiles.cs
index 301541b6c..c1a9e8894 100644
--- a/Jellyfin.Server/Migrations/Routines/MoveTrickplayFiles.cs
+++ b/Jellyfin.Server/Migrations/Routines/MoveTrickplayFiles.cs
@@ -1,10 +1,15 @@
using System;
+using System.Diagnostics;
using System.Globalization;
using System.IO;
+using System.Linq;
+using Jellyfin.Data.Enums;
+using MediaBrowser.Common;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Trickplay;
using MediaBrowser.Model.IO;
+using Microsoft.Extensions.Logging;
namespace Jellyfin.Server.Migrations.Routines;
@@ -16,6 +21,7 @@ public class MoveTrickplayFiles : IMigrationRoutine
private readonly ITrickplayManager _trickplayManager;
private readonly IFileSystem _fileSystem;
private readonly ILibraryManager _libraryManager;
+ private readonly ILogger<MoveTrickplayFiles> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="MoveTrickplayFiles"/> class.
@@ -23,11 +29,13 @@ public class MoveTrickplayFiles : IMigrationRoutine
/// <param name="trickplayManager">Instance of the <see cref="ITrickplayManager"/> interface.</param>
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
- public MoveTrickplayFiles(ITrickplayManager trickplayManager, IFileSystem fileSystem, ILibraryManager libraryManager)
+ /// <param name="logger">The logger.</param>
+ public MoveTrickplayFiles(ITrickplayManager trickplayManager, IFileSystem fileSystem, ILibraryManager libraryManager, ILogger<MoveTrickplayFiles> logger)
{
_trickplayManager = trickplayManager;
_fileSystem = fileSystem;
_libraryManager = libraryManager;
+ _logger = logger;
}
/// <inheritdoc />
@@ -42,26 +50,49 @@ public class MoveTrickplayFiles : IMigrationRoutine
/// <inheritdoc />
public void Perform()
{
- var trickplayItems = _trickplayManager.GetTrickplayItemsAsync().GetAwaiter().GetResult();
- foreach (var itemId in trickplayItems)
+ const int Limit = 100;
+ int itemCount = 0, offset = 0, previousCount;
+
+ var sw = Stopwatch.StartNew();
+ var trickplayQuery = new InternalItemsQuery
{
- var resolutions = _trickplayManager.GetTrickplayResolutions(itemId).GetAwaiter().GetResult();
- var item = _libraryManager.GetItemById(itemId);
- if (item is null)
- {
- continue;
- }
+ MediaTypes = [MediaType.Video],
+ SourceTypes = [SourceType.Library],
+ IsVirtualItem = false,
+ IsFolder = false
+ };
- foreach (var resolution in resolutions)
+ do
+ {
+ var trickplayInfos = _trickplayManager.GetTrickplayItemsAsync(Limit, offset).GetAwaiter().GetResult();
+ previousCount = trickplayInfos.Count;
+ offset += Limit;
+
+ trickplayQuery.ItemIds = trickplayInfos.Select(i => i.ItemId).Distinct().ToArray();
+ var items = _libraryManager.GetItemList(trickplayQuery);
+ foreach (var trickplayInfo in trickplayInfos)
{
- var oldPath = GetOldTrickplayDirectory(item, resolution.Key);
- var newPath = _trickplayManager.GetTrickplayDirectory(item, resolution.Value.TileWidth, resolution.Value.TileHeight, resolution.Value.Width, false);
+ var item = items.OfType<Video>().FirstOrDefault(i => i.Id.Equals(trickplayInfo.ItemId));
+ if (item is null)
+ {
+ continue;
+ }
+
+ if (++itemCount % 1_000 == 0)
+ {
+ _logger.LogInformation("Moved {Count} items in {Time}", itemCount, sw.Elapsed);
+ }
+
+ var oldPath = GetOldTrickplayDirectory(item, trickplayInfo.Width);
+ var newPath = _trickplayManager.GetTrickplayDirectory(item, trickplayInfo.TileWidth, trickplayInfo.TileHeight, trickplayInfo.Width, false);
if (_fileSystem.DirectoryExists(oldPath))
{
_fileSystem.MoveDirectory(oldPath, newPath);
}
}
- }
+ } while (previousCount == Limit);
+
+ _logger.LogInformation("Moved {Count} items in {Time}", itemCount, sw.Elapsed);
}
private string GetOldTrickplayDirectory(BaseItem item, int? width = null)
diff --git a/MediaBrowser.Controller/Trickplay/ITrickplayManager.cs b/MediaBrowser.Controller/Trickplay/ITrickplayManager.cs
index bda794aa6..800317800 100644
--- a/MediaBrowser.Controller/Trickplay/ITrickplayManager.cs
+++ b/MediaBrowser.Controller/Trickplay/ITrickplayManager.cs
@@ -46,8 +46,10 @@ public interface ITrickplayManager
/// <summary>
/// Gets the item ids of all items with trickplay info.
/// </summary>
+ /// <param name="limit">The limit of items to return.</param>
+ /// <param name="offset">The offset to start the query at.</param>
/// <returns>The list of item ids that have trickplay info.</returns>
- public Task<IReadOnlyList<Guid>> GetTrickplayItemsAsync();
+ Task<IReadOnlyList<TrickplayInfo>> GetTrickplayItemsAsync(int limit, int offset);
/// <summary>
/// Saves trickplay info.
diff --git a/MediaBrowser.Providers/Trickplay/TrickplayMoveImagesTask.cs b/MediaBrowser.Providers/Trickplay/TrickplayMoveImagesTask.cs
index c581fd26c..c0b8a8c75 100644
--- a/MediaBrowser.Providers/Trickplay/TrickplayMoveImagesTask.cs
+++ b/MediaBrowser.Providers/Trickplay/TrickplayMoveImagesTask.cs
@@ -18,8 +18,6 @@ namespace MediaBrowser.Providers.Trickplay;
/// </summary>
public class TrickplayMoveImagesTask : IScheduledTask
{
- private const int QueryPageLimit = 100;
-
private readonly ILogger<TrickplayMoveImagesTask> _logger;
private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _localization;
@@ -62,32 +60,46 @@ public class TrickplayMoveImagesTask : IScheduledTask
/// <inheritdoc />
public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
{
- var trickplayItems = await _trickplayManager.GetTrickplayItemsAsync().ConfigureAwait(false);
- var query = new InternalItemsQuery
+ const int Limit = 100;
+ int itemCount = 0, offset = 0, previousCount;
+
+ // This count may not be accurate, but just get something to show progress on the dashboard.
+ var totalVideoCount = _libraryManager.GetCount(new InternalItemsQuery
{
MediaTypes = [MediaType.Video],
SourceTypes = [SourceType.Library],
IsVirtualItem = false,
IsFolder = false,
- Recursive = true,
- Limit = QueryPageLimit
- };
-
- var numberOfVideos = _libraryManager.GetCount(query);
+ Recursive = true
+ });
- var startIndex = 0;
- var numComplete = 0;
+ var trickplayQuery = new InternalItemsQuery
+ {
+ MediaTypes = [MediaType.Video],
+ SourceTypes = [SourceType.Library],
+ IsVirtualItem = false,
+ IsFolder = false
+ };
- while (startIndex < numberOfVideos)
+ do
{
- query.StartIndex = startIndex;
- var videos = _libraryManager.GetItemList(query).OfType<Video>().ToList();
- videos.RemoveAll(i => !trickplayItems.Contains(i.Id));
+ var trickplayInfos = await _trickplayManager.GetTrickplayItemsAsync(Limit, offset).ConfigureAwait(false);
+ previousCount = trickplayInfos.Count;
+ offset += Limit;
- foreach (var video in videos)
+ trickplayQuery.ItemIds = trickplayInfos.Select(i => i.ItemId).Distinct().ToArray();
+ var items = _libraryManager.GetItemList(trickplayQuery);
+ foreach (var trickplayInfo in trickplayInfos)
{
cancellationToken.ThrowIfCancellationRequested();
+ var video = items.OfType<Video>().FirstOrDefault(i => i.Id.Equals(trickplayInfo.ItemId));
+ if (video is null)
+ {
+ continue;
+ }
+
+ itemCount++;
try
{
var libraryOptions = _libraryManager.GetLibraryOptions(video);
@@ -97,13 +109,10 @@ public class TrickplayMoveImagesTask : IScheduledTask
{
_logger.LogError(ex, "Error moving trickplay files for {ItemName}", video.Name);
}
-
- numComplete++;
- progress.Report(100d * numComplete / numberOfVideos);
}
- startIndex += QueryPageLimit;
- }
+ progress.Report(100d * itemCount / totalVideoCount);
+ } while (previousCount == Limit);
progress.Report(100);
}