summaryrefslogtreecommitdiffstats
path: root/win/CS
diff options
context:
space:
mode:
authorsr55 <[email protected]>2020-03-31 20:24:58 +0100
committersr55 <[email protected]>2020-03-31 20:25:09 +0100
commit83dde24b82284b287dc784582ebce06e4dcbfd74 (patch)
tree6384324da7dd1ad16e45b960a951d5d17babdce6 /win/CS
parentf34280f1c619dae0b4e1a1ea09cea5b39f17d695 (diff)
WinGui: Further work on the isolated process articecture.
Diffstat (limited to 'win/CS')
-rw-r--r--win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs3
-rw-r--r--win/CS/HandBrake.Worker/HandBrake.Worker.csproj7
-rw-r--r--win/CS/HandBrake.Worker/HttpServer.cs8
-rw-r--r--win/CS/HandBrake.Worker/Logging/Interfaces/ILogHandler.cs2
-rw-r--r--win/CS/HandBrake.Worker/Logging/LogHandler.cs73
-rw-r--r--win/CS/HandBrake.Worker/Program.cs36
-rw-r--r--win/CS/HandBrake.Worker/Registration/ConnectionRegistrar.cs53
-rw-r--r--win/CS/HandBrake.Worker/Routing/ApiRouter.cs85
-rw-r--r--win/CS/HandBrake.Worker/Routing/Commands/EncodeCommand.cs20
-rw-r--r--win/CS/HandBrake.Worker/Routing/Commands/InitCommand.cs28
-rw-r--r--win/CS/HandBrake.Worker/Routing/Results/CommandResult.cs17
-rw-r--r--win/CS/HandBrake.Worker/Routing/Results/ConnectionResult.cs (renamed from win/CS/HandBrake.Worker/Registration/Model/ConnectionResult.cs)2
-rw-r--r--win/CS/HandBrake.Worker/Watcher/InstanceWatcher.cs51
-rw-r--r--win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs18
-rw-r--r--win/CS/HandBrakeWPF/Instance/RemoteInstance.cs115
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs2
-rw-r--r--win/CS/HandBrakeWPF/Services/Logging/LogService.cs87
-rw-r--r--win/CS/HandBrakeWPF/Services/UserSettingService.cs2
18 files changed, 369 insertions, 240 deletions
diff --git a/win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs b/win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs
index 104983b8f..5a0957cb9 100644
--- a/win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs
+++ b/win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs
@@ -33,6 +33,9 @@ namespace HandBrake.Interop.Interop.Interfaces
/// <param name="verbosity">
/// The code for the logging verbosity to use.
/// </param>
+ /// <param name="noHardware">
+ /// Turn off Hardware Acceleration
+ /// </param>
void Initialize(int verbosity, bool noHardware);
/// <summary>
diff --git a/win/CS/HandBrake.Worker/HandBrake.Worker.csproj b/win/CS/HandBrake.Worker/HandBrake.Worker.csproj
index f075859c0..f0ca5786d 100644
--- a/win/CS/HandBrake.Worker/HandBrake.Worker.csproj
+++ b/win/CS/HandBrake.Worker/HandBrake.Worker.csproj
@@ -45,15 +45,18 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Routing\ApiRouter.cs" />
- <Compile Include="Registration\ConnectionRegistrar.cs" />
<Compile Include="HttpServer.cs" />
<Compile Include="Logging\Interfaces\ILogHandler.cs" />
<Compile Include="Logging\LogHandler.cs" />
<Compile Include="Logging\Models\LogMessage.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Registration\Model\ConnectionResult.cs" />
+ <Compile Include="Routing\Commands\EncodeCommand.cs" />
+ <Compile Include="Routing\Results\CommandResult.cs" />
+ <Compile Include="Routing\Results\ConnectionResult.cs" />
+ <Compile Include="Routing\Commands\InitCommand.cs" />
<Compile Include="Utilities\HttpUtilities.cs" />
+ <Compile Include="Watcher\InstanceWatcher.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
diff --git a/win/CS/HandBrake.Worker/HttpServer.cs b/win/CS/HandBrake.Worker/HttpServer.cs
index a2495ba39..3c9a36b37 100644
--- a/win/CS/HandBrake.Worker/HttpServer.cs
+++ b/win/CS/HandBrake.Worker/HttpServer.cs
@@ -32,15 +32,15 @@ namespace HandBrake.Worker
// Store the Handlers
this.apiHandlers = new Dictionary<string, Func<HttpListenerRequest, string>>(apiCalls);
- Console.WriteLine(Environment.NewLine + "Available APIs: ");
+ Debug.WriteLine(Environment.NewLine + "Available APIs: ");
foreach (KeyValuePair<string, Func<HttpListenerRequest, string>> api in apiCalls)
{
string url = string.Format("http://127.0.0.1:{0}/{1}/", port, api.Key);
this.httpListener.Prefixes.Add(url);
- Console.WriteLine(url);
+ Debug.WriteLine(url);
}
- Console.WriteLine(Environment.NewLine);
+ Debug.WriteLine(Environment.NewLine);
this.httpListener.Start();
}
@@ -66,7 +66,7 @@ namespace HandBrake.Worker
{
string path = context.Request.RawUrl.TrimStart('/').TrimEnd('/');
- Console.WriteLine("Handling call to: " + path);
+ Debug.WriteLine("Handling call to: " + path);
if (this.apiHandlers.TryGetValue(path, out var actionToPerform))
{
diff --git a/win/CS/HandBrake.Worker/Logging/Interfaces/ILogHandler.cs b/win/CS/HandBrake.Worker/Logging/Interfaces/ILogHandler.cs
index eaa527ed6..f9601d94e 100644
--- a/win/CS/HandBrake.Worker/Logging/Interfaces/ILogHandler.cs
+++ b/win/CS/HandBrake.Worker/Logging/Interfaces/ILogHandler.cs
@@ -30,5 +30,7 @@ namespace HandBrake.Worker.Logging.Interfaces
/// Empty the log cache and reset the log handler to defaults.
/// </summary>
void Reset();
+
+ void ShutdownFileWriter();
}
}
diff --git a/win/CS/HandBrake.Worker/Logging/LogHandler.cs b/win/CS/HandBrake.Worker/Logging/LogHandler.cs
index b0f11c1e7..6a1f7bb6f 100644
--- a/win/CS/HandBrake.Worker/Logging/LogHandler.cs
+++ b/win/CS/HandBrake.Worker/Logging/LogHandler.cs
@@ -10,7 +10,10 @@
namespace HandBrake.Worker.Logging
{
+ using System;
using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.IO;
using System.Linq;
using System.Text;
@@ -21,15 +24,32 @@ namespace HandBrake.Worker.Logging
public class LogHandler : ILogHandler
{
+ private readonly string logFile;
+
private readonly object lockObject = new object();
+ private readonly object fileWriterLock = new object();
+
private readonly StringBuilder logBuilder = new StringBuilder();
private readonly List<LogMessage> logMessages = new List<LogMessage>();
private bool isLoggingEnabled = true;
+ private bool isDiskLoggingEnabled = false;
private int messageIndex;
+ private StreamWriter fileWriter;
- public LogHandler()
+ public LogHandler(string logDirectory, string logFileName, bool enableDiskLogging)
{
+ this.isDiskLoggingEnabled = enableDiskLogging;
+
+ if (this.isDiskLoggingEnabled)
+ {
+ lock (this.fileWriterLock)
+ {
+ // Todo Handle no log directory.
+ this.fileWriter = new StreamWriter(logFileName) { AutoFlush = true };
+ }
+ }
+
HandBrakeUtils.MessageLogged += this.HandBrakeUtils_MessageLogged;
HandBrakeUtils.ErrorLogged += this.HandBrakeUtils_ErrorLogged;
}
@@ -78,17 +98,20 @@ namespace HandBrake.Worker.Logging
public void LogMessage(string content)
{
+ Console.WriteLine(content);
+
if (!this.isLoggingEnabled)
{
return;
}
+ LogMessage msg = new LogMessage(content, this.messageIndex);
lock (this.lockObject)
{
- LogMessage msg = new LogMessage(content, this.messageIndex);
this.messageIndex = this.messageIndex + 1;
this.logMessages.Add(msg);
this.logBuilder.AppendLine(msg.Content);
+ this.LogMessageToDisk(msg);
if (this.logMessages.Count > 50000)
{
@@ -96,6 +119,7 @@ namespace HandBrake.Worker.Logging
msg = new LogMessage("Log Service Pausing. Too Many Log messages. This may indicate a problem with your encode.", this.messageIndex);
this.logMessages.Add(msg);
this.logBuilder.AppendLine(msg.Content);
+ this.LogMessageToDisk(msg);
this.isLoggingEnabled = false;
}
@@ -112,6 +136,51 @@ namespace HandBrake.Worker.Logging
}
}
+ public void ShutdownFileWriter()
+ {
+ try
+ {
+ lock (this.fileWriterLock)
+ {
+ if (this.fileWriter != null)
+ {
+ this.fileWriter.Flush();
+ this.fileWriter.Close();
+ this.fileWriter.Dispose();
+ }
+
+ this.fileWriter = null;
+ }
+ }
+ catch (Exception exc)
+ {
+ Debug.WriteLine(exc); // This exception doesn't warrant user interaction, but it should be logged
+ }
+ }
+
+ private void LogMessageToDisk(LogMessage msg)
+ {
+ if (!this.isDiskLoggingEnabled)
+ {
+ return;
+ }
+
+ try
+ {
+ lock (this.fileWriterLock)
+ {
+ if (this.fileWriter != null && this.fileWriter.BaseStream.CanWrite)
+ {
+ this.fileWriter.WriteLine(msg.Content);
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ Debug.WriteLine(exc); // This exception doesn't warrant user interaction, but it should be logged
+ }
+ }
+
private void HandBrakeUtils_ErrorLogged(object sender, MessageLoggedEventArgs e)
{
if (e == null || string.IsNullOrEmpty(e.Message))
diff --git a/win/CS/HandBrake.Worker/Program.cs b/win/CS/HandBrake.Worker/Program.cs
index 326643d13..74114bd9e 100644
--- a/win/CS/HandBrake.Worker/Program.cs
+++ b/win/CS/HandBrake.Worker/Program.cs
@@ -12,22 +12,20 @@ namespace HandBrake.Worker
using System;
using System.Collections.Generic;
using System.Net;
+ using System.Runtime.CompilerServices;
using System.Threading;
- using HandBrake.Worker.Registration;
using HandBrake.Worker.Routing;
public class Program
{
private static ApiRouter router;
private static ManualResetEvent manualResetEvent = new ManualResetEvent(false);
- private static ConnectionRegistrar registrar = new ConnectionRegistrar();
public static void Main(string[] args)
{
int port = 8037; // Default Port;
- int verbosity = 1;
-
+
if (args.Length != 0)
{
foreach (string argument in args)
@@ -40,21 +38,12 @@ namespace HandBrake.Worker
port = parsedPort;
}
}
-
- if (argument.StartsWith("--verbosity"))
- {
- string value = argument.TrimStart("--port=".ToCharArray());
- if (int.TryParse(value, out var verbosityVal))
- {
- verbosity = verbosityVal;
- }
- }
}
}
Console.WriteLine("Starting HandBrake Engine ...");
router = new ApiRouter();
- router.Initialise(verbosity);
+ router.TerminationEvent += Router_TerminationEvent;
Console.WriteLine("Starting Web Server ...");
Console.WriteLine("Using Port: {0}", port);
@@ -63,21 +52,21 @@ namespace HandBrake.Worker
webServer.Run();
Console.WriteLine("Web Server Started");
-
+
manualResetEvent.WaitOne();
webServer.Stop();
}
- public static Dictionary<string, Func<HttpListenerRequest, string>> RegisterApiHandlers()
+ private static Dictionary<string, Func<HttpListenerRequest, string>> RegisterApiHandlers()
{
Dictionary<string, Func<HttpListenerRequest, string>> apiHandlers =
new Dictionary<string, Func<HttpListenerRequest, string>>();
- // Worker APIs
- apiHandlers.Add("Pair", registrar.Pair);
- apiHandlers.Add("GetToken", registrar.GetToken);
+ // Process Handling
apiHandlers.Add("Shutdown", ShutdownServer);
+ apiHandlers.Add("GetInstanceToken", router.GetInstanceToken);
+ apiHandlers.Add("Version", router.GetVersionInfo);
// Logging
apiHandlers.Add("GetAllLogMessages", router.GetAllLogMessages);
@@ -85,18 +74,21 @@ namespace HandBrake.Worker
apiHandlers.Add("ResetLogging", router.ResetLogging);
// HandBrake APIs
- apiHandlers.Add("Version", router.GetVersionInfo);
apiHandlers.Add("StartEncode", router.StartEncode);
apiHandlers.Add("PauseEncode", router.PauseEncode);
apiHandlers.Add("ResumeEncode", router.ResumeEncode);
apiHandlers.Add("StopEncode", router.StopEncode);
apiHandlers.Add("PollEncodeProgress", router.PollEncodeProgress);
- apiHandlers.Add("SetConfiguration", router.SetConfiguration);
return apiHandlers;
}
- public static string ShutdownServer(HttpListenerRequest request)
+ private static void Router_TerminationEvent(object sender, EventArgs e)
+ {
+ ShutdownServer(null);
+ }
+
+ private static string ShutdownServer(HttpListenerRequest request)
{
manualResetEvent.Set();
return "Server Terminated";
diff --git a/win/CS/HandBrake.Worker/Registration/ConnectionRegistrar.cs b/win/CS/HandBrake.Worker/Registration/ConnectionRegistrar.cs
deleted file mode 100644
index 6dca9d950..000000000
--- a/win/CS/HandBrake.Worker/Registration/ConnectionRegistrar.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-// <copyright file="ConnectionRegistrar.cs" company="HandBrake Project (http://handbrake.fr)">
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
-// </copyright>
-// <summary>
-// Defines the ConnectionRegistrar type.
-// </summary>
-// <remarks>
-// To be clear, this is NOT a security service!
-// This service simply allows the UI to verify which worker process it is connected to.
-// </remarks>
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace HandBrake.Worker.Registration
-{
- using System;
- using System.Net;
-
- using HandBrake.Worker.Registration.Model;
- using HandBrake.Worker.Utilities;
-
- using Newtonsoft.Json;
-
- public class ConnectionRegistrar
- {
- private readonly JsonSerializerSettings jsonNetSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
- private string token;
-
- public ConnectionRegistrar()
- {
- }
-
- public string Pair(HttpListenerRequest request)
- {
- string tokenKey = HttpUtilities.GetRequestPostData(request);
-
-
- if (!string.IsNullOrEmpty(token))
- {
- return JsonConvert.SerializeObject(new ConnectionResult(false, null, "Already Paired"), Formatting.Indented, this.jsonNetSettings);
- }
-
- this.token = tokenKey;
-
- return JsonConvert.SerializeObject(new ConnectionResult(true, tokenKey, null), Formatting.Indented, this.jsonNetSettings);
- }
-
- public string GetToken(HttpListenerRequest request)
- {
- return this.token;
- }
- }
-}
diff --git a/win/CS/HandBrake.Worker/Routing/ApiRouter.cs b/win/CS/HandBrake.Worker/Routing/ApiRouter.cs
index a98f7413d..81267acb9 100644
--- a/win/CS/HandBrake.Worker/Routing/ApiRouter.cs
+++ b/win/CS/HandBrake.Worker/Routing/ApiRouter.cs
@@ -20,32 +20,27 @@ namespace HandBrake.Worker.Routing
using HandBrake.Worker.Logging;
using HandBrake.Worker.Logging.Interfaces;
using HandBrake.Worker.Logging.Models;
+ using HandBrake.Worker.Routing.Commands;
+ using HandBrake.Worker.Routing.Results;
using HandBrake.Worker.Utilities;
+ using HandBrake.Worker.Watcher;
using Newtonsoft.Json;
public class ApiRouter
{
+ private readonly string token = Guid.NewGuid().ToString();
+
private readonly JsonSerializerSettings jsonNetSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
private HandBrakeInstance handbrakeInstance;
private ILogHandler logHandler;
- private bool isLoggingConfigured = false;
+ private InstanceWatcher instanceWatcher;
- public string Initialise(int verbosity)
- {
- if (this.handbrakeInstance == null)
- {
- this.handbrakeInstance = new HandBrakeInstance();
- }
+ public event EventHandler TerminationEvent;
- if (this.logHandler == null)
- {
- this.logHandler = new LogHandler();
- }
-
- this.handbrakeInstance.Initialize(verbosity, true);
-
- return null;
+ public string GetInstanceToken(HttpListenerRequest request)
+ {
+ return JsonConvert.SerializeObject(token, Formatting.Indented, this.jsonNetSettings);
}
public string GetVersionInfo(HttpListenerRequest request)
@@ -59,10 +54,18 @@ namespace HandBrake.Worker.Routing
{
string requestPostData = HttpUtilities.GetRequestPostData(request);
- Console.WriteLine(requestPostData);
- this.handbrakeInstance.StartEncode(requestPostData);
+ if (!string.IsNullOrEmpty(requestPostData))
+ {
+ EncodeCommand command = JsonConvert.DeserializeObject<EncodeCommand>(requestPostData);
- return null;
+ this.Initialise(command.InitialiseCommand);
+
+ this.handbrakeInstance.StartEncode(command.EncodeJob);
+
+ return JsonConvert.SerializeObject(new CommandResult() { WasSuccessful = true }, Formatting.Indented, this.jsonNetSettings);
+ }
+
+ return JsonConvert.SerializeObject(new CommandResult() { WasSuccessful = false, Error = "No POST data" }, Formatting.Indented, this.jsonNetSettings);
}
public string StopEncode(HttpListenerRequest request)
@@ -99,12 +102,6 @@ namespace HandBrake.Worker.Routing
return null;
}
- public string SetConfiguration(HttpListenerRequest request)
- {
- return null;
- }
-
-
/* Logging API */
// GET
@@ -112,8 +109,7 @@ namespace HandBrake.Worker.Routing
{
return JsonConvert.SerializeObject(this.logHandler.GetLogMessages(), Formatting.Indented, this.jsonNetSettings);
}
-
-
+
// POST
public string GetLogMessagesFromIndex(HttpListenerRequest request)
{
@@ -133,5 +129,42 @@ namespace HandBrake.Worker.Routing
return null;
}
+
+ public void OnTerminationEvent()
+ {
+ this.TerminationEvent?.Invoke(this, EventArgs.Empty);
+ }
+
+ private void HandbrakeInstance_EncodeCompleted(object sender, Interop.Interop.EventArgs.EncodeCompletedEventArgs e)
+ {
+ this.logHandler.ShutdownFileWriter();
+ }
+
+ private void Initialise(InitCommand command)
+ {
+ if (this.handbrakeInstance == null)
+ {
+ this.handbrakeInstance = new HandBrakeInstance();
+ }
+
+ if (this.logHandler == null)
+ {
+ this.logHandler = new LogHandler(command.LogDirectory, command.LogFile, command.EnableDiskLogging);
+ }
+
+ if (!command.AllowDisconnectedWorker)
+ {
+ this.instanceWatcher = new InstanceWatcher(this);
+ this.instanceWatcher.Start(5000);
+ }
+
+ this.handbrakeInstance.Initialize(command.LogVerbosity, command.EnableHardwareAcceleration);
+ this.handbrakeInstance.EncodeCompleted += this.HandbrakeInstance_EncodeCompleted;
+
+ if (command.DisableLibDvdNav)
+ {
+ HandBrakeUtils.SetDvdNav(true); // TODO check this is correct
+ }
+ }
}
}
diff --git a/win/CS/HandBrake.Worker/Routing/Commands/EncodeCommand.cs b/win/CS/HandBrake.Worker/Routing/Commands/EncodeCommand.cs
new file mode 100644
index 000000000..0960609a1
--- /dev/null
+++ b/win/CS/HandBrake.Worker/Routing/Commands/EncodeCommand.cs
@@ -0,0 +1,20 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="EncodeCommand.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the EncodeCommand type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.Worker.Routing.Commands
+{
+ using HandBrake.Interop.Interop.Json.Encode;
+
+ public class EncodeCommand
+ {
+ public InitCommand InitialiseCommand { get; set; }
+
+ public JsonEncodeObject EncodeJob { get; set; }
+ }
+}
diff --git a/win/CS/HandBrake.Worker/Routing/Commands/InitCommand.cs b/win/CS/HandBrake.Worker/Routing/Commands/InitCommand.cs
new file mode 100644
index 000000000..c1814de61
--- /dev/null
+++ b/win/CS/HandBrake.Worker/Routing/Commands/InitCommand.cs
@@ -0,0 +1,28 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="InitCommand.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the InitCommand type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.Worker.Routing.Commands
+{
+ public class InitCommand
+ {
+ public int LogVerbosity { get; set; }
+
+ public string LogDirectory { get; set; }
+
+ public string LogFile { get; set; }
+
+ public bool EnableDiskLogging { get; set; }
+
+ public bool EnableHardwareAcceleration { get; set; }
+
+ public bool DisableLibDvdNav { get; set; }
+
+ public bool AllowDisconnectedWorker { get; set; }
+ }
+}
diff --git a/win/CS/HandBrake.Worker/Routing/Results/CommandResult.cs b/win/CS/HandBrake.Worker/Routing/Results/CommandResult.cs
new file mode 100644
index 000000000..624ab9d3e
--- /dev/null
+++ b/win/CS/HandBrake.Worker/Routing/Results/CommandResult.cs
@@ -0,0 +1,17 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="CommandResult.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the CommandResult type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.Worker.Routing.Results
+{
+ public class CommandResult
+ {
+ public bool WasSuccessful { get; set; }
+ public string Error { get; set; }
+ }
+}
diff --git a/win/CS/HandBrake.Worker/Registration/Model/ConnectionResult.cs b/win/CS/HandBrake.Worker/Routing/Results/ConnectionResult.cs
index d11c12cec..65a26660b 100644
--- a/win/CS/HandBrake.Worker/Registration/Model/ConnectionResult.cs
+++ b/win/CS/HandBrake.Worker/Routing/Results/ConnectionResult.cs
@@ -7,7 +7,7 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
-namespace HandBrake.Worker.Registration.Model
+namespace HandBrake.Worker.Routing.Results
{
public class ConnectionResult
{
diff --git a/win/CS/HandBrake.Worker/Watcher/InstanceWatcher.cs b/win/CS/HandBrake.Worker/Watcher/InstanceWatcher.cs
new file mode 100644
index 000000000..f50ca6c4b
--- /dev/null
+++ b/win/CS/HandBrake.Worker/Watcher/InstanceWatcher.cs
@@ -0,0 +1,51 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="InstanceWatcher.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the InstanceWatcher type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.Worker.Watcher
+{
+ using System.Diagnostics;
+ using System.Timers;
+
+ using HandBrake.Worker.Routing;
+
+ public class InstanceWatcher
+ {
+ private readonly ApiRouter routerInstance;
+
+ private Timer timer;
+
+ public InstanceWatcher(ApiRouter routerInstance)
+ {
+ this.routerInstance = routerInstance;
+ }
+
+ public void Start(int ms)
+ {
+ if (this.timer != null)
+ {
+ this.timer.Stop();
+ }
+
+ this.timer = new Timer(ms) { AutoReset = true };
+ this.timer.Start();
+ this.timer.Elapsed += this.Timer_Elapsed;
+ }
+
+ private void Timer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ // Check if we are still attached to a UI. If not, terminate.
+ Process[] uiProcesses = Process.GetProcessesByName("HandBrake");
+ if (uiProcesses.Length == 0)
+ {
+ this.routerInstance.StopEncode(null);
+ this.routerInstance.OnTerminationEvent();
+ }
+ }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs b/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs
index 914d7916f..f24ae527b 100644
--- a/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs
+++ b/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs
@@ -12,11 +12,13 @@ namespace HandBrakeWPF.Instance
using System;
using System.Runtime.CompilerServices;
+
using HandBrake.Interop.Interop;
using HandBrake.Interop.Interop.Interfaces;
using HandBrake.Interop.Model;
using HandBrakeWPF.Factories;
+ using HandBrakeWPF.Services.Logging.Interfaces;
/// <summary>
/// The HandBrake Instance manager.
@@ -36,19 +38,7 @@ namespace HandBrakeWPF.Instance
HandBrakeUtils.EnsureGlobalInit(noHardwareMode);
}
- /// <summary>
- /// The get encode instance.
- /// </summary>
- /// <param name="verbosity">
- /// The verbosity.
- /// </param>
- /// <param name="configuration">
- /// The configuration.
- /// </param>
- /// <returns>
- /// The <see cref="IHandBrakeInstance"/>.
- /// </returns>
- public static IEncodeInstance GetEncodeInstance(int verbosity, HBConfiguration configuration)
+ public static IEncodeInstance GetEncodeInstance(int verbosity, HBConfiguration configuration, ILog logService)
{
if (!HandBrakeUtils.IsInitialised())
{
@@ -65,7 +55,7 @@ namespace HandBrakeWPF.Instance
if (configuration.RemoteServiceEnabled)
{
- newInstance = new RemoteInstance(configuration.RemoteServicePort);
+ newInstance = new RemoteInstance(configuration, logService);
}
else
{
diff --git a/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs b/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs
index 36221da4d..dc52d0885 100644
--- a/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs
+++ b/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs
@@ -11,22 +11,22 @@
namespace HandBrakeWPF.Instance
{
using System;
- using System.Collections.Generic;
using System.Diagnostics;
- using System.Linq;
- using System.Net.Http;
- using System.Net.Http.Headers;
- using System.Runtime.CompilerServices;
- using System.Text;
+ using System.IO;
using System.Threading.Tasks;
using System.Timers;
+ using System.Windows.Media.Animation;
+
using HandBrake.Interop.Interop.EventArgs;
using HandBrake.Interop.Interop.Interfaces;
using HandBrake.Interop.Interop.Json.Encode;
using HandBrake.Interop.Interop.Json.State;
+ using HandBrake.Interop.Model;
+ using HandBrake.Worker.Routing.Commands;
using HandBrakeWPF.Instance.Model;
+ using HandBrakeWPF.Services.Logging.Interfaces;
using HandBrakeWPF.Utilities;
using Newtonsoft.Json;
@@ -42,14 +42,21 @@ namespace HandBrakeWPF.Instance
public class RemoteInstance : HttpRequestBase, IEncodeInstance, IDisposable
{
- private const double EncodePollIntervalMs = 1000;
+ private readonly HBConfiguration configuration;
+
+ private readonly ILog logService;
+
+ private const double EncodePollIntervalMs = 250;
private Process workerProcess;
private Timer encodePollTimer;
+ private int retryCount = 0;
- public RemoteInstance(int port)
+ public RemoteInstance(HBConfiguration configuration, ILog logService)
{
- this.port = port;
+ this.configuration = configuration;
+ this.logService = logService;
+ this.port = configuration.RemoteServicePort;
this.serverUrl = string.Format("http://127.0.0.1:{0}/", this.port);
}
@@ -71,8 +78,20 @@ namespace HandBrakeWPF.Instance
public async void StartEncode(JsonEncodeObject jobToStart)
{
+ InitCommand initCommand = new InitCommand
+ {
+ EnableDiskLogging = true,
+ AllowDisconnectedWorker = false,
+ DisableLibDvdNav = this.configuration.IsDvdNavDisabled,
+ EnableHardwareAcceleration = true,
+ LogDirectory = DirectoryUtilities.GetLogDirectory(),
+ LogVerbosity = configuration.Verbosity
+ };
+
+ initCommand.LogFile = Path.Combine(initCommand.LogDirectory, string.Format("activity_log.worker.{0}.txt", GeneralUtilities.ProcessId));
+
JsonSerializerSettings settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
- string job = JsonConvert.SerializeObject(jobToStart, Formatting.None, settings);
+ string job = JsonConvert.SerializeObject(new EncodeCommand { InitialiseCommand = initCommand, EncodeJob = jobToStart }, Formatting.None, settings);
await this.MakeHttpJsonPostRequest("StartEncode", job);
@@ -82,7 +101,6 @@ namespace HandBrakeWPF.Instance
public async void StopEncode()
{
await this.MakeHttpGetRequest("StopEncode");
- this.StopPollingProgress();
}
public JsonState GetEncodeProgress()
@@ -103,34 +121,49 @@ namespace HandBrakeWPF.Instance
public void Initialize(int verbosityLvl, bool noHardwareMode)
{
- this.StartServer(verbosityLvl, noHardwareMode);
+ this.StartServer();
}
public void Dispose()
{
this.client?.Dispose();
this.workerProcess?.Dispose();
- this.StopEncode();
- this.StopServer();
}
- private void StartServer(int verbosityLvl, bool noHardwareMode)
+ private async void StartServer()
{
if (this.workerProcess == null || this.workerProcess.HasExited)
{
- this.workerProcess = new Process();
- this.workerProcess.StartInfo =
- new ProcessStartInfo("HandBrake.Worker.exe", string.Format("--port={0} --verbosity={1}", this.port, verbosityLvl))
- {
- WindowStyle = ProcessWindowStyle.Normal
- };
-
- this.workerProcess.Start();
- this.workerProcess.Exited += this.WorkerProcess_Exited;
- Debug.WriteLine("Worker Process Started. PID = {0}", this.workerProcess.Id);
+ workerProcess = new Process
+ {
+ StartInfo =
+ {
+ FileName = "HandBrake.Worker.exe",
+ Arguments = string.Format(" --port={0}", this.port),
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ CreateNoWindow = true
+ }
+ };
+ workerProcess.Exited += this.WorkerProcess_Exited;
+ workerProcess.OutputDataReceived += this.WorkerProcess_OutputDataReceived;
+ workerProcess.ErrorDataReceived += this.WorkerProcess_OutputDataReceived;
+
+ workerProcess.Start();
+ workerProcess.BeginOutputReadLine();
+ workerProcess.BeginErrorReadLine();
+
+
+ this.logService.LogMessage(string.Format("Worker Process started with Process ID: {0}", this.workerProcess.Id));
}
}
+ private void WorkerProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
+ {
+ this.logService.LogMessage(e.Data);
+ }
+
private void MonitorEncodeProgress()
{
this.encodePollTimer = new Timer();
@@ -152,13 +185,13 @@ namespace HandBrakeWPF.Instance
private void StopPollingProgress()
{
- this.PollEncodeProgress(); // Get the final progress state.
+ this.PollEncodeProgress(); // Get the last progress state.
this.encodePollTimer?.Stop();
}
private void WorkerProcess_Exited(object sender, EventArgs e)
{
- Debug.WriteLine("Worker Process has exited");
+ this.logService.LogMessage("Worker Process Existed!");
}
private void StopServer()
@@ -174,18 +207,29 @@ namespace HandBrakeWPF.Instance
ServerResponse response = null;
try
{
+ if (this.retryCount > 5)
+ {
+ this.EncodeCompleted?.Invoke(sender: this, e: new EncodeCompletedEventArgs(true));
+
+ this.encodePollTimer?.Stop();
+
+ this.workerProcess?.Kill();
+
+ return;
+ }
+
response = await this.MakeHttpGetRequest("PollEncodeProgress");
+
+ this.retryCount = 0; // Reset
}
catch (Exception e)
{
- if (this.encodePollTimer != null)
- {
- this.encodePollTimer.Stop();
- }
+ retryCount = this.retryCount + 1;
}
if (response == null || !response.WasSuccessful)
{
+ retryCount = this.retryCount + 1;
return;
}
@@ -215,8 +259,15 @@ namespace HandBrakeWPF.Instance
else if (taskState != null && taskState == TaskState.WorkDone)
{
this.encodePollTimer.Stop();
-
+
+ this.EncodeCompleted?.Invoke(sender: this, e: new EncodeCompletedEventArgs(state.WorkDone.Error != 0));
+ this.workerProcess?.Kill();
+ }
+ else if (taskState == TaskState.Idle)
+ {
+ this.encodePollTimer.Stop();
this.EncodeCompleted?.Invoke(sender: this, e: new EncodeCompletedEventArgs(state.WorkDone.Error != 0));
+ this.workerProcess?.Kill();
}
}
}
diff --git a/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs b/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs
index 417d77855..481c8cebd 100644
--- a/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs
+++ b/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs
@@ -108,7 +108,7 @@ namespace HandBrakeWPF.Services.Encode
this.TimedLogMessage(string.Format("base preset: {0}", basePresetName));
}
- this.instance = task.IsPreviewEncode ? HandBrakeInstanceManager.GetPreviewInstance(configuration.Verbosity, configuration) : HandBrakeInstanceManager.GetEncodeInstance(configuration.Verbosity, configuration);
+ this.instance = task.IsPreviewEncode ? HandBrakeInstanceManager.GetPreviewInstance(configuration.Verbosity, configuration) : HandBrakeInstanceManager.GetEncodeInstance(configuration.Verbosity, configuration, this.log);
this.instance.EncodeCompleted += this.InstanceEncodeCompleted;
this.instance.EncodeProgress += this.InstanceEncodeProgress;
diff --git a/win/CS/HandBrakeWPF/Services/Logging/LogService.cs b/win/CS/HandBrakeWPF/Services/Logging/LogService.cs
index c11b764b0..738cb2b3a 100644
--- a/win/CS/HandBrakeWPF/Services/Logging/LogService.cs
+++ b/win/CS/HandBrakeWPF/Services/Logging/LogService.cs
@@ -22,8 +22,10 @@ namespace HandBrakeWPF.Services.Logging
using HandBrake.Interop.Interop;
using HandBrake.Interop.Interop.EventArgs;
+ using HandBrake.Worker.Logging.Interfaces;
using HandBrake.Worker.Logging.Models;
+ using HandBrakeWPF.Instance;
using HandBrakeWPF.Instance.Model;
using HandBrakeWPF.Services.Interfaces;
using HandBrakeWPF.Services.Logging.Model;
@@ -34,7 +36,7 @@ namespace HandBrakeWPF.Services.Logging
using ILog = Interfaces.ILog;
using LogEventArgs = EventArgs.LogEventArgs;
- public class LogService : HttpRequestBase, ILog
+ public class LogService : ILog
{
// TODO List.
// Maybe make the event weak?
@@ -52,23 +54,11 @@ namespace HandBrakeWPF.Services.Logging
private bool isDiskLoggingEnabled;
private StreamWriter fileWriter;
private string logHeader;
- private Timer remoteLogPollTimer;
- private int remoteIndex = 0;
- private bool isRemotePollingEnabled = false;
public LogService(IUserSettingService userSettingService)
{
HandBrakeUtils.MessageLogged += this.HandBrakeUtils_MessageLogged;
HandBrakeUtils.ErrorLogged += this.HandBrakeUtils_ErrorLogged;
-
- if (userSettingService.GetUserSetting<bool>(UserSettingConstants.RemoteServiceEnabled))
- {
- this.ActivateRemoteLogPolling();
- this.isRemotePollingEnabled = true;
-
- this.port = userSettingService.GetUserSetting<int>(UserSettingConstants.RemoteServicePort);
- this.serverUrl = string.Format("http://127.0.0.1:{0}/", this.port);
- }
}
public event EventHandler<LogEventArgs> MessageLogged;
@@ -175,21 +165,6 @@ namespace HandBrakeWPF.Services.Logging
public async void Reset()
{
- //if (this.isRemotePollingEnabled)
- //{
- // try
- // {
- // await this.MakeHttpGetRequest("ResetLogging");
- // }
- // catch (Exception e)
- // {
- // if (this.remoteLogPollTimer != null)
- // {
- // this.remoteLogPollTimer.Stop();
- // }
- // }
- //}
-
lock (this.lockObject)
{
this.logMessages.Clear();
@@ -359,61 +334,9 @@ namespace HandBrakeWPF.Services.Logging
this.LogMessage(e.Message);
}
- private void ActivateRemoteLogPolling()
- {
- this.remoteLogPollTimer = new Timer();
- this.remoteLogPollTimer.Interval = 1000;
-
- this.remoteLogPollTimer.Elapsed += (o, e) =>
- {
- try
- {
- this.PollRemoteLog();
- }
- catch (Exception exc)
- {
- Debug.WriteLine(exc);
- }
- };
- this.remoteLogPollTimer.Start();
- }
-
- private async void PollRemoteLog()
+ void ILogHandler.ShutdownFileWriter()
{
- ServerResponse response = null;
- try
- {
- int nextIndex = this.remoteIndex + 1;
- string json = JsonConvert.SerializeObject(nextIndex, Formatting.Indented, this.jsonNetSettings);
-
- response = await this.MakeHttpJsonPostRequest("GetLogMessagesFromIndex", json);
- }
- catch (Exception e)
- {
- Debug.WriteLine("No Endpoint");
- }
-
- if (response == null || !response.WasSuccessful)
- {
- return;
- }
-
- string statusJson = response.JsonResponse;
-
- List<LogMessage> messages = null;
- if (!string.IsNullOrEmpty(statusJson))
- {
- messages = JsonConvert.DeserializeObject<List<LogMessage>>(statusJson, this.jsonNetSettings);
- }
-
- if (messages != null)
- {
- foreach (var item in messages)
- {
- this.LogMessage(item.Content);
- this.remoteIndex = item.MessageIndex;
- }
- }
+ throw new NotImplementedException();
}
}
}
diff --git a/win/CS/HandBrakeWPF/Services/UserSettingService.cs b/win/CS/HandBrakeWPF/Services/UserSettingService.cs
index 7e7b49e4a..4c181541a 100644
--- a/win/CS/HandBrakeWPF/Services/UserSettingService.cs
+++ b/win/CS/HandBrakeWPF/Services/UserSettingService.cs
@@ -305,7 +305,7 @@ namespace HandBrakeWPF.Services
// Experimental
defaults.Add(UserSettingConstants.RemoteServiceEnabled, false);
- defaults.Add(UserSettingConstants.RemoteServicePort, true);
+ defaults.Add(UserSettingConstants.RemoteServicePort, 8037);
// Misc
defaults.Add(UserSettingConstants.ShowPresetPanel, false);