From 635c8d50a361dc2eabbeea0ae55048d1e9f4ad8f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 13 Nov 2016 22:44:54 -0500 Subject: update character escaping --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs') diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index bae367d82..a52ac0e60 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -88,8 +88,8 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly int DefaultImageExtractionTimeoutMs; private readonly bool EnableEncoderFontFile; - public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, bool hasExternalEncoder, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func subtitleEncoder, Func mediaSourceManager, IHttpClient httpClient, IZipClient zipClient, IMemoryStreamFactory memoryStreamProvider, IProcessFactory processFactory, - int defaultImageExtractionTimeoutMs, + public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, bool hasExternalEncoder, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func subtitleEncoder, Func mediaSourceManager, IHttpClient httpClient, IZipClient zipClient, IMemoryStreamFactory memoryStreamProvider, IProcessFactory processFactory, + int defaultImageExtractionTimeoutMs, bool enableEncoderFontFile) { _logger = logger; @@ -459,7 +459,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (request.AnalyzeDurationSections > 0) { analyzeDuration = "-analyzeduration " + - (request.AnalyzeDurationSections*1000000).ToString(CultureInfo.InvariantCulture); + (request.AnalyzeDurationSections * 1000000).ToString(CultureInfo.InvariantCulture); } else { @@ -1221,9 +1221,7 @@ namespace MediaBrowser.MediaEncoding.Encoder // https://ffmpeg.org/ffmpeg-filters.html#Notes-on-filtergraph-escaping // We need to double escape - var escapeChars = new[] {':', '\'', ','}; - - return path.Replace('\\', '/').Replace(":/", "\\:/").Replace("'", "'\\\\\\''"); + return path.Replace('\\', '/').Replace(":", "\\:").Replace("'", "'\\\\\\''"); } /// -- cgit v1.2.3 From 9b5a4c22e33db6d2e4554a61c49d7f6bf3375e24 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 14 Nov 2016 01:44:21 -0500 Subject: update image & subtitle extraction --- .../Emby.Server.Implementations.csproj | 1 + .../EntryPoints/SystemEvents.cs | 47 +++++++++++++ MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 68 +++++++------------ .../Subtitles/SubtitleEncoder.cs | 76 ++-------------------- MediaBrowser.Model/System/ISystemEvents.cs | 2 + MediaBrowser.Server.Mono/Program.cs | 20 +----- MediaBrowser.Server.Startup.Common/SystemEvents.cs | 16 +++++ MediaBrowser.ServerApplication/MainStartup.cs | 14 ---- 8 files changed, 95 insertions(+), 149 deletions(-) create mode 100644 Emby.Server.Implementations/EntryPoints/SystemEvents.cs (limited to 'MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs') 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 { - _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) 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. /// -- cgit v1.2.3