diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 8f92f062c..13d184b59 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -59,6 +59,7 @@
+
diff --git a/Emby.Server.Implementations/EntryPoints/SystemEvents.cs b/Emby.Server.Implementations/EntryPoints/SystemEvents.cs
new file mode 100644
index 000000000..021ae47ec
--- /dev/null
+++ b/Emby.Server.Implementations/EntryPoints/SystemEvents.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using MediaBrowser.Model.System;
+using MediaBrowser.Controller.Plugins;
+using MediaBrowser.Common;
+
+namespace Emby.Server.Implementations.EntryPoints
+{
+ public class SystemEvents : IServerEntryPoint
+ {
+ private readonly ISystemEvents _systemEvents;
+ private readonly IApplicationHost _appHost;
+
+ public SystemEvents(ISystemEvents systemEvents, IApplicationHost appHost)
+ {
+ _systemEvents = systemEvents;
+ _appHost = appHost;
+ }
+
+ public void Run()
+ {
+ _systemEvents.SessionLogoff += _systemEvents_SessionLogoff;
+ _systemEvents.SystemShutdown += _systemEvents_SystemShutdown;
+ }
+
+ private void _systemEvents_SessionLogoff(object sender, EventArgs e)
+ {
+ if (!_appHost.IsRunningAsService)
+ {
+ _appHost.Shutdown();
+ }
+ }
+
+ private void _systemEvents_SystemShutdown(object sender, EventArgs e)
+ {
+ _appHost.Shutdown();
+ }
+
+ public void Dispose()
+ {
+ _systemEvents.SystemShutdown -= _systemEvents_SystemShutdown;
+ }
+ }
+}
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index a52ac0e60..ba1f23dfe 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -542,8 +542,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
// Must consume both or ffmpeg may hang due to deadlocks. See comments below.
RedirectStandardOutput = true,
- //RedirectStandardError = true,
- RedirectStandardInput = false,
FileName = FFProbePath,
Arguments = string.Format(args, probeSizeArgument, inputPath).Trim(),
@@ -554,7 +552,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
- using (var processWrapper = new ProcessWrapper(process, this, _logger, false))
+ using (var processWrapper = new ProcessWrapper(process, this, _logger))
{
await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
@@ -616,7 +614,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
catch
{
- StopProcess(processWrapper, 100, true);
+ StopProcess(processWrapper, 100);
throw;
}
@@ -671,9 +669,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
UseShellExecute = false,
// Must consume both or ffmpeg may hang due to deadlocks. See comments below.
- //RedirectStandardOutput = true,
RedirectStandardError = true,
- RedirectStandardInput = false,
FileName = FFMpegPath,
Arguments = string.Format(args, probeSizeArgument, inputPath, videoStream.Index.ToString(CultureInfo.InvariantCulture)).Trim(),
@@ -685,7 +681,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
var idetFoundInterlaced = false;
- using (var processWrapper = new ProcessWrapper(process, this, _logger, false))
+ using (var processWrapper = new ProcessWrapper(process, this, _logger))
{
try
{
@@ -728,7 +724,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
catch
{
- StopProcess(processWrapper, 100, true);
+ StopProcess(processWrapper, 100);
throw;
}
@@ -945,7 +941,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
- using (var processWrapper = new ProcessWrapper(process, this, _logger, false))
+ using (var processWrapper = new ProcessWrapper(process, this, _logger))
{
await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
@@ -965,7 +961,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!ranToCompletion)
{
- StopProcess(processWrapper, 1000, false);
+ StopProcess(processWrapper, 1000);
}
}
@@ -1043,8 +1039,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
FileName = FFMpegPath,
Arguments = args,
IsHidden = true,
- ErrorDialog = false,
- RedirectStandardInput = true
+ ErrorDialog = false
});
_logger.Info(process.StartInfo.FileName + " " + process.StartInfo.Arguments);
@@ -1053,7 +1048,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
bool ranToCompletion = false;
- using (var processWrapper = new ProcessWrapper(process, this, _logger, true))
+ using (var processWrapper = new ProcessWrapper(process, this, _logger))
{
try
{
@@ -1085,7 +1080,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!ranToCompletion)
{
- StopProcess(processWrapper, 1000, false);
+ StopProcess(processWrapper, 1000);
}
}
finally
@@ -1157,40 +1152,25 @@ namespace MediaBrowser.MediaEncoding.Encoder
_runningProcesses.Add(process);
}
}
- private void StopProcess(ProcessWrapper process, int waitTimeMs, bool enableForceKill)
+ private void StopProcess(ProcessWrapper process, int waitTimeMs)
{
+ try
+ {
+ if (process.Process.WaitForExit(waitTimeMs))
+ {
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Error("Error in WaitForExit", ex);
+ }
+
try
{
_logger.Info("Killing ffmpeg process");
- if (process.IsRedirectingStdin)
- {
- try
- {
- process.Process.StandardInput.WriteLine("q");
- }
- catch (Exception)
- {
- _logger.Error("Error sending q command to process");
- }
- }
-
- try
- {
- if (process.Process.WaitForExit(waitTimeMs))
- {
- return;
- }
- }
- catch (Exception ex)
- {
- _logger.Error("Error in WaitForExit", ex);
- }
-
- if (enableForceKill)
- {
- process.Process.Kill();
- }
+ process.Process.Kill();
}
catch (Exception ex)
{
@@ -1211,7 +1191,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
if (!process.HasExited)
{
- StopProcess(process, 500, true);
+ StopProcess(process, 500);
}
}
}
@@ -1252,15 +1232,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
public int? ExitCode;
private readonly MediaEncoder _mediaEncoder;
private readonly ILogger _logger;
- public bool IsRedirectingStdin { get; private set; }
- public ProcessWrapper(IProcess process, MediaEncoder mediaEncoder, ILogger logger, bool isRedirectingStdin)
+ public ProcessWrapper(IProcess process, MediaEncoder mediaEncoder, ILogger logger)
{
Process = process;
_mediaEncoder = mediaEncoder;
_logger = logger;
Process.Exited += Process_Exited;
- IsRedirectingStdin = isRedirectingStdin;
}
void Process_Exited(object sender, EventArgs e)
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index 5d065f528..9b31a1012 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -444,10 +444,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var process = _processFactory.Create(new ProcessOptions
{
- RedirectStandardOutput = false,
- RedirectStandardError = true,
- RedirectStandardInput = true,
-
CreateNoWindow = true,
UseShellExecute = false,
FileName = _mediaEncoder.EncoderPath,
@@ -459,26 +455,16 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
- var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-convert-" + Guid.NewGuid() + ".txt");
- _fileSystem.CreateDirectory(Path.GetDirectoryName(logFilePath));
-
- var logFileStream = _fileSystem.GetFileStream(logFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read,
- true);
-
try
{
process.Start();
}
catch (Exception ex)
{
- logFileStream.Dispose();
-
_logger.ErrorException("Error starting ffmpeg", ex);
throw;
}
-
- var logTask = process.StandardError.BaseStream.CopyToAsync(logFileStream);
var ranToCompletion = process.WaitForExit(60000);
@@ -488,19 +474,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
_logger.Info("Killing ffmpeg subtitle conversion process");
- process.StandardInput.WriteLine("q");
- process.WaitForExit(1000);
-
- await logTask.ConfigureAwait(false);
+ process.Kill();
}
catch (Exception ex)
{
_logger.ErrorException("Error killing subtitle conversion process", ex);
}
- finally
- {
- logFileStream.Dispose();
- }
}
var exitCode = ranToCompletion ? process.ExitCode : -1;
@@ -533,13 +512,15 @@ namespace MediaBrowser.MediaEncoding.Subtitles
if (failed)
{
- var msg = string.Format("ffmpeg subtitle converted failed for {0}", inputPath);
+ var msg = string.Format("ffmpeg subtitle conversion failed for {0}", inputPath);
_logger.Error(msg);
throw new Exception(msg);
}
await SetAssFont(outputPath).ConfigureAwait(false);
+
+ _logger.Info("ffmpeg subtitle conversion succeeded for {0}", inputPath);
}
///
@@ -597,10 +578,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
CreateNoWindow = true,
UseShellExecute = false,
- RedirectStandardOutput = false,
- RedirectStandardError = true,
- RedirectStandardInput = true,
-
FileName = _mediaEncoder.EncoderPath,
Arguments = processArgs,
IsHidden = true,
@@ -609,28 +586,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
- var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-extract-" + Guid.NewGuid() + ".txt");
- _fileSystem.CreateDirectory(Path.GetDirectoryName(logFilePath));
-
- var logFileStream = _fileSystem.GetFileStream(logFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read,
- true);
-
try
{
process.Start();
}
catch (Exception ex)
{
- logFileStream.Dispose();
-
_logger.ErrorException("Error starting ffmpeg", ex);
throw;
}
- // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
- Task.Run(() => StartStreamingLog(process.StandardError.BaseStream, logFileStream));
-
var ranToCompletion = process.WaitForExit(300000);
if (!ranToCompletion)
@@ -639,17 +605,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
_logger.Info("Killing ffmpeg subtitle extraction process");
- process.StandardInput.WriteLine("q");
- process.WaitForExit(1000);
+ process.Kill();
}
catch (Exception ex)
{
_logger.ErrorException("Error killing subtitle extraction process", ex);
}
- finally
- {
- logFileStream.Dispose();
- }
}
var exitCode = ranToCompletion ? process.ExitCode : -1;
@@ -702,33 +663,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
}
- private async Task StartStreamingLog(Stream source, Stream target)
- {
- try
- {
- using (var reader = new StreamReader(source))
- {
- while (!reader.EndOfStream)
- {
- var line = await reader.ReadLineAsync().ConfigureAwait(false);
-
- var bytes = Encoding.UTF8.GetBytes(Environment.NewLine + line);
-
- await target.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
- await target.FlushAsync().ConfigureAwait(false);
- }
- }
- }
- catch (ObjectDisposedException)
- {
- // Don't spam the log. This doesn't seem to throw in windows, but sometimes under linux
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error reading ffmpeg log", ex);
- }
- }
-
///
/// Sets the ass font.
///
diff --git a/MediaBrowser.Model/System/ISystemEvents.cs b/MediaBrowser.Model/System/ISystemEvents.cs
index c50f8ce03..dec8ed8c0 100644
--- a/MediaBrowser.Model/System/ISystemEvents.cs
+++ b/MediaBrowser.Model/System/ISystemEvents.cs
@@ -6,5 +6,7 @@ namespace MediaBrowser.Model.System
{
event EventHandler Resume;
event EventHandler Suspend;
+ event EventHandler SessionLogoff;
+ event EventHandler SystemShutdown;
}
}
diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs
index 470525ece..7fc3ff22e 100644
--- a/MediaBrowser.Server.Mono/Program.cs
+++ b/MediaBrowser.Server.Mono/Program.cs
@@ -1,8 +1,6 @@
using MediaBrowser.Model.Logging;
-using MediaBrowser.Server.Implementations;
using MediaBrowser.Server.Mono.Native;
using MediaBrowser.Server.Startup.Common;
-using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Globalization;
@@ -14,7 +12,6 @@ using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Emby.Common.Implementations.EnvironmentInfo;
-using Emby.Common.Implementations.IO;
using Emby.Common.Implementations.Logging;
using Emby.Common.Implementations.Networking;
using Emby.Common.Implementations.Security;
@@ -84,8 +81,6 @@ namespace MediaBrowser.Server.Mono
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, StartupOptions options)
{
- Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding;
-
// Allow all https requests
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
@@ -108,7 +103,7 @@ namespace MediaBrowser.Server.Mono
new MemoryStreamProvider(),
new NetworkManager(logManager.GetLogger("NetworkManager")),
GenerateCertificate,
- () => Environment.UserDomainName);
+ () => Environment.UserName);
if (options.ContainsOption("-v"))
{
@@ -219,19 +214,6 @@ namespace MediaBrowser.Server.Mono
public string machine = string.Empty;
}
- ///
- /// Handles the SessionEnding event of the SystemEvents control.
- ///
- /// The source of the event.
- /// The instance containing the event data.
- static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
- {
- if (e.Reason == SessionEndReasons.SystemShutdown)
- {
- Shutdown();
- }
- }
-
///
/// Handles the UnhandledException event of the CurrentDomain control.
///
diff --git a/MediaBrowser.Server.Startup.Common/SystemEvents.cs b/MediaBrowser.Server.Startup.Common/SystemEvents.cs
index 088d04a24..8d5cd4ad8 100644
--- a/MediaBrowser.Server.Startup.Common/SystemEvents.cs
+++ b/MediaBrowser.Server.Startup.Common/SystemEvents.cs
@@ -9,6 +9,8 @@ namespace MediaBrowser.Server.Startup.Common
{
public event EventHandler Resume;
public event EventHandler Suspend;
+ public event EventHandler SessionLogoff;
+ public event EventHandler SystemShutdown;
private readonly ILogger _logger;
@@ -16,6 +18,20 @@ namespace MediaBrowser.Server.Startup.Common
{
_logger = logger;
Microsoft.Win32.SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
+ Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding;
+ }
+
+ private void SystemEvents_SessionEnding(object sender, Microsoft.Win32.SessionEndingEventArgs e)
+ {
+ switch (e.Reason)
+ {
+ case Microsoft.Win32.SessionEndReasons.Logoff:
+ EventHelper.FireEventIfNotNull(SessionLogoff, this, EventArgs.Empty, _logger);
+ break;
+ case Microsoft.Win32.SessionEndReasons.SystemShutdown:
+ EventHelper.FireEventIfNotNull(SystemShutdown, this, EventArgs.Empty, _logger);
+ break;
+ }
}
private void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs
index c0ebcde74..f5e768133 100644
--- a/MediaBrowser.ServerApplication/MainStartup.cs
+++ b/MediaBrowser.ServerApplication/MainStartup.cs
@@ -368,7 +368,6 @@ namespace MediaBrowser.ServerApplication
task = InstallVcredist2013IfNeeded(_appHost, _logger);
Task.WaitAll(task);
- Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding;
Microsoft.Win32.SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
HideSplashScreen();
@@ -569,19 +568,6 @@ namespace MediaBrowser.ServerApplication
}
}
- ///
- /// Handles the SessionEnding event of the SystemEvents control.
- ///
- /// The source of the event.
- /// The instance containing the event data.
- static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
- {
- if (e.Reason == SessionEndReasons.SystemShutdown || !IsRunningAsService)
- {
- Shutdown();
- }
- }
-
///
/// Handles the UnhandledException event of the CurrentDomain control.
///