From 025017ace59b20ec572ae2469edbfe9e6966fa5f Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Wed, 15 Jun 2022 21:12:07 -0500 Subject: [PATCH] regularly delete old segments (#856) * regularly delete old segments * cleanup --- CHANGELOG.md | 5 ++ .../Streaming/HlsSessionWorker.cs | 74 ++++++++++++------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 637ded3a6..81a5ccd4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Check whether hardware-accelerated hevc codecs are supported by the NVIDIA card - Software codecs will be used if they are unsupported by the NVIDIA card +### Changed +- Regularly delete old segments from transcode folder while content is actively transcoding + - This should help reduce required disk space + - To further minimize required disk space, set `Work-Ahead HLS Segmenter Limit` to `0` in `Settings` + ## [0.6.1-beta] - 2022-06-03 ### Fixed - Fix Jellyfin show library paging diff --git a/ErsatzTV.Application/Streaming/HlsSessionWorker.cs b/ErsatzTV.Application/Streaming/HlsSessionWorker.cs index ed0893ff7..95b502541 100644 --- a/ErsatzTV.Application/Streaming/HlsSessionWorker.cs +++ b/ErsatzTV.Application/Streaming/HlsSessionWorker.cs @@ -28,6 +28,7 @@ public class HlsSessionWorker : IHlsSessionWorker private string _channelNumber; private bool _firstProcess; private DateTimeOffset _lastAccess; + private DateTimeOffset _lastDelete = DateTimeOffset.MinValue; private Option _targetFramerate; private Timer _timer; private DateTimeOffset _transcodedUntil; @@ -65,7 +66,19 @@ public class HlsSessionWorker : IHlsSessionWorker try { Option maybeLines = await ReadPlaylistLines(cancellationToken); - return maybeLines.Map(input => _hlsPlaylistFilter.TrimPlaylist(PlaylistStart, filterBefore, input)); + foreach (string[] input in maybeLines) + { + TrimPlaylistResult trimResult = _hlsPlaylistFilter.TrimPlaylist(PlaylistStart, filterBefore, input); + if (DateTimeOffset.Now > _lastDelete.AddSeconds(30)) + { + DeleteOldSegments(trimResult); + _lastDelete = DateTimeOffset.Now; + } + + return trimResult; + } + + return None; } finally { @@ -334,33 +347,7 @@ public class HlsSessionWorker : IHlsSessionWorker lines); await WritePlaylist(trimResult.Playlist, cancellationToken); - // delete old segments - var allSegments = Directory.GetFiles( - Path.Combine(FileSystemLayout.TranscodeFolder, _channelNumber), - "live*.ts") - .Map( - file => - { - string fileName = Path.GetFileName(file); - var sequenceNumber = int.Parse(fileName.Replace("live", string.Empty).Split('.')[0]); - return new Segment(file, sequenceNumber); - }) - .ToList(); - - var toDelete = allSegments.Filter(s => s.SequenceNumber < trimResult.Sequence).ToList(); - // if (toDelete.Count > 0) - // { - // _logger.LogDebug( - // "Deleting HLS segments {Min} to {Max} (less than {StartSequence})", - // toDelete.Map(s => s.SequenceNumber).Min(), - // toDelete.Map(s => s.SequenceNumber).Max(), - // trimResult.Sequence); - // } - - foreach (Segment segment in toDelete) - { - File.Delete(segment.File); - } + DeleteOldSegments(trimResult); PlaylistStart = trimResult.PlaylistStart; } @@ -371,6 +358,37 @@ public class HlsSessionWorker : IHlsSessionWorker } } + private void DeleteOldSegments(TrimPlaylistResult trimResult) + { + // delete old segments + var allSegments = Directory.GetFiles( + Path.Combine(FileSystemLayout.TranscodeFolder, _channelNumber), + "live*.ts") + .Map( + file => + { + string fileName = Path.GetFileName(file); + var sequenceNumber = int.Parse(fileName.Replace("live", string.Empty).Split('.')[0]); + return new Segment(file, sequenceNumber); + }) + .ToList(); + + var toDelete = allSegments.Filter(s => s.SequenceNumber < trimResult.Sequence).ToList(); + if (toDelete.Count > 0) + { + _logger.LogDebug( + "Deleting HLS segments {Min} to {Max} (less than {StartSequence})", + toDelete.Map(s => s.SequenceNumber).Min(), + toDelete.Map(s => s.SequenceNumber).Max(), + trimResult.Sequence); + } + + foreach (Segment segment in toDelete) + { + File.Delete(segment.File); + } + } + private async Task GetPtsOffset( IMediator mediator, string channelNumber,