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
14 using Handbrake.Functions;
\r
15 using Handbrake.Parsing;
\r
17 namespace Handbrake.EncodeQueue
\r
19 public class Queue : Encode
\r
21 private static XmlSerializer serializer;
\r
22 private readonly List<Job> queue = new List<Job>();
\r
23 private int NextJobId;
\r
25 #region Event Handlers
\r
27 /// Fires when an encode job has been started.
\r
29 public event EventHandler NewJobStarted;
\r
32 /// Fires when a pause to the encode queue has been requested.
\r
34 public event EventHandler QueuePauseRequested;
\r
37 /// Fires when an encode job has been completed.
\r
39 public event EventHandler CurrentJobCompleted;
\r
42 /// Fires when the entire encode queue has completed.
\r
44 public event EventHandler QueueCompleted;
\r
49 /// Gets and removes the next job in the queue.
\r
51 /// <returns>The job that was removed from the queue.</returns>
\r
52 private Job GetNextJob()
\r
56 Remove(0); // Remove the item which we are about to pass out.
\r
58 WriteQueueStateToFile("hb_queue_recovery.xml");
\r
64 /// Gets the current state of the encode queue.
\r
66 public ReadOnlyCollection<Job> CurrentQueue
\r
68 get { return queue.AsReadOnly(); }
\r
72 /// Gets the number of items in the queue.
\r
76 get { return queue.Count; }
\r
80 /// Adds an item to the queue.
\r
82 /// <param name="query">The query that will be passed to the HandBrake CLI.</param>
\r
83 /// <param name="source">The location of the source video.</param>
\r
84 /// <param name="destination">The location where the encoded video will be.</param>
\r
85 /// <param name="customJob">Custom job</param>
\r
86 /// <param name="scanInfo">The Scan</param>
\r
87 public void Add(string query, string source, string destination, bool customJob)
\r
89 Job newJob = new Job { Id = NextJobId++, Query = query, Source = source, Destination = destination, CustomQuery = customJob };
\r
92 WriteQueueStateToFile("hb_queue_recovery.xml");
\r
96 /// Removes an item from the queue.
\r
98 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
99 public void Remove(int index)
\r
101 queue.RemoveAt(index);
\r
102 WriteQueueStateToFile("hb_queue_recovery.xml");
\r
106 /// Retrieve a job from the queue
\r
108 /// <param name="index"></param>
\r
109 /// <returns></returns>
\r
110 public Job GetJob(int index)
\r
112 if (queue.Count >= (index +1))
\r
113 return queue[index];
\r
119 /// Moves an item up one position in the queue.
\r
121 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
122 public void MoveUp(int index)
\r
126 Job item = queue[index];
\r
128 queue.RemoveAt(index);
\r
129 queue.Insert((index - 1), item);
\r
132 WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file
\r
136 /// Moves an item down one position in the queue.
\r
138 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
139 public void MoveDown(int index)
\r
141 if (index < queue.Count - 1)
\r
143 Job item = queue[index];
\r
145 queue.RemoveAt(index);
\r
146 queue.Insert((index + 1), item);
\r
149 WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file
\r
153 /// Writes the current state of the queue to a file.
\r
155 /// <param name="file">The location of the file to write the queue to.</param>
\r
156 public void WriteQueueStateToFile(string file)
\r
158 string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\hb_queue_recovery.xml");
\r
159 string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file;
\r
163 using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
\r
165 if (serializer == null)
\r
166 serializer = new XmlSerializer(typeof(List<Job>));
\r
167 serializer.Serialize(strm, queue);
\r
174 // Any Errors will be out of diskspace/permissions problems.
\r
175 // Don't report them as they'll annoy the user.
\r
180 /// Writes the current state of the queue in the form of a batch (.bat) file.
\r
182 /// <param name="file">The location of the file to write the batch file to.</param>
\r
183 public void WriteBatchScriptToFile(string file)
\r
185 string queries = "";
\r
186 foreach (Job queue_item in queue)
\r
188 string q_item = queue_item.Query;
\r
189 string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + q_item;
\r
191 if (queries == string.Empty)
\r
192 queries = queries + fullQuery;
\r
194 queries = queries + " && " + fullQuery;
\r
196 string strCmdLine = queries;
\r
202 // Create a StreamWriter and open the file, Write the batch file query to the file and
\r
203 // Close the stream
\r
204 using (StreamWriter line = new StreamWriter(file))
\r
206 line.WriteLine(strCmdLine);
\r
209 MessageBox.Show("Your batch script has been sucessfully saved.", "Status", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
213 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
220 /// Reads a serialized XML file that represents a queue of encoding jobs.
\r
222 /// <param name="file">The location of the file to read the queue from.</param>
\r
223 public void LoadQueueFromFile(string file)
\r
225 string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\hb_queue_recovery.xml");
\r
226 string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file;
\r
228 if (File.Exists(tempPath))
\r
230 using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))
\r
232 if (strm.Length != 0)
\r
234 if (serializer == null)
\r
235 serializer = new XmlSerializer(typeof(List<Job>));
\r
237 List<Job> list = serializer.Deserialize(strm) as List<Job>;
\r
240 foreach (Job item in list)
\r
243 if (file != "hb_queue_recovery.xml")
\r
244 WriteQueueStateToFile("hb_queue_recovery.xml");
\r
251 /// Checks the current queue for an existing instance of the specified destination.
\r
253 /// <param name="destination">The destination of the encode.</param>
\r
254 /// <returns>Whether or not the supplied destination is already in the queue.</returns>
\r
255 public bool CheckForDestinationDuplicate(string destination)
\r
257 foreach (Job checkItem in queue)
\r
259 if (checkItem.Destination.Contains(destination.Replace("\\\\", "\\")))
\r
271 /// Gets the last encode that was processed.
\r
273 /// <returns></returns>
\r
274 public Job LastEncode { get; set; }
\r
279 public Boolean PauseRequested { get; private set; }
\r
282 /// Starts encoding the first job in the queue and continues encoding until all jobs
\r
283 /// have been encoded.
\r
285 public void Start()
\r
287 if (this.Count != 0)
\r
289 if (PauseRequested)
\r
290 PauseRequested = false;
\r
293 PauseRequested = false;
\r
296 Thread theQueue = new Thread(StartQueue) { IsBackground = true };
\r
299 catch (Exception exc)
\r
301 MessageBox.Show(exc.ToString());
\r
308 /// Requests a pause of the encode queue.
\r
310 public void Pause()
\r
312 PauseRequested = true;
\r
314 if (QueuePauseRequested != null)
\r
315 QueuePauseRequested(this, new EventArgs());
\r
319 /// Stops the current job.
\r
326 private void StartQueue(object state)
\r
328 // Run through each item on the queue
\r
329 while (this.Count != 0)
\r
331 Job encJob = GetNextJob();
\r
332 string query = encJob.Query;
\r
333 WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file
\r
337 if (NewJobStarted != null)
\r
338 NewJobStarted(this, new EventArgs());
\r
340 HbProcess.WaitForExit();
\r
342 AddCLIQueryToLog(encJob);
\r
343 CopyLog(LastEncode.Destination);
\r
346 HbProcess.Dispose();
\r
348 IsEncoding = false;
\r
351 if (Properties.Settings.Default.growlEncode)
\r
352 GrowlCommunicator.Notify("Encode Completed", "Put down that cocktail...\nyour Handbrake encode is done.");
\r
354 if (CurrentJobCompleted != null)
\r
355 CurrentJobCompleted(this, new EventArgs());
\r
357 while (PauseRequested) // Need to find a better way of doing this.
\r
359 Thread.Sleep(2000);
\r
362 LastEncode = new Job();
\r
364 if (QueueCompleted != null)
\r
365 QueueCompleted(this, new EventArgs());
\r
367 // After the encode is done, we may want to shutdown, suspend etc.
\r