summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsr55 <[email protected]>2018-06-10 21:21:45 +0100
committersr55 <[email protected]>2018-06-10 21:22:13 +0100
commitc70981efae72a8392c18a7e92db667eddbc55485 (patch)
tree99b00bbc8287434684d99603710a189c4ef243aa
parentae881a0c1aa77a80deba7a3c81ab907e8e3d62ad (diff)
WinGui: Implement most of the HTTP Worker Process stubs.
-rw-r--r--win/CS/HandBrake.Interop/Interop/HandBrakeInstance.cs16
-rw-r--r--win/CS/HandBrake.Interop/Interop/HandBrakeInstanceManager.cs53
-rw-r--r--win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs20
-rw-r--r--win/CS/HandBrake.Interop/Interop/Interfaces/IHandBrakeInstance.cs13
-rw-r--r--win/CS/HandBrake.Interop/Model/HBConfiguration.cs10
-rw-r--r--win/CS/HandBrake.Worker/ApiRouter.cs52
-rw-r--r--win/CS/HandBrake.Worker/Program.cs13
-rw-r--r--win/CS/HandBrakeWPF/Factories/HBConfigurationFactory.cs4
-rw-r--r--win/CS/HandBrakeWPF/HandBrakeWPF.csproj7
-rw-r--r--win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs78
-rw-r--r--win/CS/HandBrakeWPF/Instance/Model/ServerResponse.cs24
-rw-r--r--win/CS/HandBrakeWPF/Instance/RemoteInstance.cs188
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs13
-rw-r--r--win/CS/HandBrakeWPF/Services/Scan/LibScan.cs19
-rw-r--r--win/CS/HandBrakeWPF/UserSettingConstants.cs10
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs1
-rw-r--r--win/CS/HandBrakeWPF/defaultsettings.xml16
17 files changed, 414 insertions, 123 deletions
diff --git a/win/CS/HandBrake.Interop/Interop/HandBrakeInstance.cs b/win/CS/HandBrake.Interop/Interop/HandBrakeInstance.cs
index 9f5420d3f..a5aef04a6 100644
--- a/win/CS/HandBrake.Interop/Interop/HandBrakeInstance.cs
+++ b/win/CS/HandBrake.Interop/Interop/HandBrakeInstance.cs
@@ -421,6 +421,22 @@ namespace HandBrake.Interop.Interop
}
/// <summary>
+ /// Checks the status of the ongoing encode.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="JsonState"/>.
+ /// </returns>
+ [HandleProcessCorruptedStateExceptions]
+ public JsonState GetEncodeProgress()
+ {
+ IntPtr json = HBFunctions.hb_get_state_json(this.hbHandle);
+ string statusJson = Marshal.PtrToStringAnsi(json);
+
+ JsonState state = JsonConvert.DeserializeObject<JsonState>(statusJson);
+ return state;
+ }
+
+ /// <summary>
/// Frees any resources associated with this object.
/// </summary>
public void Dispose()
diff --git a/win/CS/HandBrake.Interop/Interop/HandBrakeInstanceManager.cs b/win/CS/HandBrake.Interop/Interop/HandBrakeInstanceManager.cs
index 07ddb8a15..227fa0bd1 100644
--- a/win/CS/HandBrake.Interop/Interop/HandBrakeInstanceManager.cs
+++ b/win/CS/HandBrake.Interop/Interop/HandBrakeInstanceManager.cs
@@ -12,6 +12,7 @@ namespace HandBrake.Interop.Interop
using System;
using HandBrake.Interop.Interop.Interfaces;
+ using HandBrake.Interop.Model;
/// <summary>
/// The HandBrake Instance manager.
@@ -20,7 +21,6 @@ namespace HandBrake.Interop.Interop
public static class HandBrakeInstanceManager
{
private static HandBrakeInstance scanInstance;
- private static HandBrakeInstance encodeInstance;
private static HandBrakeInstance previewInstance;
private static HandBrakeInstance masterInstance;
@@ -71,34 +71,13 @@ namespace HandBrake.Interop.Interop
/// <param name="verbosity">
/// The verbosity.
/// </param>
- /// <returns>
- /// The <see cref="IHandBrakeInstance"/>.
- /// </returns>
- public static IHandBrakeInstance GetEncodeInstance(int verbosity)
- {
- if (encodeInstance != null)
- {
- encodeInstance.Dispose();
- encodeInstance = null;
- }
-
- HandBrakeInstance newInstance = new HandBrakeInstance();
- newInstance.Initialize(verbosity);
- encodeInstance = newInstance;
-
- return encodeInstance;
- }
-
- /// <summary>
- /// The get encode instance.
- /// </summary>
- /// <param name="verbosity">
- /// The verbosity.
+ /// <param name="configuration">
+ /// The configuration.
/// </param>
/// <returns>
/// The <see cref="IHandBrakeInstance"/>.
/// </returns>
- public static IHandBrakeInstance GetPreviewInstance(int verbosity)
+ public static IHandBrakeInstance GetPreviewInstance(int verbosity, HBConfiguration configuration)
{
if (previewInstance != null)
{
@@ -110,6 +89,8 @@ namespace HandBrake.Interop.Interop
newInstance.Initialize(verbosity);
previewInstance = newInstance;
+ HandBrakeUtils.SetDvdNav(!configuration.IsDvdNavDisabled);
+
return previewInstance;
}
@@ -145,27 +126,5 @@ namespace HandBrake.Interop.Interop
return scanInstance.Handle;
}
}
-
- /// <summary>
- /// Gets the last encode scan instance.
- /// </summary>
- internal static IHandBrakeInstance LastEncodeScanInstance
- {
- get
- {
- return encodeInstance;
- }
- }
-
- /// <summary>
- /// Gets the encode handle.
- /// </summary>
- internal static IntPtr LastEncodeHandle
- {
- get
- {
- return encodeInstance.Handle;
- }
- }
}
}
diff --git a/win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs b/win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs
index 68fd266f0..f0c4a2575 100644
--- a/win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs
+++ b/win/CS/HandBrake.Interop/Interop/Interfaces/IEncodeInstance.cs
@@ -13,6 +13,7 @@ namespace HandBrake.Interop.Interop.Interfaces
using HandBrake.Interop.Interop.EventArgs;
using HandBrake.Interop.Interop.Json.Encode;
+ using HandBrake.Interop.Interop.Json.State;
public interface IEncodeInstance
{
@@ -27,6 +28,19 @@ namespace HandBrake.Interop.Interop.Interfaces
event EventHandler<EncodeProgressEventArgs> EncodeProgress;
/// <summary>
+ /// Initializes this instance.
+ /// </summary>
+ /// <param name="verbosity">
+ /// The code for the logging verbosity to use.
+ /// </param>
+ void Initialize(int verbosity);
+
+ /// <summary>
+ /// Frees any resources associated with this object.
+ /// </summary>
+ void Dispose();
+
+ /// <summary>
/// Pauses the current encode.
/// </summary>
void PauseEncode();
@@ -48,5 +62,11 @@ namespace HandBrake.Interop.Interop.Interfaces
/// Stops the current encode.
/// </summary>
void StopEncode();
+
+ /// <summary>
+ /// Get the current Encode State.
+ /// </summary>
+ /// <returns>A JsonState object</returns>
+ JsonState GetEncodeProgress();
}
} \ No newline at end of file
diff --git a/win/CS/HandBrake.Interop/Interop/Interfaces/IHandBrakeInstance.cs b/win/CS/HandBrake.Interop/Interop/Interfaces/IHandBrakeInstance.cs
index b6d46c80c..193769090 100644
--- a/win/CS/HandBrake.Interop/Interop/Interfaces/IHandBrakeInstance.cs
+++ b/win/CS/HandBrake.Interop/Interop/Interfaces/IHandBrakeInstance.cs
@@ -61,19 +61,6 @@ namespace HandBrake.Interop.Interop.Interfaces
#region Public Methods
/// <summary>
- /// Initializes this instance.
- /// </summary>
- /// <param name="verbosity">
- /// The code for the logging verbosity to use.
- /// </param>
- void Initialize(int verbosity);
-
- /// <summary>
- /// Frees any resources associated with this object.
- /// </summary>
- void Dispose();
-
- /// <summary>
/// Gets an image for the given job and preview
/// </summary>
/// <remarks>
diff --git a/win/CS/HandBrake.Interop/Model/HBConfiguration.cs b/win/CS/HandBrake.Interop/Model/HBConfiguration.cs
index a9c59c8b4..77ea30954 100644
--- a/win/CS/HandBrake.Interop/Model/HBConfiguration.cs
+++ b/win/CS/HandBrake.Interop/Model/HBConfiguration.cs
@@ -63,5 +63,15 @@ namespace HandBrake.Interop.Model
/// Gets or sets the save log copy directory.
/// </summary>
public string SaveLogCopyDirectory { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether we use in-process or out-of-process encoding.
+ /// </summary>
+ public bool RemoteServiceEnabled { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating what port the worker process is to use.
+ /// </summary>
+ public int RemoteServicePort { get; set; }
}
}
diff --git a/win/CS/HandBrake.Worker/ApiRouter.cs b/win/CS/HandBrake.Worker/ApiRouter.cs
index 876680848..79b0ad262 100644
--- a/win/CS/HandBrake.Worker/ApiRouter.cs
+++ b/win/CS/HandBrake.Worker/ApiRouter.cs
@@ -14,34 +14,40 @@ namespace HandBrake.Worker
using System.Net;
using HandBrake.Interop.Interop;
+ using HandBrake.Interop.Interop.Json.State;
using HandBrake.Interop.Utilities;
using Newtonsoft.Json;
public class ApiRouter
{
+ private readonly JsonSerializerSettings jsonNetSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
private HandBrakeInstance handbrakeInstance;
- public string GetVersionInfo(HttpListenerRequest request)
+ public string Initialise(HttpListenerRequest request)
{
- JsonSerializerSettings settings =
- new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore };
+ if (this.handbrakeInstance == null)
+ {
+ this.handbrakeInstance = new HandBrakeInstance();
+ }
+
+ // TODO support verbosity
+ this.handbrakeInstance.Initialize(1);
+
+ return null;
+ }
- string versionInfo = JsonConvert.SerializeObject((object)VersionHelper.GetVersion(), Formatting.Indented, settings);
+ public string GetVersionInfo(HttpListenerRequest request)
+ {
+ string versionInfo = JsonConvert.SerializeObject(VersionHelper.GetVersion(), Formatting.Indented, this.jsonNetSettings);
return versionInfo;
}
public string StartEncode(HttpListenerRequest request)
{
- if (this.handbrakeInstance == null)
- {
- this.handbrakeInstance = new HandBrakeInstance();
- }
+ string requestPostData = GetRequestPostData(request);
- string requestPostData = ApiRouter.GetRequestPostData(request);
-
- this.handbrakeInstance.Initialize(1);
this.handbrakeInstance.StartEncode(requestPostData);
return null;
@@ -49,30 +55,21 @@ namespace HandBrake.Worker
public string StopEncode(HttpListenerRequest request)
{
- if (this.handbrakeInstance != null)
- {
- this.handbrakeInstance.StopEncode();
- }
+ this.handbrakeInstance?.StopEncode();
return (string)null;
}
public string PauseEncode(HttpListenerRequest request)
{
- if (this.handbrakeInstance != null)
- {
- this.handbrakeInstance.PauseEncode();
- }
+ this.handbrakeInstance?.PauseEncode();
return null;
}
public string ResumeEncode(HttpListenerRequest request)
{
- if (this.handbrakeInstance != null)
- {
- this.handbrakeInstance.ResumeEncode();
- }
+ this.handbrakeInstance?.ResumeEncode();
return null;
}
@@ -81,7 +78,10 @@ namespace HandBrake.Worker
{
if (this.handbrakeInstance != null)
{
- return null;
+ JsonState statusJson = this.handbrakeInstance.GetEncodeProgress();
+ string versionInfo = JsonConvert.SerializeObject(statusJson, Formatting.Indented, this.jsonNetSettings);
+
+ return versionInfo;
}
return null;
@@ -108,8 +108,4 @@ namespace HandBrake.Worker
}
}
}
-
- public class strixng
- {
- }
}
diff --git a/win/CS/HandBrake.Worker/Program.cs b/win/CS/HandBrake.Worker/Program.cs
index 139cf8c8f..d65d5d36a 100644
--- a/win/CS/HandBrake.Worker/Program.cs
+++ b/win/CS/HandBrake.Worker/Program.cs
@@ -15,6 +15,16 @@ namespace HandBrake.Worker
public class Program
{
+ /*
+ * TODO
+ * Methods:
+ * 1. Fetch Log
+ * 2. Fetch Log since last index.
+ * Services:
+ * 3. Support for connecting via sockets.
+ * 4. All methods will return a json state object response.
+ */
+
private static ApiRouter router;
public static void Main(string[] args)
@@ -66,7 +76,8 @@ namespace HandBrake.Worker
apiHandlers.Add("StopEncode", router.StopEncode);
apiHandlers.Add("PollEncodeProgress", router.PollEncodeProgress);
apiHandlers.Add("SetConfiguration", router.SetConfiguration);
-
+ apiHandlers.Add("Initialise", router.Initialise);
+
return apiHandlers;
}
}
diff --git a/win/CS/HandBrakeWPF/Factories/HBConfigurationFactory.cs b/win/CS/HandBrakeWPF/Factories/HBConfigurationFactory.cs
index 568f7e390..c4d199ef8 100644
--- a/win/CS/HandBrakeWPF/Factories/HBConfigurationFactory.cs
+++ b/win/CS/HandBrakeWPF/Factories/HBConfigurationFactory.cs
@@ -45,7 +45,9 @@ namespace HandBrakeWPF.Factories
SaveLogToCopyDirectory = UserSettingService.GetUserSetting<bool>(UserSettingConstants.SaveLogToCopyDirectory),
SaveLogWithVideo = UserSettingService.GetUserSetting<bool>(UserSettingConstants.SaveLogWithVideo),
SaveLogCopyDirectory = UserSettingService.GetUserSetting<string>(UserSettingConstants.SaveLogCopyDirectory),
- };
+ RemoteServiceEnabled = UserSettingService.GetUserSetting<bool>(UserSettingConstants.RemoteServiceEnabled),
+ RemoteServicePort = UserSettingService.GetUserSetting<int>(UserSettingConstants.RemoteServicePort)
+ };
return config;
}
diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
index 1c1d4da42..bbd1fb88d 100644
--- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
+++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
@@ -90,6 +90,7 @@
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
+ <Reference Include="System.Net.Http" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -153,6 +154,8 @@
<Compile Include="Helpers\MP4Helper.cs" />
<Compile Include="Helpers\TimeSpanHelper.cs" />
<Compile Include="Helpers\Validate.cs" />
+ <Compile Include="Instance\HandBrakeInstanceManager.cs" />
+ <Compile Include="Instance\Model\ServerResponse.cs" />
<Compile Include="Instance\RemoteInstance.cs" />
<Compile Include="Model\Audio\AudioBehaviourTrack.cs" />
<Compile Include="Model\Audio\AudioTrackDefaultsMode.cs" />
@@ -718,6 +721,10 @@
<Project>{087a2ba8-bac2-4577-a46f-07ff9d420016}</Project>
<Name>HandBrake.Interop</Name>
</ProjectReference>
+ <ProjectReference Include="..\HandBrake.Worker\HandBrake.Worker.csproj">
+ <Project>{f8370f37-b226-4830-aee7-6d7ae403e3d2}</Project>
+ <Name>HandBrake.Worker</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs b/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs
new file mode 100644
index 000000000..3fcf00e8f
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs
@@ -0,0 +1,78 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="HandBrakeInstanceManager.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>
+// The hand brake instance manager.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Instance
+{
+ using HandBrake.Interop.Interop;
+ using HandBrake.Interop.Interop.Interfaces;
+ using HandBrake.Interop.Model;
+
+ /// <summary>
+ /// The HandBrake Instance manager.
+ /// Only supports scanning right now.
+ /// </summary>
+ public static class HandBrakeInstanceManager
+ {
+ private static IEncodeInstance encodeInstance;
+
+ /// <summary>
+ /// Initializes static members of the <see cref="HandBrakeInstanceManager"/> class.
+ /// </summary>
+ static HandBrakeInstanceManager()
+ {
+ }
+
+ /// <summary>
+ /// The init.
+ /// </summary>
+ public static void Init()
+ {
+ // Nothing to do. Triggers static constructor.
+ }
+
+ /// <summary>
+ /// The get encode instance.
+ /// </summary>
+ /// <param name="verbosity">
+ /// The verbosity.
+ /// </param>
+ /// <param name="configuration">
+ /// The configuratio.
+ /// </param>
+ /// <returns>
+ /// The <see cref="IHandBrakeInstance"/>.
+ /// </returns>
+ public static IEncodeInstance GetEncodeInstance(int verbosity, HBConfiguration configuration)
+ {
+ if (encodeInstance != null)
+ {
+ encodeInstance.Dispose();
+ encodeInstance = null;
+ }
+
+ IEncodeInstance newInstance;
+
+ if (configuration.RemoteServiceEnabled)
+ {
+ newInstance = new RemoteInstance(configuration.RemoteServicePort);
+ }
+ else
+ {
+ newInstance = new HandBrakeInstance();
+ }
+
+ newInstance.Initialize(verbosity);
+ encodeInstance = newInstance;
+
+ HandBrakeUtils.SetDvdNav(!configuration.IsDvdNavDisabled);
+
+ return encodeInstance;
+ }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Instance/Model/ServerResponse.cs b/win/CS/HandBrakeWPF/Instance/Model/ServerResponse.cs
new file mode 100644
index 000000000..8b66a642c
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Instance/Model/ServerResponse.cs
@@ -0,0 +1,24 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="ServerResponse.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>
+// A model of the response from the HandBrake Worker instance.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Instance.Model
+{
+ public class ServerResponse
+ {
+ public ServerResponse(bool wasSuccessful, string jsonResponse)
+ {
+ this.WasSuccessful = wasSuccessful;
+ this.JsonResponse = jsonResponse;
+ }
+
+ public bool WasSuccessful { get; private set; }
+
+ public string JsonResponse { get; private set; }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs b/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs
index bfefb6caf..375dd2db1 100644
--- a/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs
+++ b/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs
@@ -4,54 +4,111 @@
// </copyright>
// <summary>
// An Implementation of IEncodeInstance that works with a remote process rather than locally in-process.
+// This class is effectivly just a shim.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace HandBrakeWPF.Instance
{
using System;
+ using System.Collections.Generic;
using System.Diagnostics;
+ using System.Linq;
+ using System.Net.Http;
+ using System.Threading.Tasks;
+ using System.Timers;
using HandBrake.Interop.Interop.EventArgs;
using HandBrake.Interop.Interop.Interfaces;
using HandBrake.Interop.Interop.Json.Encode;
+ using HandBrake.Interop.Interop.Json.State;
- public class RemoteInstance : IEncodeInstance
+ using HandBrakeWPF.Instance.Model;
+
+ using Newtonsoft.Json;
+
+ /*
+ * TODO:
+ * 1. Add support for logging.
+ * 2. Code to detect what ports are in use / select one within range.
+ * 3. Add support for communciating via socket instead of HTTP.
+ */
+
+ public class RemoteInstance : IEncodeInstance, IDisposable
{
+ private const double EncodePollIntervalMs = 500;
+ private readonly HttpClient client = new HttpClient();
+ private readonly string serverUrl;
+ private readonly int port;
private Process workerProcess;
+ private Timer encodePollTimer;
+
+ public RemoteInstance(int port)
+ {
+ this.port = port;
+ this.serverUrl = "http://localhost/";
+ }
public event EventHandler<EncodeCompletedEventArgs> EncodeCompleted;
public event EventHandler<EncodeProgressEventArgs> EncodeProgress;
- public void PauseEncode()
+ public async void PauseEncode()
{
- throw new NotImplementedException();
+ this.StopPollingProgres();
+ await this.MakeHttpGetRequest("PauseEncode");
}
- public void ResumeEncode()
+ public async void ResumeEncode()
{
- throw new NotImplementedException();
+ await this.MakeHttpGetRequest("ResumeEncode");
+ this.MonitorEncodeProgress();
}
- public void StartEncode(JsonEncodeObject jobToStart)
+ public async void StartEncode(JsonEncodeObject jobToStart)
{
- throw new NotImplementedException();
+ JsonSerializerSettings settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
+ string job = JsonConvert.SerializeObject(jobToStart, Formatting.Indented, settings);
+
+ var values = new Dictionary<string, string> { { "jpb", job } };
+ await this.MakeHttpPostRequest("StartEncode", values);
+
+ this.MonitorEncodeProgress();
}
- public void StopEncode()
+ public async void StopEncode()
{
- throw new NotImplementedException();
+ this.StopPollingProgres();
+ await this.MakeHttpGetRequest("StopEncode");
}
- protected virtual void OnEncodeCompleted(EncodeCompletedEventArgs e)
+ public JsonState GetEncodeProgress()
{
- this.EncodeCompleted?.Invoke(this, e);
+ Task<ServerResponse> response = this.MakeHttpGetRequest("PollEncodeProgress");
+ response.Wait();
+
+ if (!response.Result.WasSuccessful)
+ {
+ return null;
+ }
+
+ string statusJson = response.Result?.JsonResponse;
+
+ JsonState state = JsonConvert.DeserializeObject<JsonState>(statusJson);
+ return state;
}
- protected virtual void OnEncodeProgress(EncodeProgressEventArgs e)
+ public void Initialize(int verbosity)
{
- this.EncodeProgress?.Invoke(this, e);
+ this.StartServer();
+ }
+
+ public void Dispose()
+ {
+ this.client?.Dispose();
+ this.workerProcess?.Dispose();
+ this.StopEncode();
+ this.StopServer();
}
private void StartServer()
@@ -59,19 +116,42 @@ namespace HandBrakeWPF.Instance
if (this.workerProcess == null || this.workerProcess.HasExited)
{
this.workerProcess = new Process();
-
- // TODO Take default port from preferences, then find a usable port thereafter.
this.workerProcess.StartInfo =
- new ProcessStartInfo("HandBrake.Worker.exe", "--port=8080")
+ new ProcessStartInfo("HandBrake.Worker.exe", string.Format("--port={0}", this.port))
{
WindowStyle = ProcessWindowStyle.Normal
};
this.workerProcess.Start();
this.workerProcess.Exited += this.WorkerProcess_Exited;
+ Debug.WriteLine("Worker Process Started. PID = {0}", this.workerProcess.Id);
}
}
+ private void MonitorEncodeProgress()
+ {
+ this.encodePollTimer = new Timer();
+ this.encodePollTimer.Interval = EncodePollIntervalMs;
+
+ this.encodePollTimer.Elapsed += (o, e) =>
+ {
+ try
+ {
+ this.PollEncodeProgress();
+ }
+ catch (Exception exc)
+ {
+ Debug.WriteLine(exc);
+ }
+ };
+ this.encodePollTimer.Start();
+ }
+
+ private void StopPollingProgres()
+ {
+ this.encodePollTimer?.Stop();
+ }
+
private void WorkerProcess_Exited(object sender, EventArgs e)
{
Debug.WriteLine("Worker Process has exited");
@@ -84,5 +164,81 @@ namespace HandBrakeWPF.Instance
this.workerProcess.Kill();
}
}
+
+ private async void PollEncodeProgress()
+ {
+ ServerResponse response = await this.MakeHttpGetRequest("PollEncodeProgress");
+ if (!response.WasSuccessful)
+ {
+ return;
+ }
+
+ string statusJson = response.JsonResponse;
+
+ JsonState state = JsonConvert.DeserializeObject<JsonState>(statusJson);
+
+ TaskState taskState = state != null ? TaskState.FromRepositoryValue(state.State) : null;
+
+ if (taskState != null && (taskState == TaskState.Working || taskState == TaskState.Muxing || taskState == TaskState.Searching))
+ {
+ if (this.EncodeProgress != null)
+ {
+ var progressEventArgs = new EncodeProgressEventArgs(
+ fractionComplete: state.Working.Progress,
+ currentFrameRate: state.Working.Rate,
+ averageFrameRate: state.Working.RateAvg,
+ estimatedTimeLeft: new TimeSpan(state.Working.Hours, state.Working.Minutes, state.Working.Seconds),
+ passId: state.Working.PassID,
+ pass: state.Working.Pass,
+ passCount: state.Working.PassCount,
+ stateCode: taskState.Code);
+
+ this.EncodeProgress(this, progressEventArgs);
+ }
+ }
+ else if (taskState != null && taskState == TaskState.WorkDone)
+ {
+ this.encodePollTimer.Stop();
+
+ this.EncodeCompleted?.Invoke(sender: this, e: new EncodeCompletedEventArgs(state.WorkDone.Error != 0));
+ }
+ }
+
+ private async Task<ServerResponse> MakeHttpPostRequest(string urlPath, Dictionary<string, string> postValues)
+ {
+ if (postValues == null || !postValues.Any())
+ {
+ throw new InvalidOperationException("No Post Values Found.");
+ }
+
+ if (postValues.Any())
+ {
+ FormUrlEncodedContent content = new FormUrlEncodedContent(postValues);
+ HttpResponseMessage response = await this.client.PostAsync(this.serverUrl + urlPath, content);
+ if (response != null)
+ {
+ string returnContent = await response.Content.ReadAsStringAsync();
+ ServerResponse serverResponse = new ServerResponse(response.IsSuccessStatusCode, returnContent);
+
+ return serverResponse;
+ }
+ }
+
+ return null;
+ }
+
+ private async Task<ServerResponse> MakeHttpGetRequest(string urlPath)
+ {
+ HttpResponseMessage response = await this.client.GetAsync(this.serverUrl + urlPath);
+ if (response != null)
+ {
+ string returnContent = await response.Content.ReadAsStringAsync();
+ ServerResponse serverResponse = new ServerResponse(response.IsSuccessStatusCode, returnContent);
+
+ return serverResponse;
+ }
+
+ return null;
+ }
}
}
diff --git a/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs b/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs
index 85c5a42b1..a00344836 100644
--- a/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs
+++ b/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs
@@ -13,7 +13,6 @@ namespace HandBrakeWPF.Services.Encode
using System.Diagnostics;
using System.IO;
- using HandBrake.Interop.Interop;
using HandBrake.Interop.Interop.EventArgs;
using HandBrake.Interop.Interop.Interfaces;
using HandBrake.Interop.Interop.Json.State;
@@ -24,11 +23,12 @@ namespace HandBrakeWPF.Services.Encode
using HandBrakeWPF.Services.Encode.Factories;
using EncodeTask = Model.EncodeTask;
+ using HandBrakeInstanceManager = Instance.HandBrakeInstanceManager;
using IEncode = Interfaces.IEncode;
- using ILog = HandBrakeWPF.Services.Logging.Interfaces.ILog;
- using LogLevel = HandBrakeWPF.Services.Logging.Model.LogLevel;
- using LogMessageType = HandBrakeWPF.Services.Logging.Model.LogMessageType;
- using LogService = HandBrakeWPF.Services.Logging.LogService;
+ using ILog = Logging.Interfaces.ILog;
+ using LogLevel = Logging.Model.LogLevel;
+ using LogMessageType = Logging.Model.LogMessageType;
+ using LogService = Logging.LogService;
/// <summary>
/// LibHB Implementation of IEncode
@@ -80,8 +80,7 @@ namespace HandBrakeWPF.Services.Encode
this.log.Reset(); // Reset so we have a clean log for the start of the encode.
this.ServiceLogMessage("Starting Encode ...");
- HandBrakeUtils.SetDvdNav(!configuration.IsDvdNavDisabled);
- this.instance = task.IsPreviewEncode ? HandBrakeInstanceManager.GetPreviewInstance(configuration.Verbosity) : HandBrakeInstanceManager.GetEncodeInstance(configuration.Verbosity);
+ this.instance = task.IsPreviewEncode ? HandBrake.Interop.Interop.HandBrakeInstanceManager.GetPreviewInstance(configuration.Verbosity, configuration) : HandBrakeInstanceManager.GetEncodeInstance(configuration.Verbosity, configuration);
this.instance.EncodeCompleted += this.InstanceEncodeCompleted;
this.instance.EncodeProgress += this.InstanceEncodeProgress;
diff --git a/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs b/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs
index 7bcc5531b..d17a5d3c9 100644
--- a/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs
+++ b/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs
@@ -30,14 +30,14 @@ namespace HandBrakeWPF.Services.Scan
using HandBrakeWPF.Services.Scan.Model;
using HandBrakeWPF.Utilities;
- using Chapter = HandBrakeWPF.Services.Scan.Model.Chapter;
- using ILog = HandBrakeWPF.Services.Logging.Interfaces.ILog;
- using LogLevel = HandBrakeWPF.Services.Logging.Model.LogLevel;
- using LogMessageType = HandBrakeWPF.Services.Logging.Model.LogMessageType;
- using LogService = HandBrakeWPF.Services.Logging.LogService;
+ using Chapter = Model.Chapter;
+ using ILog = Logging.Interfaces.ILog;
+ using LogLevel = Logging.Model.LogLevel;
+ using LogMessageType = Logging.Model.LogMessageType;
+ using LogService = Logging.LogService;
using ScanProgressEventArgs = HandBrake.Interop.Interop.EventArgs.ScanProgressEventArgs;
- using Subtitle = HandBrakeWPF.Services.Scan.Model.Subtitle;
- using Title = HandBrakeWPF.Services.Scan.Model.Title;
+ using Subtitle = Model.Subtitle;
+ using Title = Model.Title;
/// <summary>
/// Scan a Source
@@ -129,7 +129,7 @@ namespace HandBrakeWPF.Services.Scan
this.postScanOperation = postAction;
// Create a new HandBrake Instance.
- this.instance = HandBrakeInstanceManager.GetScanInstance(configuraiton.Verbosity);
+ this.instance = HandBrake.Interop.Interop.HandBrakeInstanceManager.GetScanInstance(configuraiton.Verbosity);
this.instance.ScanProgress += this.InstanceScanProgress;
this.instance.ScanCompleted += this.InstanceScanCompleted;
@@ -266,8 +266,7 @@ namespace HandBrakeWPF.Services.Scan
this.ServiceLogMessage("Starting Scan ...");
this.instance.StartScan(sourcePath.ToString(), previewCount, minDuration, title != 0 ? title : 0);
- if (this.ScanStarted != null)
- this.ScanStarted(this, System.EventArgs.Empty);
+ this.ScanStarted?.Invoke(this, System.EventArgs.Empty);
}
catch (Exception exc)
{
diff --git a/win/CS/HandBrakeWPF/UserSettingConstants.cs b/win/CS/HandBrakeWPF/UserSettingConstants.cs
index 34d24d25d..9e4d37a17 100644
--- a/win/CS/HandBrakeWPF/UserSettingConstants.cs
+++ b/win/CS/HandBrakeWPF/UserSettingConstants.cs
@@ -256,6 +256,16 @@ namespace HandBrakeWPF
/// </summary>
public static string WhenDoneAudioFile = "WhenDoneAudioFile";
+ /// <summary>
+ /// Setting to store whether we are using a Worker Process or in-process encoding.
+ /// </summary>
+ public static string RemoteServiceEnabled = "RemoteServiceEnabled";
+
+ /// <summary>
+ /// The port that the worker process is running on.
+ /// </summary>
+ public static string RemoteServicePort = "RemoteServicePort";
+
#endregion
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
index 70fc5250e..9548fb573 100644
--- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
@@ -56,6 +56,7 @@ namespace HandBrakeWPF.ViewModels
using DataFormats = System.Windows.DataFormats;
using DragEventArgs = System.Windows.DragEventArgs;
using Execute = Caliburn.Micro.Execute;
+ using HandBrakeInstanceManager = HandBrakeWPF.Instance.HandBrakeInstanceManager;
using LogManager = HandBrakeWPF.Helpers.LogManager;
using MessageBox = System.Windows.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
diff --git a/win/CS/HandBrakeWPF/defaultsettings.xml b/win/CS/HandBrakeWPF/defaultsettings.xml
index c48921fff..853cf5396 100644
--- a/win/CS/HandBrakeWPF/defaultsettings.xml
+++ b/win/CS/HandBrakeWPF/defaultsettings.xml
@@ -520,4 +520,20 @@
<anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d4p1:type="q1:string" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">Choose a File:</anyType>
</value>
</item>
+ <item>
+ <key>
+ <string>RemoteServiceEnabled</string>
+ </key>
+ <value>
+ <anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d4p1:type="q1:boolean" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">false</anyType>
+ </value>
+ </item>
+ <item>
+ <key>
+ <string>RemoteServicePort</string>
+ </key>
+ <value>
+ <anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d4p1:type="q1:int" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">8080</anyType>
+ </value>
+ </item>
</dictionary> \ No newline at end of file