diff options
Diffstat (limited to 'MediaBrowser.Api/ApiEntryPoint.cs')
| -rw-r--r-- | MediaBrowser.Api/ApiEntryPoint.cs | 91 |
1 files changed, 60 insertions, 31 deletions
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 88654a42c..8dbc26356 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; @@ -17,7 +18,6 @@ using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Dto; using MediaBrowser.Model.IO; using MediaBrowser.Model.Session; -using MediaBrowser.Model.Threading; using Microsoft.Extensions.Logging; namespace MediaBrowser.Api @@ -47,7 +47,6 @@ namespace MediaBrowser.Api private readonly ISessionManager _sessionManager; private readonly IFileSystem _fileSystem; private readonly IMediaSourceManager _mediaSourceManager; - public readonly ITimerFactory TimerFactory; public readonly IProcessFactory ProcessFactory; /// <summary> @@ -58,6 +57,8 @@ namespace MediaBrowser.Api private readonly Dictionary<string, SemaphoreSlim> _transcodingLocks = new Dictionary<string, SemaphoreSlim>(); + private bool _disposed = false; + /// <summary> /// Initializes a new instance of the <see cref="ApiEntryPoint" /> class. /// </summary> @@ -66,20 +67,27 @@ namespace MediaBrowser.Api /// <param name="config">The configuration.</param> /// <param name="fileSystem">The file system.</param> /// <param name="mediaSourceManager">The media source manager.</param> - public ApiEntryPoint(ILogger logger, ISessionManager sessionManager, IServerConfigurationManager config, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager, ITimerFactory timerFactory, IProcessFactory processFactory, IHttpResultFactory resultFactory) + public ApiEntryPoint( + ILogger logger, + ISessionManager sessionManager, + IServerConfigurationManager config, + IFileSystem fileSystem, + IMediaSourceManager mediaSourceManager, + IProcessFactory processFactory, + IHttpResultFactory resultFactory) { Logger = logger; _sessionManager = sessionManager; _config = config; _fileSystem = fileSystem; _mediaSourceManager = mediaSourceManager; - TimerFactory = timerFactory; ProcessFactory = processFactory; ResultFactory = resultFactory; - Instance = this; _sessionManager.PlaybackProgress += _sessionManager_PlaybackProgress; _sessionManager.PlaybackStart += _sessionManager_PlaybackStart; + + Instance = this; } public static string[] Split(string value, char separator, bool removeEmpty) @@ -185,17 +193,40 @@ namespace MediaBrowser.Api /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool dispose) { - var list = _activeTranscodingJobs.ToList(); - var jobCount = list.Count; + if (_disposed) + { + return; + } - Parallel.ForEach(list, j => KillTranscodingJob(j, false, path => true)); + if (dispose) + { + // TODO: dispose + } - // Try to allow for some time to kill the ffmpeg processes and delete the partial stream files + var jobs = _activeTranscodingJobs.ToList(); + var jobCount = jobs.Count; + + IEnumerable<Task> GetKillJobs() + { + foreach (var job in jobs) + { + yield return KillTranscodingJob(job, false, path => true); + } + } + + // Wait for all processes to be killed if (jobCount > 0) { - var task = Task.Delay(1000); - Task.WaitAll(task); + Task.WaitAll(GetKillJobs().ToArray()); } + + _activeTranscodingJobs.Clear(); + _transcodingLocks.Clear(); + + _sessionManager.PlaybackProgress -= _sessionManager_PlaybackProgress; + _sessionManager.PlaybackStart -= _sessionManager_PlaybackStart; + + _disposed = true; } @@ -212,19 +243,20 @@ namespace MediaBrowser.Api /// <param name="state">The state.</param> /// <param name="cancellationTokenSource">The cancellation token source.</param> /// <returns>TranscodingJob.</returns> - public TranscodingJob OnTranscodeBeginning(string path, + public TranscodingJob OnTranscodeBeginning( + string path, string playSessionId, string liveStreamId, string transcodingJobId, TranscodingJobType type, - IProcess process, + Process process, string deviceId, StreamState state, CancellationTokenSource cancellationTokenSource) { lock (_activeTranscodingJobs) { - var job = new TranscodingJob(Logger, TimerFactory) + var job = new TranscodingJob(Logger) { Type = type, Path = path, @@ -446,7 +478,7 @@ namespace MediaBrowser.Api /// Called when [transcode kill timer stopped]. /// </summary> /// <param name="state">The state.</param> - private void OnTranscodeKillTimerStopped(object state) + private async void OnTranscodeKillTimerStopped(object state) { var job = (TranscodingJob)state; @@ -463,7 +495,7 @@ namespace MediaBrowser.Api Logger.LogInformation("Transcoding kill timer stopped for JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId); - KillTranscodingJob(job, true, path => true).GetAwaiter().GetResult(); + await KillTranscodingJob(job, true, path => true); } /// <summary> @@ -551,7 +583,7 @@ namespace MediaBrowser.Api { if (job.TranscodingThrottler != null) { - job.TranscodingThrottler.Stop(); + job.TranscodingThrottler.Stop().GetAwaiter().GetResult(); } var process = job.Process; @@ -562,7 +594,7 @@ namespace MediaBrowser.Api { try { - Logger.LogInformation("Stopping ffmpeg process with q command for {path}", job.Path); + Logger.LogInformation("Stopping ffmpeg process with q command for {Path}", job.Path); //process.Kill(); process.StandardInput.WriteLine("q"); @@ -570,13 +602,13 @@ namespace MediaBrowser.Api // Need to wait because killing is asynchronous if (!process.WaitForExit(5000)) { - Logger.LogInformation("Killing ffmpeg process for {path}", job.Path); + Logger.LogInformation("Killing ffmpeg process for {Path}", job.Path); process.Kill(); } } catch (Exception ex) { - Logger.LogError(ex, "Error killing transcoding job for {path}", job.Path); + Logger.LogError(ex, "Error killing transcoding job for {Path}", job.Path); } } } @@ -606,7 +638,7 @@ namespace MediaBrowser.Api return; } - Logger.LogInformation("Deleting partial stream file(s) {0}", path); + Logger.LogInformation("Deleting partial stream file(s) {Path}", path); await Task.Delay(delayMs).ConfigureAwait(false); @@ -627,13 +659,13 @@ namespace MediaBrowser.Api } catch (IOException ex) { - Logger.LogError(ex, "Error deleting partial stream file(s) {path}", path); + Logger.LogError(ex, "Error deleting partial stream file(s) {Path}", path); await DeletePartialStreamFiles(path, jobType, retryCount + 1, 500).ConfigureAwait(false); } catch (Exception ex) { - Logger.LogError(ex, "Error deleting partial stream file(s) {path}", path); + Logger.LogError(ex, "Error deleting partial stream file(s) {Path}", path); } } @@ -674,7 +706,7 @@ namespace MediaBrowser.Api catch (IOException ex) { e = ex; - Logger.LogError(ex, "Error deleting HLS file {path}", file); + Logger.LogError(ex, "Error deleting HLS file {Path}", file); } } @@ -718,7 +750,7 @@ namespace MediaBrowser.Api /// Gets or sets the process. /// </summary> /// <value>The process.</value> - public IProcess Process { get; set; } + public Process Process { get; set; } public ILogger Logger { get; private set; } /// <summary> /// Gets or sets the active request count. @@ -729,9 +761,7 @@ namespace MediaBrowser.Api /// Gets or sets the kill timer. /// </summary> /// <value>The kill timer.</value> - private ITimer KillTimer { get; set; } - - private readonly ITimerFactory _timerFactory; + private Timer KillTimer { get; set; } public string DeviceId { get; set; } @@ -761,10 +791,9 @@ namespace MediaBrowser.Api public DateTime LastPingDate { get; set; } public int PingTimeout { get; set; } - public TranscodingJob(ILogger logger, ITimerFactory timerFactory) + public TranscodingJob(ILogger logger) { Logger = logger; - _timerFactory = timerFactory; } public void StopKillTimer() @@ -807,7 +836,7 @@ namespace MediaBrowser.Api if (KillTimer == null) { //Logger.LogDebug("Starting kill timer at {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId); - KillTimer = _timerFactory.Create(callback, this, intervalMs, Timeout.Infinite); + KillTimer = new Timer(new TimerCallback(callback), this, intervalMs, Timeout.Infinite); } else { |
