From c4c9126f79f43ad865cfa670bda90a94ffb39d9c Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Fri, 8 Mar 2013 14:14:09 -0500 Subject: added more attributes for api docs --- MediaBrowser.Api/ApiEntryPoint.cs | 333 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 MediaBrowser.Api/ApiEntryPoint.cs (limited to 'MediaBrowser.Api/ApiEntryPoint.cs') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs new file mode 100644 index 000000000..9003c7263 --- /dev/null +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -0,0 +1,333 @@ +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Api +{ + /// + /// Class ServerEntryPoint + /// + public class ApiEntryPoint : IServerEntryPoint + { + /// + /// The instance + /// + public static ApiEntryPoint Instance; + + /// + /// Gets or sets the logger. + /// + /// The logger. + private ILogger Logger { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The logger. + public ApiEntryPoint(ILogger logger) + { + Logger = logger; + + Instance = this; + } + + /// + /// Runs this instance. + /// + public void Run() + { + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool dispose) + { + var jobCount = ActiveTranscodingJobs.Count; + + Parallel.ForEach(ActiveTranscodingJobs, OnTranscodeKillTimerStopped); + + // Try to allow for some time to kill the ffmpeg processes and delete the partial stream files + if (jobCount > 0) + { + Thread.Sleep(1000); + } + } + + /// + /// The active transcoding jobs + /// + private readonly List ActiveTranscodingJobs = new List(); + + /// + /// Called when [transcode beginning]. + /// + /// The path. + /// The type. + /// The process. + public void OnTranscodeBeginning(string path, TranscodingJobType type, Process process) + { + lock (ActiveTranscodingJobs) + { + ActiveTranscodingJobs.Add(new TranscodingJob + { + Type = type, + Path = path, + Process = process, + ActiveRequestCount = 1 + }); + } + } + + /// + /// + /// The progressive + /// + /// Called when [transcode failed to start]. + /// + /// The path. + /// The type. + public void OnTranscodeFailedToStart(string path, TranscodingJobType type) + { + lock (ActiveTranscodingJobs) + { + var job = ActiveTranscodingJobs.First(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); + + ActiveTranscodingJobs.Remove(job); + } + } + + /// + /// Determines whether [has active transcoding job] [the specified path]. + /// + /// The path. + /// The type. + /// true if [has active transcoding job] [the specified path]; otherwise, false. + public bool HasActiveTranscodingJob(string path, TranscodingJobType type) + { + lock (ActiveTranscodingJobs) + { + return ActiveTranscodingJobs.Any(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); + } + } + + /// + /// Called when [transcode begin request]. + /// + /// The path. + /// The type. + public void OnTranscodeBeginRequest(string path, TranscodingJobType type) + { + lock (ActiveTranscodingJobs) + { + var job = ActiveTranscodingJobs.FirstOrDefault(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); + + if (job == null) + { + return; + } + + job.ActiveRequestCount++; + + if (job.KillTimer != null) + { + job.KillTimer.Dispose(); + job.KillTimer = null; + } + } + } + + /// + /// Called when [transcode end request]. + /// + /// The path. + /// The type. + public void OnTranscodeEndRequest(string path, TranscodingJobType type) + { + lock (ActiveTranscodingJobs) + { + var job = ActiveTranscodingJobs.FirstOrDefault(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); + + if (job == null) + { + return; + } + + job.ActiveRequestCount--; + + if (job.ActiveRequestCount == 0) + { + var timerDuration = type == TranscodingJobType.Progressive ? 1000 : 30000; + + if (job.KillTimer == null) + { + job.KillTimer = new Timer(OnTranscodeKillTimerStopped, job, timerDuration, Timeout.Infinite); + } + else + { + job.KillTimer.Change(timerDuration, Timeout.Infinite); + } + } + } + } + + /// + /// Called when [transcoding finished]. + /// + /// The path. + /// The type. + public void OnTranscodingFinished(string path, TranscodingJobType type) + { + lock (ActiveTranscodingJobs) + { + var job = ActiveTranscodingJobs.FirstOrDefault(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); + + if (job == null) + { + return; + } + + ActiveTranscodingJobs.Remove(job); + + if (job.KillTimer != null) + { + job.KillTimer.Dispose(); + job.KillTimer = null; + } + } + } + + /// + /// Called when [transcode kill timer stopped]. + /// + /// The state. + private void OnTranscodeKillTimerStopped(object state) + { + var job = (TranscodingJob)state; + + lock (ActiveTranscodingJobs) + { + ActiveTranscodingJobs.Remove(job); + + if (job.KillTimer != null) + { + job.KillTimer.Dispose(); + job.KillTimer = null; + } + } + + var process = job.Process; + + var hasExited = true; + + try + { + hasExited = process.HasExited; + } + catch (Win32Exception ex) + { + Logger.ErrorException("Error determining if ffmpeg process has exited for {0}", ex, job.Path); + } + catch (InvalidOperationException ex) + { + Logger.ErrorException("Error determining if ffmpeg process has exited for {0}", ex, job.Path); + } + catch (NotSupportedException ex) + { + Logger.ErrorException("Error determining if ffmpeg process has exited for {0}", ex, job.Path); + } + + if (hasExited) + { + return; + } + + try + { + Logger.Info("Killing ffmpeg process for {0}", job.Path); + + process.Kill(); + } + catch (Win32Exception ex) + { + Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path); + } + catch (InvalidOperationException ex) + { + Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path); + } + catch (NotSupportedException ex) + { + Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path); + } + } + + } + + /// + /// Class TranscodingJob + /// + public class TranscodingJob + { + /// + /// Gets or sets the path. + /// + /// The path. + public string Path { get; set; } + /// + /// Gets or sets the type. + /// + /// The type. + public TranscodingJobType Type { get; set; } + /// + /// Gets or sets the process. + /// + /// The process. + public Process Process { get; set; } + /// + /// Gets or sets the active request count. + /// + /// The active request count. + public int ActiveRequestCount { get; set; } + /// + /// + /// Enum TranscodingJobType + /// + /// + /// Gets or sets the kill timer. + /// + /// The kill timer. + public Timer KillTimer { get; set; } + } + + /// + /// Enum TranscodingJobType + /// + public enum TranscodingJobType + { + /// + /// The progressive + /// + Progressive, + /// + /// The HLS + /// + Hls + } +} -- cgit v1.2.3