Explorar o código

update image & subtitle extraction

Luke Pulverenti %!s(int64=8) %!d(string=hai) anos
pai
achega
9b5a4c22e3

+ 1 - 0
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -59,6 +59,7 @@
     <Compile Include="EntryPoints\RecordingNotifier.cs" />
     <Compile Include="EntryPoints\RefreshUsersMetadata.cs" />
     <Compile Include="EntryPoints\ServerEventNotifier.cs" />
+    <Compile Include="EntryPoints\SystemEvents.cs" />
     <Compile Include="EntryPoints\UdpServerEntryPoint.cs" />
     <Compile Include="EntryPoints\UsageEntryPoint.cs" />
     <Compile Include="EntryPoints\UsageReporter.cs" />

+ 47 - 0
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;
+        }
+    }
+}

+ 23 - 45
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
             {
-                _logger.Info("Killing ffmpeg process");
-
-                if (process.IsRedirectingStdin)
+                if (process.Process.WaitForExit(waitTimeMs))
                 {
-                    try
-                    {
-                        process.Process.StandardInput.WriteLine("q");
-                    }
-                    catch (Exception)
-                    {
-                        _logger.Error("Error sending q command to process");
-                    }
+                    return;
                 }
+            }
+            catch (Exception ex)
+            {
+                _logger.Error("Error in WaitForExit", ex);
+            }
 
-                try
-                {
-                    if (process.Process.WaitForExit(waitTimeMs))
-                    {
-                        return;
-                    }
-                }
-                catch (Exception ex)
-                {
-                    _logger.Error("Error in WaitForExit", ex);
-                }
+            try
+            {
+                _logger.Info("Killing ffmpeg process");
 
-                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)

+ 5 - 71
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);
         }
 
         /// <summary>
@@ -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);
-            }
-        }
-
         /// <summary>
         /// Sets the ass font.
         /// </summary>

+ 2 - 0
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;
     }
 }

+ 1 - 19
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;
         }
 
-        /// <summary>
-        /// Handles the SessionEnding event of the SystemEvents control.
-        /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="e">The <see cref="SessionEndingEventArgs"/> instance containing the event data.</param>
-        static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
-        {
-            if (e.Reason == SessionEndReasons.SystemShutdown)
-            {
-                Shutdown();
-            }
-        }
-
         /// <summary>
         /// Handles the UnhandledException event of the CurrentDomain control.
         /// </summary>

+ 16 - 0
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)

+ 0 - 14
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
             }
         }
 
-        /// <summary>
-        /// Handles the SessionEnding event of the SystemEvents control.
-        /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="e">The <see cref="SessionEndingEventArgs"/> instance containing the event data.</param>
-        static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
-        {
-            if (e.Reason == SessionEndReasons.SystemShutdown || !IsRunningAsService)
-            {
-                Shutdown();
-            }
-        }
-
         /// <summary>
         /// Handles the UnhandledException event of the CurrentDomain control.
         /// </summary>