aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api/ApiEntryPoint.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Api/ApiEntryPoint.cs')
-rw-r--r--MediaBrowser.Api/ApiEntryPoint.cs91
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
{