1 /* QueueHandler.cs $
\r
3 This file is part of the HandBrake source code.
\r
4 Homepage: <http://handbrake.fr/>.
\r
5 It may be used under the terms of the GNU General Public License. */
\r
8 using System.Collections.Generic;
\r
9 using System.Collections.ObjectModel;
\r
11 using System.Threading;
\r
12 using System.Windows.Forms;
\r
13 using System.Xml.Serialization;
\r
15 namespace Handbrake.EncodeQueue
\r
18 /// Provides a handler for encoding jobs and a queue of those jobs.
\r
20 public class QueueHandler
\r
22 public Encode encodeHandler = new Encode();
\r
23 private static XmlSerializer serializer = new XmlSerializer(typeof(List<Job>));
\r
24 private List<Job> queue = new List<Job>();
\r
25 private int nextJobId;
\r
28 /// Gets the number of items in the queue.
\r
32 get { return queue.Count; }
\r
36 /// Gets the last encode that was processed.
\r
38 /// <returns></returns>
\r
39 public Job LastEncode { get; set; }
\r
42 /// Gets the current state of the encode queue.
\r
44 public ReadOnlyCollection<Job> CurrentQueue
\r
46 get { return queue.AsReadOnly(); }
\r
50 /// Fires when an encode job has been started.
\r
52 public event EventHandler NewJobStarted;
\r
55 /// Fires when a pause to the encode queue has been requested.
\r
57 public event EventHandler QueuePauseRequested;
\r
60 /// Fires when an encode job has been completed.
\r
62 public event EventHandler CurrentJobCompleted;
\r
65 /// Fires when the entire encode queue has completed.
\r
67 public event EventHandler QueueCompleted;
\r
69 #region Queue Handling
\r
72 /// Gets and removes the next job in the queue.
\r
74 /// <returns>The job that was removed from the queue.</returns>
\r
75 private Job GetNextJob()
\r
79 RemoveJob(0); // Remove the item which we are about to pass out.
\r
81 WriteQueueStateToFile("hb_queue_recovery.xml");
\r
87 /// Adds an item to the queue.
\r
89 /// <param name="query">The query that will be passed to the HandBrake CLI.</param>
\r
90 /// <param name="source">The location of the source video.</param>
\r
91 /// <param name="destination">The location where the encoded video will be.</param>
\r
92 public void AddJob(string query, string source, string destination)
\r
94 Job newJob = new Job { Id = nextJobId++, Query = query, Source = source, Destination = destination };
\r
97 WriteQueueStateToFile("hb_queue_recovery.xml");
\r
101 /// Removes an item from the queue.
\r
103 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
104 public void RemoveJob(int index)
\r
106 queue.RemoveAt(index);
\r
107 WriteQueueStateToFile("hb_queue_recovery.xml");
\r
111 /// Moves an item up one position in the queue.
\r
113 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
114 public void MoveUp(int index)
\r
118 Job item = queue[index];
\r
120 queue.RemoveAt(index);
\r
121 queue.Insert((index - 1), item);
\r
124 WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file
\r
128 /// Moves an item down one position in the queue.
\r
130 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
131 public void MoveDown(int index)
\r
133 if (index < queue.Count - 1)
\r
135 Job item = queue[index];
\r
137 queue.RemoveAt(index);
\r
138 queue.Insert((index + 1), item);
\r
141 WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file
\r
145 /// Writes the current state of the queue to a file.
\r
147 /// <param name="file">The location of the file to write the queue to.</param>
\r
148 public void WriteQueueStateToFile(string file)
\r
150 string tempPath = file == "hb_queue_recovery.xml" ? Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml") : file;
\r
154 using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
\r
156 serializer.Serialize(strm, queue);
\r
163 // Any Errors will be out of diskspace/permissions problems.
\r
164 // Don't report them as they'll annoy the user.
\r
169 /// Writes the current state of the queue in the form of a batch (.bat) file.
\r
171 /// <param name="file">The location of the file to write the batch file to.</param>
\r
172 public void WriteBatchScriptToFile(string file)
\r
174 string queries = "";
\r
175 foreach (Job queue_item in queue)
\r
177 string q_item = queue_item.Query;
\r
178 string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + q_item;
\r
180 if (queries == string.Empty)
\r
181 queries = queries + fullQuery;
\r
183 queries = queries + " && " + fullQuery;
\r
185 string strCmdLine = queries;
\r
191 // Create a StreamWriter and open the file, Write the batch file query to the file and
\r
192 // Close the stream
\r
193 using (StreamWriter line = new StreamWriter(file))
\r
195 line.WriteLine(strCmdLine);
\r
198 MessageBox.Show("Your batch script has been sucessfully saved.", "Status", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
202 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
209 /// Reads a serialized XML file that represents a queue of encoding jobs.
\r
211 /// <param name="file">The location of the file to read the queue from.</param>
\r
212 public void LoadQueueFromFile(string file)
\r
214 string tempPath = file == "hb_queue_recovery.xml" ? Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml") : file;
\r
216 if (File.Exists(tempPath))
\r
218 using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))
\r
220 if (strm.Length != 0)
\r
222 List<Job> list = serializer.Deserialize(strm) as List<Job>;
\r
225 foreach (Job item in list)
\r
228 if (file != "hb_queue_recovery.xml")
\r
229 WriteQueueStateToFile("hb_queue_recovery.xml");
\r
236 /// Checks the current queue for an existing instance of the specified destination.
\r
238 /// <param name="destination">The destination of the encode.</param>
\r
239 /// <returns>Whether or not the supplied destination is already in the queue.</returns>
\r
240 public bool CheckForDestinationDuplicate(string destination)
\r
242 foreach (Job checkItem in queue)
\r
244 if (checkItem.Destination.Contains(destination.Replace("\\\\", "\\")))
\r
255 public bool PauseRequested { get; private set; }
\r
256 public bool IsEncoding { get; private set; }
\r
259 /// Starts encoding the first job in the queue and continues encoding until all jobs
\r
260 /// have been encoded.
\r
262 public void StartEncodeQueue()
\r
264 if (this.Count != 0)
\r
266 if (PauseRequested)
\r
267 PauseRequested = false;
\r
270 PauseRequested = false;
\r
273 Thread theQueue = new Thread(startProcess) { IsBackground = true };
\r
276 catch (Exception exc)
\r
278 MessageBox.Show(exc.ToString());
\r
285 /// Requests a pause of the encode queue.
\r
287 public void RequestPause()
\r
289 PauseRequested = true;
\r
291 if (QueuePauseRequested != null)
\r
292 QueuePauseRequested(this, new EventArgs());
\r
296 /// Stops the current job.
\r
298 public void EndEncodeJob()
\r
300 encodeHandler.closeCLI();
\r
303 private void startProcess(object state)
\r
305 // Run through each item on the queue
\r
306 while (this.Count != 0)
\r
308 string query = GetNextJob().Query;
\r
309 WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file
\r
311 encodeHandler.runCli(query);
\r
313 if (NewJobStarted != null)
\r
314 NewJobStarted(this, new EventArgs());
\r
316 encodeHandler.hbProcess.WaitForExit();
\r
318 encodeHandler.addCLIQueryToLog(query);
\r
319 encodeHandler.copyLog(LastEncode.Destination);
\r
321 encodeHandler.hbProcess.Close();
\r
322 encodeHandler.hbProcess.Dispose();
\r
324 if (CurrentJobCompleted != null)
\r
325 CurrentJobCompleted(this, new EventArgs());
\r
327 while (PauseRequested) // Need to find a better way of doing this.
\r
329 Thread.Sleep(5000);
\r
333 if (QueueCompleted != null)
\r
334 QueueCompleted(this, new EventArgs());
\r
336 // After the encode is done, we may want to shutdown, suspend etc.
\r
337 encodeHandler.afterEncodeAction();
\r