| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 | 
							- using System;
 
- using System.Diagnostics;
 
- using System.Threading;
 
- using MediaBrowser.Model.Dto;
 
- using Microsoft.Extensions.Logging;
 
- namespace MediaBrowser.Controller.MediaEncoding;
 
- /// <summary>
 
- /// Class TranscodingJob.
 
- /// </summary>
 
- public sealed class TranscodingJob : IDisposable
 
- {
 
-     private readonly ILogger<TranscodingJob> _logger;
 
-     private readonly object _processLock = new();
 
-     private readonly object _timerLock = new();
 
-     private Timer? _killTimer;
 
-     /// <summary>
 
-     /// Initializes a new instance of the <see cref="TranscodingJob"/> class.
 
-     /// </summary>
 
-     /// <param name="logger">Instance of the <see cref="ILogger{TranscodingJobDto}"/> interface.</param>
 
-     public TranscodingJob(ILogger<TranscodingJob> logger)
 
-     {
 
-         _logger = logger;
 
-     }
 
-     /// <summary>
 
-     /// Gets or sets the play session identifier.
 
-     /// </summary>
 
-     public string? PlaySessionId { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets the live stream identifier.
 
-     /// </summary>
 
-     public string? LiveStreamId { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets a value indicating whether is live output.
 
-     /// </summary>
 
-     public bool IsLiveOutput { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets the path.
 
-     /// </summary>
 
-     public MediaSourceInfo? MediaSource { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets path.
 
-     /// </summary>
 
-     public string? Path { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets the type.
 
-     /// </summary>
 
-     public TranscodingJobType Type { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets the process.
 
-     /// </summary>
 
-     public Process? Process { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets the active request count.
 
-     /// </summary>
 
-     public int ActiveRequestCount { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets device id.
 
-     /// </summary>
 
-     public string? DeviceId { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets cancellation token source.
 
-     /// </summary>
 
-     public CancellationTokenSource? CancellationTokenSource { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets a value indicating whether has exited.
 
-     /// </summary>
 
-     public bool HasExited { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets exit code.
 
-     /// </summary>
 
-     public int ExitCode { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets a value indicating whether is user paused.
 
-     /// </summary>
 
-     public bool IsUserPaused { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets id.
 
-     /// </summary>
 
-     public string? Id { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets framerate.
 
-     /// </summary>
 
-     public float? Framerate { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets completion percentage.
 
-     /// </summary>
 
-     public double? CompletionPercentage { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets bytes downloaded.
 
-     /// </summary>
 
-     public long BytesDownloaded { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets bytes transcoded.
 
-     /// </summary>
 
-     public long? BytesTranscoded { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets bit rate.
 
-     /// </summary>
 
-     public int? BitRate { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets transcoding position ticks.
 
-     /// </summary>
 
-     public long? TranscodingPositionTicks { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets download position ticks.
 
-     /// </summary>
 
-     public long? DownloadPositionTicks { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets transcoding throttler.
 
-     /// </summary>
 
-     public TranscodingThrottler? TranscodingThrottler { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets last ping date.
 
-     /// </summary>
 
-     public DateTime LastPingDate { get; set; }
 
-     /// <summary>
 
-     /// Gets or sets ping timeout.
 
-     /// </summary>
 
-     public int PingTimeout { get; set; }
 
-     /// <summary>
 
-     /// Stop kill timer.
 
-     /// </summary>
 
-     public void StopKillTimer()
 
-     {
 
-         lock (_timerLock)
 
-         {
 
-             _killTimer?.Change(Timeout.Infinite, Timeout.Infinite);
 
-         }
 
-     }
 
-     /// <summary>
 
-     /// Dispose kill timer.
 
-     /// </summary>
 
-     public void DisposeKillTimer()
 
-     {
 
-         lock (_timerLock)
 
-         {
 
-             if (_killTimer is not null)
 
-             {
 
-                 _killTimer.Dispose();
 
-                 _killTimer = null;
 
-             }
 
-         }
 
-     }
 
-     /// <summary>
 
-     /// Start kill timer.
 
-     /// </summary>
 
-     /// <param name="callback">Callback action.</param>
 
-     public void StartKillTimer(Action<object?> callback)
 
-     {
 
-         StartKillTimer(callback, PingTimeout);
 
-     }
 
-     /// <summary>
 
-     /// Start kill timer.
 
-     /// </summary>
 
-     /// <param name="callback">Callback action.</param>
 
-     /// <param name="intervalMs">Callback interval.</param>
 
-     public void StartKillTimer(Action<object?> callback, int intervalMs)
 
-     {
 
-         if (HasExited)
 
-         {
 
-             return;
 
-         }
 
-         lock (_timerLock)
 
-         {
 
-             if (_killTimer is null)
 
-             {
 
-                 _logger.LogDebug("Starting kill timer at {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
 
-                 _killTimer = new Timer(new TimerCallback(callback), this, intervalMs, Timeout.Infinite);
 
-             }
 
-             else
 
-             {
 
-                 _logger.LogDebug("Changing kill timer to {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
 
-                 _killTimer.Change(intervalMs, Timeout.Infinite);
 
-             }
 
-         }
 
-     }
 
-     /// <summary>
 
-     /// Change kill timer if started.
 
-     /// </summary>
 
-     public void ChangeKillTimerIfStarted()
 
-     {
 
-         if (HasExited)
 
-         {
 
-             return;
 
-         }
 
-         lock (_timerLock)
 
-         {
 
-             if (_killTimer is not null)
 
-             {
 
-                 var intervalMs = PingTimeout;
 
-                 _logger.LogDebug("Changing kill timer to {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
 
-                 _killTimer.Change(intervalMs, Timeout.Infinite);
 
-             }
 
-         }
 
-     }
 
-     /// <summary>
 
-     /// Stops the transcoding job.
 
-     /// </summary>
 
-     public void Stop()
 
-     {
 
-         lock (_processLock)
 
-         {
 
- #pragma warning disable CA1849 // Can't await in lock block
 
-             TranscodingThrottler?.Stop().GetAwaiter().GetResult();
 
-             var process = Process;
 
-             if (!HasExited)
 
-             {
 
-                 try
 
-                 {
 
-                     _logger.LogInformation("Stopping ffmpeg process with q command for {Path}", Path);
 
-                     process!.StandardInput.WriteLine("q");
 
-                     // Need to wait because killing is asynchronous.
 
-                     if (!process.WaitForExit(5000))
 
-                     {
 
-                         _logger.LogInformation("Killing FFmpeg process for {Path}", Path);
 
-                         process.Kill();
 
-                     }
 
-                 }
 
-                 catch (InvalidOperationException)
 
-                 {
 
-                 }
 
-             }
 
- #pragma warning restore CA1849
 
-         }
 
-     }
 
-     /// <inheritdoc />
 
-     public void Dispose()
 
-     {
 
-         Process?.Dispose();
 
-         Process = null;
 
-         _killTimer?.Dispose();
 
-         _killTimer = null;
 
-         CancellationTokenSource?.Dispose();
 
-         CancellationTokenSource = null;
 
-         TranscodingThrottler?.Dispose();
 
-         TranscodingThrottler = null;
 
-     }
 
- }
 
 
  |