// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // LibHB Implementation of IEncode // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrakeWPF.Services.Encode { using System; using System.Diagnostics; using System.IO; using HandBrake.Interop.Interop.EventArgs; using HandBrake.Interop.Interop.Interfaces; using HandBrake.Interop.Interop.Json.State; using HandBrake.Interop.Model; using HandBrakeWPF.Exceptions; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Encode.Factories; using EncodeTask = Model.EncodeTask; using HandBrakeInstanceManager = Instance.HandBrakeInstanceManager; using IEncode = Interfaces.IEncode; using ILog = Logging.Interfaces.ILog; using LogLevel = Logging.Model.LogLevel; using LogMessageType = Logging.Model.LogMessageType; using LogService = Logging.LogService; /// /// LibHB Implementation of IEncode /// public class LibEncode : EncodeBase, IEncode { #region Private Variables private ILog log = LogService.GetLogger(); private IEncodeInstance instance; private DateTime startTime; private EncodeTask currentTask; private HBConfiguration currentConfiguration; private bool isPreviewInstance; #endregion /// /// Gets a value indicating whether is pasued. /// public bool IsPasued { get; private set; } /// /// Start with a LibHb EncodeJob Object /// /// /// The task. /// /// /// The configuration. /// public void Start(EncodeTask task, HBConfiguration configuration) { try { // Sanity Checking and Setup if (this.IsEncoding) { throw new GeneralApplicationException(Resources.Queue_AlreadyEncoding, Resources.Queue_AlreadyEncodingSolution, null); } // Setup this.startTime = DateTime.Now; this.currentTask = task; this.currentConfiguration = configuration; // Create a new HandBrake instance // Setup the HandBrake Instance this.log.Reset(); // Reset so we have a clean log for the start of the encode. if (this.instance != null) { // Cleanup try { this.instance.EncodeCompleted -= this.InstanceEncodeCompleted; this.instance.EncodeProgress -= this.InstanceEncodeProgress; this.instance.Dispose(); this.instance = null; } catch (Exception exc) { this.ServiceLogMessage("Failed to cleanup previous instance: " + exc); } } this.ServiceLogMessage("Starting Encode ..."); this.instance = task.IsPreviewEncode ? HandBrakeInstanceManager.GetPreviewInstance(configuration.Verbosity, configuration) : HandBrakeInstanceManager.GetEncodeInstance(configuration.Verbosity, configuration); this.instance.EncodeCompleted += this.InstanceEncodeCompleted; this.instance.EncodeProgress += this.InstanceEncodeProgress; this.IsEncoding = true; this.isPreviewInstance = task.IsPreviewEncode; // Verify the Destination Path Exists, and if not, create it. this.VerifyEncodeDestinationPath(task); // Get an EncodeJob object for the Interop Library this.instance.StartEncode(EncodeTaskFactory.Create(task, configuration)); // Fire the Encode Started Event this.InvokeEncodeStarted(System.EventArgs.Empty); } catch (Exception exc) { this.IsEncoding = false; this.ServiceLogMessage("Failed to start encoding ..." + Environment.NewLine + exc); this.InvokeEncodeCompleted(new EventArgs.EncodeCompletedEventArgs(false, exc, "Unable to start encoding", task.Source, null, 0)); } } /// /// Pause the currently running encode. /// public void Pause() { if (this.instance != null) { this.instance.PauseEncode(); this.ServiceLogMessage("Encode Paused"); this.IsPasued = true; } } /// /// Resume the currently running encode. /// public void Resume() { if (this.instance != null) { this.instance.ResumeEncode(); this.ServiceLogMessage("Encode Resumed"); this.IsPasued = false; } } /// /// Kill the process /// public void Stop() { try { this.IsEncoding = false; if (this.instance != null) { this.instance.StopEncode(); this.ServiceLogMessage("Encode Stopped"); } } catch (Exception exc) { Debug.WriteLine(exc); } } #region HandBrakeInstance Event Handlers. /// /// Service Log Message. /// /// Log message content protected void ServiceLogMessage(string message) { this.log.LogMessage(string.Format("{0}# {1}{0}", Environment.NewLine, message), LogMessageType.ScanOrEncode, LogLevel.Info); } /// /// Encode Progress Event Handler /// /// /// The sender. /// /// /// The Interop.EncodeProgressEventArgs. /// private void InstanceEncodeProgress(object sender, EncodeProgressEventArgs e) { EventArgs.EncodeProgressEventArgs args = new EventArgs.EncodeProgressEventArgs { AverageFrameRate = e.AverageFrameRate, CurrentFrameRate = e.CurrentFrameRate, EstimatedTimeLeft = e.EstimatedTimeLeft, PercentComplete = e.FractionComplete * 100, Task = e.Pass, TaskCount = e.PassCount, ElapsedTime = DateTime.Now - this.startTime, PassId = e.PassId, IsMuxing = e.StateCode == TaskState.Muxing.Code, IsSearching = e.StateCode == TaskState.Searching.Code }; this.InvokeEncodeStatusChanged(args); } /// /// Encode Completed Event Handler /// /// /// The sender. /// /// /// The e. /// private void InstanceEncodeCompleted(object sender, EncodeCompletedEventArgs e) { this.IsEncoding = false; this.ServiceLogMessage("Encode Completed ..."); // Handling Log Data string hbLog = this.ProcessLogs(this.currentTask.Destination, this.isPreviewInstance, this.currentConfiguration); long filesize = this.GetFilesize(this.currentTask.Destination); // Raise the Encode Completed Event. this.InvokeEncodeCompleted( e.Error ? new EventArgs.EncodeCompletedEventArgs(false, null, string.Empty, this.currentTask.Destination, hbLog, filesize) : new EventArgs.EncodeCompletedEventArgs(true, null, string.Empty, this.currentTask.Destination, hbLog, filesize)); } private long GetFilesize(string destination) { try { if (!string.IsNullOrEmpty(destination) && File.Exists(destination)) { return new FileInfo(destination).Length; } return 0; } catch (Exception e) { this.ServiceLogMessage("Unable to get final filesize ..." + Environment.NewLine + e); Debug.WriteLine(e); } return 0; } #endregion } }