| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 | 
							- using System;
 
- using System.Collections.Generic;
 
- using System.IO;
 
- using System.Linq;
 
- using System.Threading;
 
- using System.Threading.Tasks;
 
- using MediaBrowser.Common.Configuration;
 
- using MediaBrowser.Model.Configuration;
 
- using MediaBrowser.Model.IO;
 
- using Microsoft.Extensions.Logging;
 
- namespace MediaBrowser.Controller.MediaEncoding;
 
- /// <summary>
 
- /// Transcoding segment cleaner.
 
- /// </summary>
 
- public class TranscodingSegmentCleaner : IDisposable
 
- {
 
-     private readonly TranscodingJob _job;
 
-     private readonly ILogger<TranscodingSegmentCleaner> _logger;
 
-     private readonly IConfigurationManager _config;
 
-     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.
 
-     /// </summary>
 
-     /// <param name="job">Transcoding job dto.</param>
 
-     /// <param name="logger">Instance of the <see cref="ILogger{TranscodingSegmentCleaner}"/> interface.</param>
 
-     /// <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>
 
-     public TranscodingSegmentCleaner(TranscodingJob job, ILogger<TranscodingSegmentCleaner> logger, IConfigurationManager config, IFileSystem fileSystem, IMediaEncoder mediaEncoder, int segmentLength)
 
-     {
 
-         _job = job;
 
-         _logger = logger;
 
-         _config = config;
 
-         _fileSystem = fileSystem;
 
-         _mediaEncoder = mediaEncoder;
 
-         _segmentLength = segmentLength;
 
-     }
 
-     /// <summary>
 
-     /// Start timer.
 
-     /// </summary>
 
-     public void Start()
 
-     {
 
-         _timer = new Timer(TimerCallback, null, 20000, 20000);
 
-     }
 
-     /// <summary>
 
-     /// Stop cleaner.
 
-     /// </summary>
 
-     public void Stop()
 
-     {
 
-         DisposeTimer();
 
-     }
 
-     /// <summary>
 
-     /// Dispose cleaner.
 
-     /// </summary>
 
-     public void Dispose()
 
-     {
 
-         Dispose(true);
 
-         GC.SuppressFinalize(this);
 
-     }
 
-     /// <summary>
 
-     /// Dispose cleaner.
 
-     /// </summary>
 
-     /// <param name="disposing">Disposing.</param>
 
-     protected virtual void Dispose(bool disposing)
 
-     {
 
-         if (disposing)
 
-         {
 
-             DisposeTimer();
 
-         }
 
-     }
 
-     private EncodingOptions GetOptions()
 
-     {
 
-         return _config.GetEncodingOptions();
 
-     }
 
-     private async void TimerCallback(object? state)
 
-     {
 
-         if (_job.HasExited)
 
-         {
 
-             DisposeTimer();
 
-             return;
 
-         }
 
-         var options = GetOptions();
 
-         var enableSegmentDeletion = options.EnableSegmentDeletion;
 
-         var segmentKeepSeconds = Math.Max(options.SegmentKeepSeconds, 20);
 
-         if (enableSegmentDeletion)
 
-         {
 
-             var downloadPositionTicks = _job.DownloadPositionTicks ?? 0;
 
-             var downloadPositionSeconds = Convert.ToInt64(TimeSpan.FromTicks(downloadPositionTicks).TotalSeconds);
 
-             if (downloadPositionSeconds > 0 && segmentKeepSeconds > 0 && downloadPositionSeconds > segmentKeepSeconds)
 
-             {
 
-                 var idxMaxToDelete = (downloadPositionSeconds - segmentKeepSeconds) / _segmentLength;
 
-                 if (idxMaxToDelete > 0)
 
-                 {
 
-                     await DeleteSegmentFiles(_job, 0, idxMaxToDelete, 1500).ConfigureAwait(false);
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     private async Task DeleteSegmentFiles(TranscodingJob job, long idxMin, long idxMax, int delayMs)
 
-     {
 
-         var path = job.Path ?? throw new ArgumentException("Path can't be null.");
 
-         _logger.LogDebug("Deleting segment file(s) index {Min} to {Max} from {Path}", idxMin, idxMax, path);
 
-         await Task.Delay(delayMs).ConfigureAwait(false);
 
-         try
 
-         {
 
-             if (job.Type == TranscodingJobType.Hls)
 
-             {
 
-                 DeleteHlsSegmentFiles(path, idxMin, idxMax);
 
-             }
 
-         }
 
-         catch (Exception ex)
 
-         {
 
-             _logger.LogDebug(ex, "Error deleting segment file(s) {Path}", path);
 
-         }
 
-     }
 
-     private void DeleteHlsSegmentFiles(string outputFilePath, long idxMin, long idxMax)
 
-     {
 
-         var directory = Path.GetDirectoryName(outputFilePath)
 
-                         ?? throw new ArgumentException("Path can't be a root directory.", nameof(outputFilePath));
 
-         var name = Path.GetFileNameWithoutExtension(outputFilePath);
 
-         var filesToDelete = _fileSystem.GetFilePaths(directory)
 
-             .Where(f => long.TryParse(Path.GetFileNameWithoutExtension(f).Replace(name, string.Empty, StringComparison.Ordinal), out var idx)
 
-                         && (idx >= idxMin && idx <= idxMax));
 
-         List<Exception>? exs = null;
 
-         foreach (var file in filesToDelete)
 
-         {
 
-             try
 
-             {
 
-                 _logger.LogDebug("Deleting HLS segment file {0}", file);
 
-                 _fileSystem.DeleteFile(file);
 
-             }
 
-             catch (IOException ex)
 
-             {
 
-                 (exs ??= new List<Exception>()).Add(ex);
 
-                 _logger.LogDebug(ex, "Error deleting HLS segment file {Path}", file);
 
-             }
 
-         }
 
-         if (exs is not null)
 
-         {
 
-             throw new AggregateException("Error deleting HLS segment files", exs);
 
-         }
 
-     }
 
-     private void DisposeTimer()
 
-     {
 
-         if (_timer is not null)
 
-         {
 
-             _timer.Dispose();
 
-             _timer = null;
 
-         }
 
-     }
 
- }
 
 
  |