aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj1
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs6
-rw-r--r--MediaBrowser.Api/Playback/Hls/BaseHlsService.cs4
-rw-r--r--MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs4
-rw-r--r--MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs2
-rw-r--r--MediaBrowser.Api/Plugin.cs303
-rw-r--r--MediaBrowser.Api/PluginService.cs22
-rw-r--r--MediaBrowser.Api/ServerEntryPoint.cs333
-rw-r--r--MediaBrowser.Common.Implementations/BaseApplicationHost.cs23
-rw-r--r--MediaBrowser.Common/Kernel/BaseKernel.cs80
-rw-r--r--MediaBrowser.Common/Kernel/IApplicationHost.cs15
-rw-r--r--MediaBrowser.Common/Kernel/IKernel.cs15
-rw-r--r--MediaBrowser.Common/Plugins/BasePlugin.cs96
-rw-r--r--MediaBrowser.Common/Plugins/IPlugin.cs34
-rw-r--r--MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs2
-rw-r--r--MediaBrowser.Controller/Kernel.cs24
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj1
-rw-r--r--MediaBrowser.Controller/Plugins/IServerEntryPoint.cs15
-rw-r--r--MediaBrowser.Controller/Updates/InstallationManager.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs5
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj2
-rw-r--r--MediaBrowser.Server.Implementations/packages.config2
-rw-r--r--MediaBrowser.ServerApplication/App.xaml.cs2
-rw-r--r--MediaBrowser.sln3
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec9
-rw-r--r--Nuget/MediaBrowser.Common.nuspec5
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec7
27 files changed, 487 insertions, 534 deletions
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index cf2a55695..97c399fbe 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -97,6 +97,7 @@
<Compile Include="PluginService.cs" />
<Compile Include="ScheduledTasks\ScheduledTaskService.cs" />
<Compile Include="ScheduledTasks\ScheduledTasksWebSocketListener.cs" />
+ <Compile Include="ServerEntryPoint.cs" />
<Compile Include="SystemService.cs" />
<Compile Include="UserLibrary\BaseItemsByNameService.cs" />
<Compile Include="UserLibrary\GenresService.cs" />
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index ce9fe0e0b..980856410 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -518,7 +518,7 @@ namespace MediaBrowser.Api.Playback
EnableRaisingEvents = true
};
- Plugin.Instance.OnTranscodeBeginning(outputPath, TranscodingJobType, process);
+ ServerEntryPoint.Instance.OnTranscodeBeginning(outputPath, TranscodingJobType, process);
//Logger.Info(process.StartInfo.FileName + " " + process.StartInfo.Arguments);
@@ -537,7 +537,7 @@ namespace MediaBrowser.Api.Playback
{
Logger.ErrorException("Error starting ffmpeg", ex);
- Plugin.Instance.OnTranscodeFailedToStart(outputPath, TranscodingJobType);
+ ServerEntryPoint.Instance.OnTranscodeFailedToStart(outputPath, TranscodingJobType);
state.LogFileStream.Dispose();
@@ -588,7 +588,7 @@ namespace MediaBrowser.Api.Playback
process.Dispose();
- Plugin.Instance.OnTranscodingFinished(outputFilePath, TranscodingJobType);
+ ServerEntryPoint.Instance.OnTranscodingFinished(outputFilePath, TranscodingJobType);
if (!exitCode.HasValue || exitCode.Value != 0)
{
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 8c7edbe91..d616565ca 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -77,7 +77,7 @@ namespace MediaBrowser.Api.Playback.Hls
}
else
{
- Plugin.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType.Hls);
+ ServerEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType.Hls);
}
// Get the current playlist text and convert to bytes
@@ -94,7 +94,7 @@ namespace MediaBrowser.Api.Playback.Hls
}
finally
{
- Plugin.Instance.OnTranscodeEndRequest(playlist, TranscodingJobType.Hls);
+ ServerEntryPoint.Instance.OnTranscodeEndRequest(playlist, TranscodingJobType.Hls);
}
}
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index 08e66c387..bbfe65504 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -107,7 +107,7 @@ namespace MediaBrowser.Api.Playback.Progressive
var outputPath = GetOutputFilePath(state);
- if (File.Exists(outputPath) && !Plugin.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive))
+ if (File.Exists(outputPath) && !ServerEntryPoint.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive))
{
return ToStaticFileResult(outputPath);
}
@@ -133,7 +133,7 @@ namespace MediaBrowser.Api.Playback.Progressive
}
else
{
- Plugin.Instance.OnTranscodeBeginRequest(outputPath, TranscodingJobType.Progressive);
+ ServerEntryPoint.Instance.OnTranscodeBeginRequest(outputPath, TranscodingJobType.Progressive);
}
return new ProgressiveStreamWriter
diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
index 9ac93694b..b6b73c78d 100644
--- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
+++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
@@ -41,7 +41,7 @@ namespace MediaBrowser.Api.Playback.Progressive
}
finally
{
- Plugin.Instance.OnTranscodeEndRequest(Path, TranscodingJobType.Progressive);
+ ServerEntryPoint.Instance.OnTranscodeEndRequest(Path, TranscodingJobType.Progressive);
}
}
diff --git a/MediaBrowser.Api/Plugin.cs b/MediaBrowser.Api/Plugin.cs
index 58c0ffcfa..b8c81bbe1 100644
--- a/MediaBrowser.Api/Plugin.cs
+++ b/MediaBrowser.Api/Plugin.cs
@@ -1,12 +1,7 @@
-using MediaBrowser.Common.Plugins;
+using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.Plugins;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Api
{
@@ -16,6 +11,16 @@ namespace MediaBrowser.Api
public class Plugin : BasePlugin<BasePluginConfiguration>
{
/// <summary>
+ /// Initializes a new instance of the <see cref="Plugin" /> class.
+ /// </summary>
+ /// <param name="kernel">The kernel.</param>
+ /// <param name="xmlSerializer">The XML serializer.</param>
+ public Plugin(IKernel kernel, IXmlSerializer xmlSerializer) : base(kernel, xmlSerializer)
+ {
+ Instance = this;
+ }
+
+ /// <summary>
/// Gets the name of the plugin
/// </summary>
/// <value>The name.</value>
@@ -41,287 +46,5 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The instance.</value>
public static Plugin Instance { get; private set; }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Plugin" /> class.
- /// </summary>
- public Plugin()
- {
- Instance = this;
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void DisposeOnServer(bool dispose)
- {
- if (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);
- }
- }
-
- base.DisposeOnServer(dispose);
- }
-
- /// <summary>
- /// The active transcoding jobs
- /// </summary>
- private readonly List<TranscodingJob> ActiveTranscodingJobs = new List<TranscodingJob>();
-
- /// <summary>
- /// Called when [transcode beginning].
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="type">The type.</param>
- /// <param name="process">The process.</param>
- public void OnTranscodeBeginning(string path, TranscodingJobType type, Process process)
- {
- lock (ActiveTranscodingJobs)
- {
- ActiveTranscodingJobs.Add(new TranscodingJob
- {
- Type = type,
- Path = path,
- Process = process,
- ActiveRequestCount = 1
- });
- }
- }
-
- /// <summary>
- /// Called when [transcode failed to start].
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="type">The type.</param>
- 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);
- }
- }
-
- /// <summary>
- /// Determines whether [has active transcoding job] [the specified path].
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="type">The type.</param>
- /// <returns><c>true</c> if [has active transcoding job] [the specified path]; otherwise, <c>false</c>.</returns>
- public bool HasActiveTranscodingJob(string path, TranscodingJobType type)
- {
- lock (ActiveTranscodingJobs)
- {
- return ActiveTranscodingJobs.Any(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase));
- }
- }
-
- /// <summary>
- /// Called when [transcode begin request].
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="type">The type.</param>
- 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;
- }
- }
- }
-
- /// <summary>
- /// Called when [transcode end request].
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="type">The type.</param>
- 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);
- }
- }
- }
- }
-
- /// <summary>
- /// Called when [transcoding finished].
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="type">The type.</param>
- 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;
- }
- }
- }
-
- /// <summary>
- /// Called when [transcode kill timer stopped].
- /// </summary>
- /// <param name="state">The state.</param>
- 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);
- }
- }
- }
-
- /// <summary>
- /// Class TranscodingJob
- /// </summary>
- public class TranscodingJob
- {
- /// <summary>
- /// Gets or sets the path.
- /// </summary>
- /// <value>The path.</value>
- public string Path { get; set; }
- /// <summary>
- /// Gets or sets the type.
- /// </summary>
- /// <value>The type.</value>
- public TranscodingJobType Type { get; set; }
- /// <summary>
- /// Gets or sets the process.
- /// </summary>
- /// <value>The process.</value>
- public Process Process { get; set; }
- /// <summary>
- /// Gets or sets the active request count.
- /// </summary>
- /// <value>The active request count.</value>
- public int ActiveRequestCount { get; set; }
- /// <summary>
- /// Gets or sets the kill timer.
- /// </summary>
- /// <value>The kill timer.</value>
- public Timer KillTimer { get; set; }
- }
-
- /// <summary>
- /// Enum TranscodingJobType
- /// </summary>
- public enum TranscodingJobType
- {
- /// <summary>
- /// The progressive
- /// </summary>
- Progressive,
- /// <summary>
- /// The HLS
- /// </summary>
- Hls
}
}
diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs
index 06db7a276..7e907c2dd 100644
--- a/MediaBrowser.Api/PluginService.cs
+++ b/MediaBrowser.Api/PluginService.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Implementations.HttpServer;
+using MediaBrowser.Common.Kernel;
using MediaBrowser.Controller;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Plugins;
@@ -124,11 +125,17 @@ namespace MediaBrowser.Api
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
+ /// The _app host
+ /// </summary>
+ private readonly IApplicationHost _appHost;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="PluginService" /> class.
/// </summary>
/// <param name="jsonSerializer">The json serializer.</param>
+ /// <param name="appHost">The app host.</param>
/// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
- public PluginService(IJsonSerializer jsonSerializer)
+ public PluginService(IJsonSerializer jsonSerializer, IApplicationHost appHost)
: base()
{
if (jsonSerializer == null)
@@ -136,6 +143,7 @@ namespace MediaBrowser.Api
throw new ArgumentNullException("jsonSerializer");
}
+ _appHost = appHost;
_jsonSerializer = jsonSerializer;
}
@@ -146,7 +154,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetPlugins request)
{
- var result = Kernel.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToList();
+ var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToList();
return ToOptimizedResult(result);
}
@@ -158,7 +166,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetPluginAssembly request)
{
- var plugin = Kernel.Plugins.First(p => p.Id == request.Id);
+ var plugin = _appHost.Plugins.First(p => p.Id == request.Id);
return ToStaticFileResult(plugin.AssemblyFilePath);
}
@@ -170,7 +178,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetPluginConfiguration request)
{
- var plugin = Kernel.Plugins.First(p => p.Id == request.Id);
+ var plugin = _appHost.Plugins.First(p => p.Id == request.Id);
var dateModified = plugin.ConfigurationDateLastModified;
@@ -186,7 +194,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetPluginConfigurationFile request)
{
- var plugin = Kernel.Plugins.First(p => p.Id == request.Id);
+ var plugin = _appHost.Plugins.First(p => p.Id == request.Id);
return ToStaticFileResult(plugin.ConfigurationFilePath);
}
@@ -235,7 +243,7 @@ namespace MediaBrowser.Api
var pathInfo = PathInfo.Parse(Request.PathInfo);
var id = new Guid(pathInfo.GetArgumentValue<string>(1));
- var plugin = Kernel.Plugins.First(p => p.Id == id);
+ var plugin = _appHost.Plugins.First(p => p.Id == id);
var configuration = _jsonSerializer.DeserializeFromStream(request.RequestStream, plugin.ConfigurationType) as BasePluginConfiguration;
@@ -250,7 +258,7 @@ namespace MediaBrowser.Api
{
var kernel = (Kernel)Kernel;
- var plugin = kernel.Plugins.First(p => p.Id == request.Id);
+ var plugin = _appHost.Plugins.First(p => p.Id == request.Id);
kernel.InstallationManager.UninstallPlugin(plugin);
}
diff --git a/MediaBrowser.Api/ServerEntryPoint.cs b/MediaBrowser.Api/ServerEntryPoint.cs
new file mode 100644
index 000000000..663d1aeca
--- /dev/null
+++ b/MediaBrowser.Api/ServerEntryPoint.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
+{
+ /// <summary>
+ /// Class ServerEntryPoint
+ /// </summary>
+ public class ServerEntryPoint : IServerEntryPoint
+ {
+ /// <summary>
+ /// The instance
+ /// </summary>
+ public static ServerEntryPoint Instance;
+
+ /// <summary>
+ /// Gets or sets the logger.
+ /// </summary>
+ /// <value>The logger.</value>
+ private ILogger Logger { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ServerEntryPoint" /> class.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ public ServerEntryPoint(ILogger logger)
+ {
+ Logger = logger;
+
+ Instance = this;
+ }
+
+ /// <summary>
+ /// Runs this instance.
+ /// </summary>
+ public void Run()
+ {
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources.
+ /// </summary>
+ /// <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 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);
+ }
+ }
+
+ /// <summary>
+ /// The active transcoding jobs
+ /// </summary>
+ private readonly List<TranscodingJob> ActiveTranscodingJobs = new List<TranscodingJob>();
+
+ /// <summary>
+ /// Called when [transcode beginning].
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="type">The type.</param>
+ /// <param name="process">The process.</param>
+ public void OnTranscodeBeginning(string path, TranscodingJobType type, Process process)
+ {
+ lock (ActiveTranscodingJobs)
+ {
+ ActiveTranscodingJobs.Add(new TranscodingJob
+ {
+ Type = type,
+ Path = path,
+ Process = process,
+ ActiveRequestCount = 1
+ });
+ }
+ }
+
+ /// <summary>
+ /// <summary>
+ /// The progressive
+ /// </summary>
+ /// Called when [transcode failed to start].
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="type">The type.</param>
+ 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);
+ }
+ }
+
+ /// <summary>
+ /// Determines whether [has active transcoding job] [the specified path].
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="type">The type.</param>
+ /// <returns><c>true</c> if [has active transcoding job] [the specified path]; otherwise, <c>false</c>.</returns>
+ public bool HasActiveTranscodingJob(string path, TranscodingJobType type)
+ {
+ lock (ActiveTranscodingJobs)
+ {
+ return ActiveTranscodingJobs.Any(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase));
+ }
+ }
+
+ /// <summary>
+ /// Called when [transcode begin request].
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="type">The type.</param>
+ 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;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called when [transcode end request].
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="type">The type.</param>
+ 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);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called when [transcoding finished].
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="type">The type.</param>
+ 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;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called when [transcode kill timer stopped].
+ /// </summary>
+ /// <param name="state">The state.</param>
+ 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);
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// Class TranscodingJob
+ /// </summary>
+ public class TranscodingJob
+ {
+ /// <summary>
+ /// Gets or sets the path.
+ /// </summary>
+ /// <value>The path.</value>
+ public string Path { get; set; }
+ /// <summary>
+ /// Gets or sets the type.
+ /// </summary>
+ /// <value>The type.</value>
+ public TranscodingJobType Type { get; set; }
+ /// <summary>
+ /// Gets or sets the process.
+ /// </summary>
+ /// <value>The process.</value>
+ public Process Process { get; set; }
+ /// <summary>
+ /// Gets or sets the active request count.
+ /// </summary>
+ /// <value>The active request count.</value>
+ public int ActiveRequestCount { get; set; }
+ /// <summary>
+ /// <summary>
+ /// Enum TranscodingJobType
+ /// </summary>
+ /// <summary>
+ /// Gets or sets the kill timer.
+ /// </summary>
+ /// <value>The kill timer.</value>
+ public Timer KillTimer { get; set; }
+ }
+
+ /// <summary>
+ /// Enum TranscodingJobType
+ /// </summary>
+ public enum TranscodingJobType
+ {
+ /// <summary>
+ /// The progressive
+ /// </summary>
+ Progressive,
+ /// <summary>
+ /// The HLS
+ /// </summary>
+ Hls
+ }
+}
diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
index f23d859e8..3d7421f67 100644
--- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
+++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.Implementations.Updates;
using MediaBrowser.Common.Implementations.WebSocket;
using MediaBrowser.Common.Kernel;
using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Common.Updates;
using MediaBrowser.Model.Logging;
@@ -26,6 +27,12 @@ namespace MediaBrowser.Common.Implementations
public ILogger Logger { get; protected set; }
/// <summary>
+ /// Gets or sets the plugins.
+ /// </summary>
+ /// <value>The plugins.</value>
+ public IEnumerable<IPlugin> Plugins { get; protected set; }
+
+ /// <summary>
/// Gets or sets the log manager.
/// </summary>
/// <value>The log manager.</value>
@@ -142,12 +149,13 @@ namespace MediaBrowser.Common.Implementations
/// </summary>
protected virtual void FindParts()
{
- Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false));
-
Resolve<IHttpServer>().Init(GetExports<IRestfulService>(false));
Resolve<IServerManager>().AddWebSocketListeners(GetExports<IWebSocketListener>(false));
Resolve<IServerManager>().Start();
+ Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false));
+
+ Plugins = GetExports<IPlugin>();
}
/// <summary>
@@ -349,6 +357,17 @@ namespace MediaBrowser.Common.Implementations
}
/// <summary>
+ /// Removes the plugin.
+ /// </summary>
+ /// <param name="plugin">The plugin.</param>
+ public void RemovePlugin(IPlugin plugin)
+ {
+ var list = Plugins.ToList();
+ list.Remove(plugin);
+ Plugins = list;
+ }
+
+ /// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
diff --git a/MediaBrowser.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs
index 78277ed2f..d35ee42c9 100644
--- a/MediaBrowser.Common/Kernel/BaseKernel.cs
+++ b/MediaBrowser.Common/Kernel/BaseKernel.cs
@@ -1,16 +1,13 @@
using MediaBrowser.Common.Events;
-using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Security;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
using System;
-using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
-using System.Threading.Tasks;
namespace MediaBrowser.Common.Kernel
{
@@ -122,12 +119,6 @@ namespace MediaBrowser.Common.Kernel
public TApplicationPathsType ApplicationPaths { get; private set; }
/// <summary>
- /// Gets the list of currently loaded plugins
- /// </summary>
- /// <value>The plugins.</value>
- public IEnumerable<IPlugin> Plugins { get; protected set; }
-
- /// <summary>
/// Gets or sets the TCP manager.
/// </summary>
/// <value>The TCP manager.</value>
@@ -211,9 +202,9 @@ namespace MediaBrowser.Common.Kernel
/// Initializes the Kernel
/// </summary>
/// <returns>Task.</returns>
- public async Task Init()
+ public void Init()
{
- await ReloadInternal().ConfigureAwait(false);
+ ReloadInternal();
OnReloadCompleted();
@@ -224,65 +215,12 @@ namespace MediaBrowser.Common.Kernel
/// Performs initializations that can be reloaded at anytime
/// </summary>
/// <returns>Task.</returns>
- protected virtual async Task ReloadInternal()
+ protected virtual void ReloadInternal()
{
- // Set these to null so that they can be lazy loaded again
- Configuration = null;
-
- await OnConfigurationLoaded().ConfigureAwait(false);
-
- FindParts();
-
- await OnComposablePartsLoaded().ConfigureAwait(false);
-
ServerManager = ApplicationHost.Resolve<IServerManager>();
}
/// <summary>
- /// Called when [configuration loaded].
- /// </summary>
- /// <returns>Task.</returns>
- protected virtual Task OnConfigurationLoaded()
- {
- return Task.FromResult<object>(null);
- }
-
- /// <summary>
- /// Composes the parts with ioc container.
- /// </summary>
- protected virtual void FindParts()
- {
- Plugins = ApplicationHost.GetExports<IPlugin>();
- }
-
- /// <summary>
- /// Fires after MEF finishes finding composable parts within plugin assemblies
- /// </summary>
- /// <returns>Task.</returns>
- protected virtual Task OnComposablePartsLoaded()
- {
- return Task.Run(() =>
- {
- // Start-up each plugin
- Parallel.ForEach(Plugins, plugin =>
- {
- Logger.Info("Initializing {0} {1}", plugin.Name, plugin.Version);
-
- try
- {
- plugin.Initialize(this, _xmlSerializer, Logger);
-
- Logger.Info("{0} {1} initialized.", plugin.Name, plugin.Version);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error initializing {0}", ex, plugin.Name);
- }
- });
- });
- }
-
- /// <summary>
/// Notifies that the kernel that a change has been made that requires a restart
/// </summary>
public void NotifyPendingRestart()
@@ -442,17 +380,5 @@ namespace MediaBrowser.Common.Kernel
/// </summary>
/// <value>The resource pools.</value>
public ResourcePool ResourcePools { get; set; }
-
- /// <summary>
- /// Removes the plugin.
- /// </summary>
- /// <param name="plugin">The plugin.</param>
- public void RemovePlugin(IPlugin plugin)
- {
- var list = Plugins.ToList();
- list.Remove(plugin);
- Plugins = list;
- }
-
}
}
diff --git a/MediaBrowser.Common/Kernel/IApplicationHost.cs b/MediaBrowser.Common/Kernel/IApplicationHost.cs
index bb007ddff..29934988a 100644
--- a/MediaBrowser.Common/Kernel/IApplicationHost.cs
+++ b/MediaBrowser.Common/Kernel/IApplicationHost.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Model.Updates;
+using MediaBrowser.Common.Plugins;
+using MediaBrowser.Model.Updates;
using System;
using System.Collections.Generic;
using System.Threading;
@@ -97,5 +98,17 @@ namespace MediaBrowser.Common.Kernel
/// Shuts down.
/// </summary>
void Shutdown();
+
+ /// <summary>
+ /// Gets the plugins.
+ /// </summary>
+ /// <value>The plugins.</value>
+ IEnumerable<IPlugin> Plugins { get; }
+
+ /// <summary>
+ /// Removes the plugin.
+ /// </summary>
+ /// <param name="plugin">The plugin.</param>
+ void RemovePlugin(IPlugin plugin);
}
}
diff --git a/MediaBrowser.Common/Kernel/IKernel.cs b/MediaBrowser.Common/Kernel/IKernel.cs
index d02f0af20..0d123476c 100644
--- a/MediaBrowser.Common/Kernel/IKernel.cs
+++ b/MediaBrowser.Common/Kernel/IKernel.cs
@@ -40,7 +40,7 @@ namespace MediaBrowser.Common.Kernel
/// Inits this instance.
/// </summary>
/// <returns>Task.</returns>
- Task Init();
+ void Init();
/// <summary>
/// Gets or sets a value indicating whether this instance has pending kernel reload.
@@ -72,12 +72,6 @@ namespace MediaBrowser.Common.Kernel
void PerformPendingRestart();
/// <summary>
- /// Gets the plugins.
- /// </summary>
- /// <value>The plugins.</value>
- IEnumerable<IPlugin> Plugins { get; }
-
- /// <summary>
/// Gets the UDP server port number.
/// </summary>
/// <value>The UDP server port number.</value>
@@ -123,12 +117,5 @@ namespace MediaBrowser.Common.Kernel
/// </summary>
/// <value>The resource pools.</value>
ResourcePool ResourcePools { get; set; }
-
- /// <summary>
- /// Removes the plugin.
- /// </summary>
- /// <param name="plugin">The plugin.</param>
- void RemovePlugin(IPlugin plugin);
-
}
}
diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs
index 0d7c5c060..c968a65c8 100644
--- a/MediaBrowser.Common/Plugins/BasePlugin.cs
+++ b/MediaBrowser.Common/Plugins/BasePlugin.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Common.Kernel;
-using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Plugins;
using MediaBrowser.Model.Serialization;
using System;
@@ -14,7 +13,7 @@ namespace MediaBrowser.Common.Plugins
/// Provides a common base class for all plugins
/// </summary>
/// <typeparam name="TConfigurationType">The type of the T configuration type.</typeparam>
- public abstract class BasePlugin<TConfigurationType> : IDisposable, IPlugin
+ public abstract class BasePlugin<TConfigurationType> : IPlugin
where TConfigurationType : BasePluginConfiguration
{
/// <summary>
@@ -24,6 +23,12 @@ namespace MediaBrowser.Common.Plugins
protected IKernel Kernel { get; private set; }
/// <summary>
+ /// Gets the XML serializer.
+ /// </summary>
+ /// <value>The XML serializer.</value>
+ protected IXmlSerializer XmlSerializer { get; private set; }
+
+ /// <summary>
/// Gets or sets the plugin's current context
/// </summary>
/// <value>The context.</value>
@@ -57,6 +62,12 @@ namespace MediaBrowser.Common.Plugins
}
/// <summary>
+ /// Gets a value indicating whether this instance is first run.
+ /// </summary>
+ /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
+ public bool IsFirstRun { get; private set; }
+
+ /// <summary>
/// Gets the type of configuration this plugin uses
/// </summary>
/// <value>The type of the configuration.</value>
@@ -252,87 +263,14 @@ namespace MediaBrowser.Common.Plugins
}
/// <summary>
- /// Gets the logger.
- /// </summary>
- /// <value>The logger.</value>
- public ILogger Logger { get; private set; }
-
- /// <summary>
- /// Gets the XML serializer.
- /// </summary>
- /// <value>The XML serializer.</value>
- protected IXmlSerializer XmlSerializer { get; private set; }
-
- /// <summary>
- /// Starts the plugin.
+ /// Initializes a new instance of the <see cref="BasePlugin{TConfigurationType}" /> class.
/// </summary>
/// <param name="kernel">The kernel.</param>
/// <param name="xmlSerializer">The XML serializer.</param>
- /// <param name="logger">The logger.</param>
- /// <exception cref="System.ArgumentNullException">kernel</exception>
- public void Initialize(IKernel kernel, IXmlSerializer xmlSerializer, ILogger logger)
+ protected BasePlugin(IKernel kernel, IXmlSerializer xmlSerializer)
{
- if (kernel == null)
- {
- throw new ArgumentNullException("kernel");
- }
-
- if (xmlSerializer == null)
- {
- throw new ArgumentNullException("xmlSerializer");
- }
-
- if (logger == null)
- {
- throw new ArgumentNullException("logger");
- }
-
- XmlSerializer = xmlSerializer;
- Logger = logger;
Kernel = kernel;
-
- if (kernel.KernelContext == KernelContext.Server)
- {
- InitializeOnServer(!File.Exists(ConfigurationFilePath));
- }
- }
-
- /// <summary>
- /// Starts the plugin on the server
- /// </summary>
- /// <param name="isFirstRun">if set to <c>true</c> [is first run].</param>
- protected virtual void InitializeOnServer(bool isFirstRun)
- {
- }
-
- /// <summary>
- /// Disposes the plugins. Undos all actions performed during Init.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected void Dispose(bool dispose)
- {
- if (Kernel.KernelContext == KernelContext.Server)
- {
- DisposeOnServer(dispose);
- }
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <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 DisposeOnServer(bool dispose)
- {
-
+ XmlSerializer = xmlSerializer;
}
/// <summary>
@@ -351,8 +289,6 @@ namespace MediaBrowser.Common.Plugins
throw new InvalidOperationException("Cannot call Plugin.SaveConfiguration from the UI.");
}
- Logger.Info("Saving configuration");
-
lock (_configurationSaveLock)
{
XmlSerializer.SerializeToFile(Configuration, ConfigurationFilePath);
diff --git a/MediaBrowser.Common/Plugins/IPlugin.cs b/MediaBrowser.Common/Plugins/IPlugin.cs
index 7d5fddb9a..ace82d83f 100644
--- a/MediaBrowser.Common/Plugins/IPlugin.cs
+++ b/MediaBrowser.Common/Plugins/IPlugin.cs
@@ -1,11 +1,11 @@
-using MediaBrowser.Common.Kernel;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Plugins;
-using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Plugins;
using System;
namespace MediaBrowser.Common.Plugins
{
+ /// <summary>
+ /// Interface IPlugin
+ /// </summary>
public interface IPlugin
{
/// <summary>
@@ -93,26 +93,6 @@ namespace MediaBrowser.Common.Plugins
string DataFolderPath { get; }
/// <summary>
- /// Gets the logger.
- /// </summary>
- /// <value>The logger.</value>
- ILogger Logger { get; }
-
- /// <summary>
- /// Starts the plugin.
- /// </summary>
- /// <param name="kernel">The kernel.</param>
- /// <param name="xmlSerializer">The XML serializer.</param>
- /// <param name="logger">The logger.</param>
- /// <exception cref="System.ArgumentNullException">kernel</exception>
- void Initialize(IKernel kernel, IXmlSerializer xmlSerializer, ILogger logger);
-
- /// <summary>
- /// Disposes the plugins. Undos all actions performed during Init.
- /// </summary>
- void Dispose();
-
- /// <summary>
/// Saves the current configuration to the file system
/// </summary>
/// <exception cref="System.InvalidOperationException">Cannot call Plugin.SaveConfiguration from the UI.</exception>
@@ -136,5 +116,11 @@ namespace MediaBrowser.Common.Plugins
/// Called when just before the plugin is uninstalled from the server.
/// </summary>
void OnUninstalling();
+
+ /// <summary>
+ /// Gets a value indicating whether this instance is first run.
+ /// </summary>
+ /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
+ bool IsFirstRun { get; }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs b/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs
index e48551425..6dc5c6b38 100644
--- a/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs
+++ b/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs
@@ -16,7 +16,7 @@ namespace MediaBrowser.Common.ScheduledTasks
{
if (isApplicationStartup)
{
- await Task.Delay(2000).ConfigureAwait(false);
+ await Task.Delay(3000).ConfigureAwait(false);
OnTriggered();
}
diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs
index 16175783f..99e0ef783 100644
--- a/MediaBrowser.Controller/Kernel.cs
+++ b/MediaBrowser.Controller/Kernel.cs
@@ -183,7 +183,7 @@ namespace MediaBrowser.Controller
/// <summary>
/// Composes the parts with ioc container.
/// </summary>
- protected override void FindParts()
+ protected void FindParts()
{
// For now there's no real way to inject this properly
BaseItem.LibraryManager = ApplicationHost.Resolve<ILibraryManager>();
@@ -194,8 +194,6 @@ namespace MediaBrowser.Controller
ProviderManager = (ProviderManager)ApplicationHost.CreateInstance(typeof(ProviderManager));
SecurityManager = (PluginSecurityManager)ApplicationHost.CreateInstance(typeof(PluginSecurityManager));
- base.FindParts();
-
UserDataRepositories = ApplicationHost.GetExports<IUserDataRepository>();
UserRepositories = ApplicationHost.GetExports<IUserRepository>();
DisplayPreferencesRepositories = ApplicationHost.GetExports<IDisplayPreferencesRepository>();
@@ -211,15 +209,24 @@ namespace MediaBrowser.Controller
/// Performs initializations that can be reloaded at anytime
/// </summary>
/// <returns>Task.</returns>
- protected override async Task ReloadInternal()
+ protected override async void ReloadInternal()
{
- await base.ReloadInternal().ConfigureAwait(false);
+ base.ReloadInternal();
+
+ FindParts();
+
+ await LoadRepositories().ConfigureAwait(false);
ReloadResourcePools();
ReloadFileSystemManager();
await ApplicationHost.Resolve<IUserManager>().RefreshUsersMetadata(CancellationToken.None).ConfigureAwait(false);
+
+ foreach (var entryPoint in ApplicationHost.GetExports<IServerEntryPoint>())
+ {
+ entryPoint.Run();
+ }
}
/// <summary>
@@ -263,11 +270,8 @@ namespace MediaBrowser.Controller
/// Called when [composable parts loaded].
/// </summary>
/// <returns>Task.</returns>
- protected override async Task OnComposablePartsLoaded()
+ protected Task LoadRepositories()
{
- // The base class will start up all the plugins
- await base.OnComposablePartsLoaded().ConfigureAwait(false);
-
// Get the current item repository
ItemRepository = GetRepository(ItemRepositories, Configuration.ItemRepository);
var itemRepoTask = ItemRepository.Initialize();
@@ -284,7 +288,7 @@ namespace MediaBrowser.Controller
DisplayPreferencesRepository = GetRepository(DisplayPreferencesRepositories, Configuration.DisplayPreferencesRepository);
var displayPreferencesRepoTask = DisplayPreferencesRepository.Initialize();
- await Task.WhenAll(itemRepoTask, userRepoTask, userDataRepoTask, displayPreferencesRepoTask).ConfigureAwait(false);
+ return Task.WhenAll(itemRepoTask, userRepoTask, userDataRepoTask, displayPreferencesRepoTask);
}
/// <summary>
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 71116881e..63468a8e8 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -131,6 +131,7 @@
<Compile Include="Persistence\IUserRepository.cs" />
<Compile Include="Library\IIntroProvider.cs" />
<Compile Include="Plugins\IPluginConfigurationPage.cs" />
+ <Compile Include="Plugins\IServerEntryPoint.cs" />
<Compile Include="Plugins\PluginSecurityManager.cs" />
<Compile Include="Providers\FanartBaseProvider.cs" />
<Compile Include="Providers\IImageEnhancer.cs" />
diff --git a/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs b/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs
new file mode 100644
index 000000000..de6de8f84
--- /dev/null
+++ b/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace MediaBrowser.Controller.Plugins
+{
+ /// <summary>
+ /// Interface IServerEntryPoint
+ /// </summary>
+ public interface IServerEntryPoint : IDisposable
+ {
+ /// <summary>
+ /// Runs this instance.
+ /// </summary>
+ void Run();
+ }
+}
diff --git a/MediaBrowser.Controller/Updates/InstallationManager.cs b/MediaBrowser.Controller/Updates/InstallationManager.cs
index d616e8898..f67f690ae 100644
--- a/MediaBrowser.Controller/Updates/InstallationManager.cs
+++ b/MediaBrowser.Controller/Updates/InstallationManager.cs
@@ -287,7 +287,7 @@ namespace MediaBrowser.Controller.Updates
{
var catalog = await GetAvailablePackages(cancellationToken).ConfigureAwait(false);
- var plugins = Kernel.Plugins;
+ var plugins = ApplicationHost.Plugins;
if (withAutoUpdateEnabled)
{
@@ -424,7 +424,7 @@ namespace MediaBrowser.Controller.Updates
if (!(Path.GetExtension(package.targetFilename) ?? "").Equals(".zip", StringComparison.OrdinalIgnoreCase))
{
// Set last update time if we were installed before
- var plugin = Kernel.Plugins.FirstOrDefault(p => p.Name.Equals(package.name, StringComparison.OrdinalIgnoreCase));
+ var plugin = ApplicationHost.Plugins.FirstOrDefault(p => p.Name.Equals(package.name, StringComparison.OrdinalIgnoreCase));
if (plugin != null)
{
@@ -460,7 +460,7 @@ namespace MediaBrowser.Controller.Updates
plugin.OnUninstalling();
// Remove it the quick way for now
- Kernel.RemovePlugin(plugin);
+ ApplicationHost.RemovePlugin(plugin);
File.Delete(plugin.AssemblyFilePath);
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index 18108842f..ba54b5d2b 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -287,11 +287,6 @@ namespace MediaBrowser.Server.Implementations.Library
/// <exception cref="System.InvalidOperationException">Cannot create the root folder until plugins have loaded</exception>
public AggregateFolder CreateRootFolder()
{
- if (Kernel.Plugins == null)
- {
- throw new InvalidOperationException("Cannot create the root folder until plugins have loaded");
- }
-
var rootFolderPath = Kernel.ApplicationPaths.RootFolderPath;
var rootFolder = Kernel.ItemRepository.RetrieveItem(rootFolderPath.GetMBId(typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)ResolvePath(rootFolderPath);
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index f18df77c2..83136aed9 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -34,7 +34,7 @@
<ItemGroup>
<Reference Include="BdInfo, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.0\lib\net45\BdInfo.dll</HintPath>
+ <HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.2\lib\net45\BdInfo.dll</HintPath>
</Reference>
<Reference Include="MoreLinq">
<HintPath>..\packages\morelinq.1.0.15631-beta\lib\net35\MoreLinq.dll</HintPath>
diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config
index c20edb5ab..fb84d9aa7 100644
--- a/MediaBrowser.Server.Implementations/packages.config
+++ b/MediaBrowser.Server.Implementations/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="MediaBrowser.BdInfo" version="1.0.0.0" targetFramework="net45" />
+ <package id="MediaBrowser.BdInfo" version="1.0.0.2" targetFramework="net45" />
<package id="morelinq" version="1.0.15631-beta" targetFramework="net45" />
<package id="System.Data.SQLite" version="1.0.84.0" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/App.xaml.cs b/MediaBrowser.ServerApplication/App.xaml.cs
index dddd87782..95ece67e6 100644
--- a/MediaBrowser.ServerApplication/App.xaml.cs
+++ b/MediaBrowser.ServerApplication/App.xaml.cs
@@ -177,7 +177,7 @@ namespace MediaBrowser.ServerApplication
var now = DateTime.UtcNow;
- await Kernel.Init();
+ Kernel.Init();
var done = (DateTime.UtcNow - now);
Logger.Info("Kernel.Init completed in {0}{1} minutes and {2} seconds.", done.Hours > 0 ? done.Hours + " Hours " : "", done.Minutes, done.Seconds);
diff --git a/MediaBrowser.sln b/MediaBrowser.sln
index b473b2062..0fe54d005 100644
--- a/MediaBrowser.sln
+++ b/MediaBrowser.sln
@@ -253,4 +253,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(Performance) = preSolution
+ HasPerformanceSessions = true
+ EndGlobalSection
EndGlobal
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index c005b145b..cc6679348 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,16 +2,17 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.22</version>
- <title />
+ <version>3.0.23</version>
+ <title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
- <owners>Media Browser Team</owners>
+ <owners>ebr,Luke,scottisafool</owners>
<projectUrl>https://github.com/MediaBrowser/MediaBrowser</projectUrl>
<iconUrl>http://www.mb3admin.com/images/mb3icons1-1.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Contains common components shared by Media Browser Theatre and Media Browser Server. Not intended for plugin developer consumption.</description>
+ <copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.22" />
+ <dependency id="MediaBrowser.Common" version="3.0.23" />
<dependency id="NLog" version="2.0.0.2000" />
<dependency id="ServiceStack" version="3.9.37" />
<dependency id="ServiceStack.Api.Swagger" version="3.9.35" />
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index bd5363302..cf832f548 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,13 +2,14 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.22</version>
+ <version>3.0.23</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
- <owners />
+ <owners>ebr,Luke,scottisafool</owners>
<projectUrl>https://github.com/MediaBrowser/MediaBrowser</projectUrl>
<iconUrl>http://www.mb3admin.com/images/mb3icons1-1.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <copyright>Copyright © Media Browser 2013</copyright>
<description>Contains common model objects and interfaces used by all Media Browser solutions.</description>
</metadata>
<files>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index be7a20a8a..7a195fe55 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,16 +2,17 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.22</version>
+ <version>3.0.23</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
- <owners />
+ <owners>ebr,Luke,scottisafool</owners>
<projectUrl>https://github.com/MediaBrowser/MediaBrowser</projectUrl>
<iconUrl>http://www.mb3admin.com/images/mb3icons1-1.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Contains core components required to build plugins for Media Browser Server.</description>
+ <copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.22" />
+ <dependency id="MediaBrowser.Common" version="3.0.23" />
</dependencies>
</metadata>
<files>