diff options
| author | ThunderClapLP <59509654+ThunderClapLP@users.noreply.github.com> | 2025-06-10 15:45:09 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-10 07:45:09 -0600 |
| commit | 6b5ce934b3ad522cc73b702538026ec7c99103cd (patch) | |
| tree | b0e8bdda983c6324c9e342e3c6edd01f8043c9e6 | |
| parent | 7174bb6a93e77031da9a7130305dd3c1e1426fe9 (diff) | |
Fix existing media segments not being handled on scan (#14218)
4 files changed, 59 insertions, 14 deletions
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 57d7398be..1a98414e9 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -197,6 +197,7 @@ - [benedikt257](https://github.com/benedikt257) - [revam](https://github.com/revam) - [allesmi](https://github.com/allesmi) + - [ThunderClapLP](https://github.com/ThunderClapLP) # Emby Contributors diff --git a/Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs b/Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs index 28b6890b0..97c9d79f5 100644 --- a/Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs +++ b/Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs @@ -51,7 +51,7 @@ public class MediaSegmentManager : IMediaSegmentManager } /// <inheritdoc/> - public async Task RunSegmentPluginProviders(BaseItem baseItem, LibraryOptions libraryOptions, bool overwrite, CancellationToken cancellationToken) + public async Task RunSegmentPluginProviders(BaseItem baseItem, LibraryOptions libraryOptions, bool forceOverwrite, CancellationToken cancellationToken) { var providers = _segmentProviders .Where(e => !libraryOptions.DisabledMediaSegmentProviders.Contains(GetProviderId(e.Name))) @@ -70,18 +70,13 @@ public class MediaSegmentManager : IMediaSegmentManager using var db = await _dbProvider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false); - if (!overwrite && (await db.MediaSegments.AnyAsync(e => e.ItemId.Equals(baseItem.Id), cancellationToken).ConfigureAwait(false))) - { - _logger.LogDebug("Skip {MediaPath} as it already contains media segments", baseItem.Path); - return; - } - _logger.LogDebug("Start media segment extraction for {MediaPath} with {CountProviders} providers enabled", baseItem.Path, providers.Count); - await db.MediaSegments.Where(e => e.ItemId.Equals(baseItem.Id)).ExecuteDeleteAsync(cancellationToken).ConfigureAwait(false); - - // no need to recreate the request object every time. - var requestItem = new MediaSegmentGenerationRequest() { ItemId = baseItem.Id }; + if (forceOverwrite) + { + // delete all existing media segments if forceOverwrite is set. + await db.MediaSegments.Where(e => e.ItemId.Equals(baseItem.Id)).ExecuteDeleteAsync(cancellationToken).ConfigureAwait(false); + } foreach (var provider in providers) { @@ -91,15 +86,56 @@ public class MediaSegmentManager : IMediaSegmentManager continue; } + IQueryable<MediaSegment> existingSegments; + if (forceOverwrite) + { + existingSegments = Array.Empty<MediaSegment>().AsQueryable(); + } + else + { + existingSegments = db.MediaSegments.Where(e => e.ItemId.Equals(baseItem.Id) && e.SegmentProviderId == GetProviderId(provider.Name)); + } + + var requestItem = new MediaSegmentGenerationRequest() + { + ItemId = baseItem.Id, + ExistingSegments = existingSegments.Select(e => Map(e)).ToArray() + }; + try { var segments = await provider.GetMediaSegments(requestItem, cancellationToken) .ConfigureAwait(false); - if (segments.Count == 0) + + if (!forceOverwrite) + { + var existingSegmentsList = existingSegments.ToArray(); // Cannot use requestItem's list, as the provider might tamper with its items. + if (segments.Count == requestItem.ExistingSegments.Count && segments.All(e => existingSegmentsList.Any(f => + { + return + e.StartTicks == f.StartTicks && + e.EndTicks == f.EndTicks && + e.Type == f.Type; + }))) + { + _logger.LogDebug("Media Segment provider {ProviderName} did not modify any segments for {MediaPath}", provider.Name, baseItem.Path); + continue; + } + + // delete existing media segments that were re-generated. + await existingSegments.ExecuteDeleteAsync(cancellationToken).ConfigureAwait(false); + } + + if (segments.Count == 0 && !requestItem.ExistingSegments.Any()) { _logger.LogDebug("Media Segment provider {ProviderName} did not find any segments for {MediaPath}", provider.Name, baseItem.Path); continue; } + else if (segments.Count == 0 && requestItem.ExistingSegments.Any()) + { + _logger.LogDebug("Media Segment provider {ProviderName} deleted all segments for {MediaPath}", provider.Name, baseItem.Path); + continue; + } _logger.LogInformation("Media Segment provider {ProviderName} found {CountSegments} for {MediaPath}", provider.Name, segments.Count, baseItem.Path); var providerId = GetProviderId(provider.Name); diff --git a/MediaBrowser.Controller/MediaSegments/IMediaSegmentManager.cs b/MediaBrowser.Controller/MediaSegments/IMediaSegmentManager.cs index 720c607f1..4f13a7ecc 100644 --- a/MediaBrowser.Controller/MediaSegments/IMediaSegmentManager.cs +++ b/MediaBrowser.Controller/MediaSegments/IMediaSegmentManager.cs @@ -20,10 +20,10 @@ public interface IMediaSegmentManager /// </summary> /// <param name="baseItem">The Item to evaluate.</param> /// <param name="libraryOptions">The library options.</param> - /// <param name="overwrite">If set, will remove existing segments and replace it with new ones otherwise will check for existing segments and if found any, stops.</param> + /// <param name="forceOverwrite">If set, will force to remove existing segments and replace it with new ones otherwise will check for existing segments and if found any that should not be deleted, stops.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A task that indicates the Operation is finished.</returns> - Task RunSegmentPluginProviders(BaseItem baseItem, LibraryOptions libraryOptions, bool overwrite, CancellationToken cancellationToken); + Task RunSegmentPluginProviders(BaseItem baseItem, LibraryOptions libraryOptions, bool forceOverwrite, CancellationToken cancellationToken); /// <summary> /// Returns if this item supports media segments. diff --git a/MediaBrowser.Model/MediaSegments/MediaSegmentGenerationRequest.cs b/MediaBrowser.Model/MediaSegments/MediaSegmentGenerationRequest.cs index 8c1f44de8..53d017375 100644 --- a/MediaBrowser.Model/MediaSegments/MediaSegmentGenerationRequest.cs +++ b/MediaBrowser.Model/MediaSegments/MediaSegmentGenerationRequest.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Generic; +using Jellyfin.Database.Implementations.Entities; +using MediaBrowser.Model.MediaSegments; namespace MediaBrowser.Model; @@ -11,4 +14,9 @@ public record MediaSegmentGenerationRequest /// Gets the Id to the BaseItem the segments should be extracted from. /// </summary> public Guid ItemId { get; init; } + + /// <summary> + /// Gets existing media segments generated on an earlier scan by this provider. + /// </summary> + public required IReadOnlyList<MediaSegmentDto> ExistingSegments { get; init; } } |
