--- /dev/null
+/* Encode.cs $\r
+ \r
+ This file is part of the HandBrake source code.\r
+ Homepage: <http://handbrake.fr>.\r
+ It may be used under the terms of the GNU General Public License. */\r
+\r
+using System;\r
+using System.Diagnostics;\r
+using System.Windows.Forms;\r
+using System.IO;\r
+using System.Runtime.InteropServices;\r
+using Handbrake.Functions;\r
+\r
+namespace Handbrake.EncodeQueue\r
+{\r
+ public class Encode\r
+ {\r
+ // DLL Imports\r
+ [DllImport("user32.dll")]\r
+ private static extern void LockWorkStation();\r
+ [DllImport("user32.dll")]\r
+ private static extern int ExitWindowsEx(int uFlags, int dwReason);\r
+ \r
+ /// <summary>\r
+ /// Execute a HandBrakeCLI process.\r
+ /// </summary>\r
+ /// <param name="query">The CLI Query</param>\r
+ public EncodeProcess runCli(string query)\r
+ {\r
+ EncodeProcess currentEncode = new EncodeProcess();\r
+ try\r
+ {\r
+ string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");\r
+ string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
+ string logPath = Path.Combine(logDir, "last_encode_log.txt");\r
+ string strCmdLine = String.Format(@" CMD /c """"{0}"" {1} 2>""{2}"" """, handbrakeCLIPath, query, logPath);\r
+\r
+ ProcessStartInfo cliStart = new ProcessStartInfo("CMD.exe", strCmdLine);\r
+ if (Properties.Settings.Default.enocdeStatusInGui == "Checked")\r
+ {\r
+ cliStart.RedirectStandardOutput = true;\r
+ cliStart.UseShellExecute = false;\r
+ }\r
+ if (Properties.Settings.Default.cli_minimized == "Checked")\r
+ cliStart.WindowStyle = ProcessWindowStyle.Minimized;\r
+\r
+ Process[] before = Process.GetProcesses(); // Get a list of running processes before starting.\r
+ currentEncode.hbProcProcess = Process.Start(cliStart);\r
+ currentEncode.processID = Main.getCliProcess(before);\r
+ currentEncode.isEncoding = true;\r
+ currentEncode.currentQuery = query;\r
+ currentEncode.processHandle = (int)currentEncode.hbProcProcess.MainWindowHandle; // Set the process Handle\r
+\r
+ // Set the process Priority\r
+ Process hbCliProcess = null;\r
+ if (currentEncode.processID != -1)\r
+ hbCliProcess = Process.GetProcessById(currentEncode.processID);\r
+\r
+ if (hbCliProcess != null)\r
+ switch (Properties.Settings.Default.processPriority)\r
+ {\r
+ case "Realtime":\r
+ hbCliProcess.PriorityClass = ProcessPriorityClass.RealTime;\r
+ break;\r
+ case "High":\r
+ hbCliProcess.PriorityClass = ProcessPriorityClass.High;\r
+ break;\r
+ case "Above Normal":\r
+ hbCliProcess.PriorityClass = ProcessPriorityClass.AboveNormal;\r
+ break;\r
+ case "Normal":\r
+ hbCliProcess.PriorityClass = ProcessPriorityClass.Normal;\r
+ break;\r
+ case "Low":\r
+ hbCliProcess.PriorityClass = ProcessPriorityClass.Idle;\r
+ break;\r
+ default:\r
+ hbCliProcess.PriorityClass = ProcessPriorityClass.BelowNormal;\r
+ break;\r
+ }\r
+ }\r
+ catch (Exception exc)\r
+ {\r
+ MessageBox.Show("An error occured in runCli()\n Error Information: \n\n" + exc);\r
+ }\r
+\r
+ return currentEncode;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Kill the CLI process\r
+ /// </summary>\r
+ public void closeCLI(EncodeProcess ep)\r
+ {\r
+ Process[] prs = Process.GetProcesses();\r
+ foreach (Process process in prs)\r
+ {\r
+ if (process.Id == ep.processID)\r
+ {\r
+ process.Refresh();\r
+ if (!process.HasExited)\r
+ process.Kill();\r
+\r
+ process.WaitForExit();\r
+ }\r
+ } \r
+ }\r
+\r
+ /// <summary>\r
+ /// Perform an action after an encode. e.g a shutdown, standby, restart etc.\r
+ /// </summary>\r
+ public void afterEncodeAction(EncodeProcess ep)\r
+ {\r
+ ep.isEncoding = false;\r
+ ep.currentQuery = String.Empty;\r
+ // Do something whent he encode ends.\r
+ switch (Properties.Settings.Default.CompletionOption)\r
+ {\r
+ case "Shutdown":\r
+ Process.Start("Shutdown", "-s -t 60");\r
+ break;\r
+ case "Log Off":\r
+ ExitWindowsEx(0, 0);\r
+ break;\r
+ case "Suspend":\r
+ Application.SetSuspendState(PowerState.Suspend, true, true);\r
+ break;\r
+ case "Hibernate":\r
+ Application.SetSuspendState(PowerState.Hibernate, true, true);\r
+ break;\r
+ case "Lock System":\r
+ LockWorkStation();\r
+ break;\r
+ case "Quit HandBrake":\r
+ Application.Exit();\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Append the CLI query to the start of the log file.\r
+ /// </summary>\r
+ /// <param name="query"></param>\r
+ public void addCLIQueryToLog(string query)\r
+ {\r
+ string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
+ string logPath = Path.Combine(logDir, "last_encode_log.txt");\r
+\r
+ StreamReader reader = new StreamReader(File.Open(logPath, FileMode.Open, FileAccess.Read));\r
+ String log = reader.ReadToEnd();\r
+ reader.Close();\r
+\r
+ StreamWriter writer = new StreamWriter(File.Create(logPath));\r
+\r
+ writer.Write("### CLI Query: " + query + "\n\n");\r
+ writer.Write("#########################################\n\n");\r
+ writer.WriteLine(log);\r
+ writer.Flush();\r
+ writer.Close();\r
+ }\r
+\r
+ /// <summary>\r
+ /// Save a copy of the log to the users desired location or a default location\r
+ /// if this feature is enabled in options.\r
+ /// </summary>\r
+ /// <param name="destination"></param>\r
+ public void copyLog(string destination)\r
+ {\r
+ try\r
+ {\r
+ string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
+ string tempLogFile = Path.Combine(logDir, "last_encode_log.txt");\r
+\r
+ string encodeDestinationPath = Path.GetDirectoryName(destination);\r
+ String[] destName = destination.Split('\\');\r
+ string destinationFile = destName[destName.Length - 1];\r
+ string encodeLogFile = DateTime.Now.ToString().Replace("/", "-").Replace(":", "-") + " " + destinationFile + ".txt";\r
+\r
+ // Make sure the log directory exists.\r
+ if (!Directory.Exists(logDir))\r
+ Directory.CreateDirectory(logDir);\r
+\r
+ // Copy the Log to HandBrakes log folder in the users applciation data folder.\r
+ File.Copy(tempLogFile, Path.Combine(logDir, encodeLogFile));\r
+\r
+ // Save a copy of the log file in the same location as the enocde.\r
+ if (Properties.Settings.Default.saveLogWithVideo == "Checked")\r
+ File.Copy(tempLogFile, Path.Combine(encodeDestinationPath, encodeLogFile));\r
+\r
+ // Save a copy of the log file to a user specified location\r
+ if (Directory.Exists(Properties.Settings.Default.saveLogPath))\r
+ if (Properties.Settings.Default.saveLogPath != String.Empty && Properties.Settings.Default.saveLogToSpecifiedPath == "Checked")\r
+ File.Copy(tempLogFile, Path.Combine(Properties.Settings.Default.saveLogPath, encodeLogFile));\r
+ }\r
+ catch (Exception exc)\r
+ {\r
+ MessageBox.Show("Something went a bit wrong trying to copy your log file.\nError Information:\n\n" + exc, "Error",\r
+ MessageBoxButtons.OK, MessageBoxIcon.Error);\r
+ }\r
+ }\r
+\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* QueueHandler.cs $\r
+ \r
+ This file is part of the HandBrake source code.\r
+ Homepage: <http://handbrake.fr/>.\r
+ It may be used under the terms of the GNU General Public License. */\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.IO;\r
+using System.Windows.Forms;\r
+using System.Xml.Serialization;\r
+using System.Threading;\r
+using System.Diagnostics;\r
+\r
+namespace Handbrake.EncodeQueue\r
+{\r
+ public class QueueHandler\r
+ {\r
+ Encode encodeHandler = new Encode();\r
+ private static XmlSerializer ser = new XmlSerializer(typeof(List<QueueItem>));\r
+ List<QueueItem> queue = new List<QueueItem>();\r
+ int id; // Unique identifer number for each job\r
+\r
+ #region Queue Handling\r
+ public List<QueueItem> getQueue()\r
+ {\r
+ return queue;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Get's the next CLI query for encoding\r
+ /// </summary>\r
+ /// <returns>String</returns>\r
+ private string getNextItemForEncoding()\r
+ {\r
+ QueueItem job = queue[0];\r
+ String query = job.Query;\r
+ lastQueueItem = job;\r
+ remove(0); // Remove the item which we are about to pass out.\r
+ return query;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Get the last query that was returned by getNextItemForEncoding()\r
+ /// </summary>\r
+ /// <returns></returns>\r
+ public QueueItem lastQueueItem { get; set; }\r
+\r
+ /// <summary>\r
+ /// Add's a new item to the queue\r
+ /// </summary>\r
+ /// <param name="query">String</param>\r
+ /// <param name="source"></param>\r
+ /// <param name="destination"></param>\r
+ public void add(string query, string source, string destination)\r
+ {\r
+ QueueItem newJob = new QueueItem { Id = id, Query = query, Source = source, Destination = destination };\r
+ id++;\r
+\r
+ queue.Add(newJob);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Check to see if a destination path is already on the queue\r
+ /// </summary>\r
+ /// <param name="destination">Destination path</param>\r
+ /// <returns>Boolean True/False. True = Path Exists</returns>\r
+ public Boolean checkDestinationPath(string destination)\r
+ {\r
+ foreach (QueueItem checkItem in queue)\r
+ {\r
+ if (checkItem.Destination.Contains(destination.Replace("\\\\", "\\")))\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Removes an item from the queue.\r
+ /// </summary>\r
+ /// <param name="index">Index</param>\r
+ /// <returns>Bolean true if successful</returns>\r
+ public void remove(int index)\r
+ {\r
+ queue.RemoveAt(index);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Returns how many items are in the queue\r
+ /// </summary>\r
+ /// <returns>Int</returns>\r
+ public int count()\r
+ {\r
+ return queue.Count;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Move an item with an index x, up in the queue\r
+ /// </summary>\r
+ /// <param name="index">Int</param>\r
+ public void moveUp(int index)\r
+ {\r
+ if (index > 0)\r
+ {\r
+ QueueItem item = queue[index];\r
+\r
+ queue.RemoveAt(index);\r
+ queue.Insert((index - 1), item);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Move an item with an index x, down in the queue\r
+ /// </summary>\r
+ /// <param name="index">Int</param>\r
+ public void moveDown(int index)\r
+ {\r
+ if (index < queue.Count - 1)\r
+ {\r
+ QueueItem item = queue[index];\r
+\r
+ queue.RemoveAt(index);\r
+ queue.Insert((index + 1), item);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Writes the current queue to disk. hb_queue_recovery.xml\r
+ /// This function is called after getNextItemForEncoding()\r
+ /// </summary>\r
+ public void write2disk(string file)\r
+ {\r
+ string tempPath = file == "hb_queue_recovery.xml" ? Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml") : file;\r
+\r
+ try\r
+ {\r
+ using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))\r
+ {\r
+ ser.Serialize(strm, queue);\r
+ strm.Close();\r
+ strm.Dispose();\r
+ }\r
+ }\r
+ catch (Exception)\r
+ {\r
+ // Any Errors will be out of diskspace/permissions problems. \r
+ // Don't report them as they'll annoy the user.\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Writes the current queue to disk to the location specified in file\r
+ /// </summary>\r
+ /// <param name="file"></param>\r
+ public void writeBatchScript(string file)\r
+ {\r
+ string queries = "";\r
+ foreach (QueueItem queue_item in queue)\r
+ {\r
+ string q_item = queue_item.Query;\r
+ string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + q_item;\r
+\r
+ if (queries == string.Empty)\r
+ queries = queries + fullQuery;\r
+ else\r
+ queries = queries + " && " + fullQuery;\r
+ }\r
+ string strCmdLine = queries;\r
+\r
+ if (file != "")\r
+ {\r
+ try\r
+ {\r
+ // Create a StreamWriter and open the file, Write the batch file query to the file and \r
+ // Close the stream\r
+ StreamWriter line = new StreamWriter(file);\r
+ line.WriteLine(strCmdLine);\r
+ line.Close();\r
+\r
+ MessageBox.Show("Your batch script has been sucessfully saved.", "Status", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);\r
+ }\r
+ catch (Exception)\r
+ {\r
+ MessageBox.Show("Unable to write to the file. Please make sure that the location has the correct permissions for file writing.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Recover the queue from hb_queue_recovery.xml\r
+ /// </summary>\r
+ public void recoverQueue(string file)\r
+ {\r
+ string tempPath;\r
+ if (file == "hb_queue_recovery.xml")\r
+ tempPath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");\r
+ else\r
+ tempPath = file;\r
+\r
+ if (File.Exists(tempPath))\r
+ {\r
+ using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))\r
+ {\r
+ if (strm.Length != 0)\r
+ {\r
+ List<QueueItem> list = ser.Deserialize(strm) as List<QueueItem>;\r
+\r
+ if (list != null)\r
+ foreach (QueueItem item in list)\r
+ queue.Add(item);\r
+\r
+ if (file != "hb_queue_recovery.xml")\r
+ write2disk("hb_queue_recovery.xml");\r
+ }\r
+ }\r
+ }\r
+ }\r
+ #endregion\r
+\r
+ #region Encoding\r
+\r
+ public Boolean isEncodeStarted { get; private set; }\r
+ public Boolean isPaused { get; private set; }\r
+ public Boolean isEncoding { get; private set; }\r
+ public EncodeProcess encodeProcess { get; set; }\r
+\r
+ public void startEncode()\r
+ { \r
+ Thread theQueue;\r
+ if (this.count() != 0)\r
+ {\r
+ if (isPaused)\r
+ isPaused = false;\r
+ else\r
+ {\r
+ isPaused = false;\r
+ try\r
+ {\r
+ theQueue = new Thread(startProc) { IsBackground = true };\r
+ theQueue.Start();\r
+ }\r
+ catch (Exception exc)\r
+ {\r
+ MessageBox.Show(exc.ToString());\r
+ }\r
+ }\r
+ }\r
+ }\r
+ public void pauseEncodeQueue()\r
+ {\r
+ isPaused = true;\r
+ EncodePaused(null);\r
+ }\r
+ public void endEncode()\r
+ {\r
+ encodeHandler.closeCLI(encodeProcess);\r
+ }\r
+\r
+ private void startProc(object state)\r
+ {\r
+ try\r
+ {\r
+ // Run through each item on the queue\r
+ while (this.count() != 0)\r
+ {\r
+ string query = getNextItemForEncoding();\r
+ write2disk("hb_queue_recovery.xml"); // Update the queue recovery file\r
+\r
+ encodeProcess = encodeHandler.runCli(query);\r
+ EncodeStarted(null);\r
+ encodeProcess.hbProcProcess.WaitForExit();\r
+\r
+ encodeHandler.addCLIQueryToLog(query);\r
+ encodeHandler.copyLog(lastQueueItem.Destination);\r
+\r
+ encodeProcess.hbProcProcess.Close();\r
+ encodeProcess.hbProcProcess.Dispose();\r
+ EncodeFinished(null);\r
+\r
+ while (isPaused) // Need to find a better way of doing this.\r
+ {\r
+ Thread.Sleep(10000);\r
+ }\r
+ }\r
+ EncodeQueueFinished(null);\r
+\r
+ // After the encode is done, we may want to shutdown, suspend etc.\r
+ encodeHandler.afterEncodeAction(encodeProcess);\r
+ }\r
+ catch (Exception exc)\r
+ {\r
+ throw new Exception(exc.ToString());\r
+ }\r
+ }\r
+ #endregion\r
+\r
+ #region Events\r
+ public event EventHandler OnEncodeStart;\r
+ public event EventHandler OnPaused;\r
+ public event EventHandler OnEncodeEnded;\r
+ public event EventHandler OnQueueFinished;\r
+\r
+ // Invoke the Changed event; called whenever encodestatus changes:\r
+ protected virtual void EncodeStarted(EventArgs e)\r
+ {\r
+ if (OnEncodeStart != null)\r
+ OnEncodeStart(this, e);\r
+\r
+ isEncoding = true;\r
+ }\r
+ protected virtual void EncodePaused(EventArgs e)\r
+ {\r
+ if (OnPaused != null)\r
+ OnPaused(this, e);\r
+ }\r
+ protected virtual void EncodeFinished(EventArgs e)\r
+ {\r
+ if (OnEncodeEnded != null)\r
+ OnEncodeEnded(this, e);\r
+\r
+ isEncoding = false;\r
+ }\r
+ protected virtual void EncodeQueueFinished(EventArgs e)\r
+ {\r
+ if (OnQueueFinished != null)\r
+ OnQueueFinished(this, e);\r
+ }\r
+ #endregion\r
+\r
+ }\r
+}
\ No newline at end of file