2 This file is part of the HandBrake source code.
\r
3 Homepage: <http://handbrake.fr/>.
\r
4 It may be used under the terms of the GNU General Public License. */
\r
6 namespace Handbrake.Services
\r
9 using System.Collections.Generic;
\r
10 using System.Collections.ObjectModel;
\r
12 using System.Threading;
\r
13 using System.Windows.Forms;
\r
14 using System.Xml.Serialization;
\r
19 /// The HandBrake Queue
\r
21 public class Queue : Encode
\r
24 /// The Queue Job List
\r
26 private readonly List<Job> queue = new List<Job>();
\r
29 /// An XML Serializer
\r
31 private static XmlSerializer serializer;
\r
36 private int nextJobId;
\r
39 /// Fires when a pause to the encode queue has been requested.
\r
41 public event EventHandler QueuePauseRequested;
\r
44 /// Fires when the entire encode queue has completed.
\r
46 public event EventHandler QueueCompleted;
\r
51 /// Gets and removes the next job in the queue.
\r
53 /// <returns>The job that was removed from the queue.</returns>
\r
54 private Job GetNextJob()
\r
56 Job job = this.queue[0];
\r
57 this.LastEncode = job;
\r
58 this.Remove(0); // Remove the item which we are about to pass out.
\r
60 this.WriteQueueStateToFile("hb_queue_recovery.xml");
\r
66 /// Gets the current state of the encode queue.
\r
68 public ReadOnlyCollection<Job> CurrentQueue
\r
70 get { return this.queue.AsReadOnly(); }
\r
74 /// Gets the number of items in the queue.
\r
78 get { return this.queue.Count; }
\r
82 /// Adds an item to the queue.
\r
84 /// <param name="query">
\r
85 /// The query that will be passed to the HandBrake CLI.
\r
87 /// <param name="title">
\r
90 /// <param name="source">
\r
91 /// The location of the source video.
\r
93 /// <param name="destination">
\r
94 /// The location where the encoded video will be.
\r
96 /// <param name="customJob">
\r
99 public void Add(string query, int title, string source, string destination, bool customJob)
\r
101 Job newJob = new Job
\r
103 Id = this.nextJobId++,
\r
107 Destination = destination,
\r
108 CustomQuery = customJob
\r
111 this.queue.Add(newJob);
\r
112 this.WriteQueueStateToFile("hb_queue_recovery.xml");
\r
116 /// Removes an item from the queue.
\r
118 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
119 public void Remove(int index)
\r
121 this.queue.RemoveAt(index);
\r
122 this.WriteQueueStateToFile("hb_queue_recovery.xml");
\r
126 /// Retrieve a job from the queue
\r
128 /// <param name="index">the job id</param>
\r
129 /// <returns>A job for the given index or blank job object</returns>
\r
130 public Job GetJob(int index)
\r
132 if (this.queue.Count >= (index + 1))
\r
133 return this.queue[index];
\r
139 /// Moves an item up one position in the queue.
\r
141 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
142 public void MoveUp(int index)
\r
146 Job item = queue[index];
\r
148 queue.RemoveAt(index);
\r
149 queue.Insert((index - 1), item);
\r
152 WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file
\r
156 /// Moves an item down one position in the queue.
\r
158 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
159 public void MoveDown(int index)
\r
161 if (index < this.queue.Count - 1)
\r
163 Job item = this.queue[index];
\r
165 this.queue.RemoveAt(index);
\r
166 this.queue.Insert((index + 1), item);
\r
169 this.WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file
\r
173 /// Writes the current state of the queue to a file.
\r
175 /// <param name="file">The location of the file to write the queue to.</param>
\r
176 public void WriteQueueStateToFile(string file)
\r
178 string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
\r
179 @"HandBrake\hb_queue_recovery.xml");
\r
180 string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file;
\r
184 using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
\r
186 if (serializer == null)
\r
187 serializer = new XmlSerializer(typeof (List<Job>));
\r
188 serializer.Serialize(strm, queue);
\r
200 /// Writes the current state of the queue in the form of a batch (.bat) file.
\r
202 /// <param name="file">The location of the file to write the batch file to.</param>
\r
203 public void WriteBatchScriptToFile(string file)
\r
205 string queries = string.Empty;
\r
206 foreach (Job queueItem in this.queue)
\r
208 string qItem = queueItem.Query;
\r
209 string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + qItem;
\r
211 if (queries == string.Empty)
\r
212 queries = queries + fullQuery;
\r
214 queries = queries + " && " + fullQuery;
\r
216 string strCmdLine = queries;
\r
218 if (file != string.Empty)
\r
222 // Create a StreamWriter and open the file, Write the batch file query to the file and
\r
223 // Close the stream
\r
224 using (StreamWriter line = new StreamWriter(file))
\r
226 line.WriteLine(strCmdLine);
\r
229 MessageBox.Show("Your batch script has been sucessfully saved.", "Status", MessageBoxButtons.OK,
\r
230 MessageBoxIcon.Asterisk);
\r
235 "Unable to write to the file. Please make sure that the location has the correct permissions for file writing.",
\r
236 "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
242 /// Reads a serialized XML file that represents a queue of encoding jobs.
\r
244 /// <param name="file">The location of the file to read the queue from.</param>
\r
245 public void LoadQueueFromFile(string file)
\r
247 string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
\r
248 @"HandBrake\hb_queue_recovery.xml");
\r
249 string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file;
\r
251 if (File.Exists(tempPath))
\r
253 using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))
\r
255 if (strm.Length != 0)
\r
257 if (serializer == null)
\r
258 serializer = new XmlSerializer(typeof (List<Job>));
\r
260 List<Job> list = serializer.Deserialize(strm) as List<Job>;
\r
263 foreach (Job item in list)
\r
264 this.queue.Add(item);
\r
266 if (file != "hb_queue_recovery.xml")
\r
267 this.WriteQueueStateToFile("hb_queue_recovery.xml");
\r
274 /// Checks the current queue for an existing instance of the specified destination.
\r
276 /// <param name="destination">The destination of the encode.</param>
\r
277 /// <returns>Whether or not the supplied destination is already in the queue.</returns>
\r
278 public bool CheckForDestinationDuplicate(string destination)
\r
280 foreach (Job checkItem in this.queue)
\r
282 if (checkItem.Destination.Contains(destination.Replace("\\\\", "\\")))
\r
294 /// Gets or sets the last encode that was processed.
\r
296 /// <returns></returns>
\r
297 public Job LastEncode { get; set; }
\r
300 /// Gets a value indicating whether Request Pause
\r
302 public bool PauseRequested { get; private set; }
\r
305 /// Starts encoding the first job in the queue and continues encoding until all jobs
\r
306 /// have been encoded.
\r
308 public void Start()
\r
310 if (this.Count != 0)
\r
312 if (this.PauseRequested)
\r
313 this.PauseRequested = false;
\r
316 this.PauseRequested = false;
\r
319 Thread theQueue = new Thread(this.StartQueue) {IsBackground = true};
\r
322 catch (Exception exc)
\r
324 MessageBox.Show(exc.ToString());
\r
331 /// Requests a pause of the encode queue.
\r
333 public void Pause()
\r
335 this.PauseRequested = true;
\r
337 if (this.QueuePauseRequested != null)
\r
338 this.QueuePauseRequested(this, new EventArgs());
\r
342 /// Run through all the jobs on the queue.
\r
344 /// <param name="state">Object State</param>
\r
345 private void StartQueue(object state)
\r
347 // Run through each item on the queue
\r
348 while (this.Count != 0)
\r
350 Job encJob = this.GetNextJob();
\r
351 this.WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file
\r
355 if (HbProcess == null)
\r
359 HbProcess.WaitForExit();
\r
361 AddCLIQueryToLog(encJob);
\r
362 this.CopyLog(this.LastEncode.Destination);
\r
365 HbProcess.Dispose();
\r
368 if (Properties.Settings.Default.growlEncode)
\r
369 GrowlCommunicator.Notify("Encode Completed",
\r
370 "Put down that cocktail...\nyour Handbrake encode is done.");
\r
372 while (this.PauseRequested) // Need to find a better way of doing this.
\r
374 Thread.Sleep(2000);
\r
377 this.LastEncode = new Job();
\r
379 if (this.QueueCompleted != null)
\r
380 this.QueueCompleted(this, new EventArgs());
\r
382 // After the encode is done, we may want to shutdown, suspend etc.
\r