diff options
| author | klizas <klizas@users.noreply.github.com> | 2026-10-05 19:18:45 -0400 |
|---|---|---|
| committer | Cody Robibero <cody@robibe.ro> | 2026-10-05 19:18:45 -0400 |
| commit | 7dc6544d3441187f73393dac54dc358b3ceb98ed (patch) | |
| tree | 339d4cf7da2c12397602a372e028433e6e9c2434 /MediaBrowser.Controller | |
| parent | 69e131eaa5bbe6ff01175332b58c5b262863a5a3 (diff) | |
Backport pull request #18186 from jellyfin/release-12.z
Fix segment cleaner deleting segments ahead of playback when remuxing MKV
Original-merge: 3acc9c8443d7ee445c4fe015f2977a47d4ea57ac
Merged-by: crobibero <cody@robibe.ro>
Backported-by: Cody Robibero <cody@robibe.ro>
Diffstat (limited to 'MediaBrowser.Controller')
| -rw-r--r-- | MediaBrowser.Controller/MediaEncoding/TranscodingJob.cs | 36 | ||||
| -rw-r--r-- | MediaBrowser.Controller/MediaEncoding/TranscodingSegmentCleaner.cs | 8 |
2 files changed, 39 insertions, 5 deletions
diff --git a/MediaBrowser.Controller/MediaEncoding/TranscodingJob.cs b/MediaBrowser.Controller/MediaEncoding/TranscodingJob.cs index 5045030b9b..12600af384 100644 --- a/MediaBrowser.Controller/MediaEncoding/TranscodingJob.cs +++ b/MediaBrowser.Controller/MediaEncoding/TranscodingJob.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.Threading; using MediaBrowser.Model.Dto; @@ -14,6 +15,7 @@ public sealed class TranscodingJob : IDisposable private readonly ILogger<TranscodingJob> _logger; private readonly Lock _processLock = new(); private readonly Lock _timerLock = new(); + private readonly ConcurrentDictionary<int, long> _segmentEndPositionTicks = new(); private int _activeRequestCount; private Timer? _killTimer; @@ -157,6 +159,40 @@ public sealed class TranscodingJob : IDisposable public int PingTimeout { get; set; } /// <summary> + /// Records the end position of a served segment. + /// </summary> + /// <param name="segmentIndex">The segment index.</param> + /// <param name="segmentEndPositionTicks">The segment end position ticks.</param> + public void ReportSegmentDownloaded(int segmentIndex, long segmentEndPositionTicks) + { + if (segmentIndex < 0) + { + return; + } + + _segmentEndPositionTicks[segmentIndex] = segmentEndPositionTicks; + } + + /// <summary> + /// Gets the highest index among served segments whose end position is at or before the given position. + /// </summary> + /// <param name="positionTicks">The position ticks.</param> + /// <returns>The segment index, or <c>null</c> if there is none.</returns> + public int? GetHighestServedSegmentIndexEndingAtOrBefore(long positionTicks) + { + int? result = null; + foreach (var (index, endPositionTicks) in _segmentEndPositionTicks) + { + if (endPositionTicks <= positionTicks && (result is null || index > result)) + { + result = index; + } + } + + return result; + } + + /// <summary> /// Increments the active request count. /// </summary> /// <returns>The incremented count.</returns> diff --git a/MediaBrowser.Controller/MediaEncoding/TranscodingSegmentCleaner.cs b/MediaBrowser.Controller/MediaEncoding/TranscodingSegmentCleaner.cs index 67bfcb02fd..924fc2e659 100644 --- a/MediaBrowser.Controller/MediaEncoding/TranscodingSegmentCleaner.cs +++ b/MediaBrowser.Controller/MediaEncoding/TranscodingSegmentCleaner.cs @@ -22,7 +22,6 @@ public class TranscodingSegmentCleaner : IDisposable private readonly IFileSystem _fileSystem; private readonly IMediaEncoder _mediaEncoder; private Timer? _timer; - private int _segmentLength; /// <summary> /// Initializes a new instance of the <see cref="TranscodingSegmentCleaner"/> class. @@ -32,7 +31,7 @@ public class TranscodingSegmentCleaner : IDisposable /// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param> /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param> /// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param> - /// <param name="segmentLength">The segment length of this transcoding job.</param> + /// <param name="segmentLength">The segment length of this transcoding job. Unused.</param> public TranscodingSegmentCleaner(TranscodingJob job, ILogger<TranscodingSegmentCleaner> logger, IConfigurationManager config, IFileSystem fileSystem, IMediaEncoder mediaEncoder, int segmentLength) { _job = job; @@ -40,7 +39,6 @@ public class TranscodingSegmentCleaner : IDisposable _config = config; _fileSystem = fileSystem; _mediaEncoder = mediaEncoder; - _segmentLength = segmentLength; } /// <summary> @@ -104,11 +102,11 @@ public class TranscodingSegmentCleaner : IDisposable if (downloadPositionSeconds > 0 && segmentKeepSeconds > 0 && downloadPositionSeconds > segmentKeepSeconds) { - var idxMaxToDelete = (downloadPositionSeconds - segmentKeepSeconds) / _segmentLength; + var idxMaxToDelete = _job.GetHighestServedSegmentIndexEndingAtOrBefore(downloadPositionTicks - TimeSpan.FromSeconds(segmentKeepSeconds).Ticks); if (idxMaxToDelete > 0) { - await DeleteSegmentFiles(_job, 0, idxMaxToDelete, 1500).ConfigureAwait(false); + await DeleteSegmentFiles(_job, 0, idxMaxToDelete.Value, 1500).ConfigureAwait(false); } } } |
