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.Windows.Forms;
\r
10 using System.Diagnostics;
\r
11 using System.Text.RegularExpressions;
\r
12 using System.Collections.Generic;
\r
13 using System.Xml.Serialization;
\r
14 using System.Threading;
\r
15 using Handbrake.EncodeQueue;
\r
17 namespace Handbrake.Functions
\r
21 // Private Variables
\r
22 private static readonly XmlSerializer ser = new XmlSerializer(typeof(List<Job>));
\r
25 /// Calculate the duration of the selected title and chapters
\r
27 public static TimeSpan calculateDuration(string chapter_start, string chapter_end, Parsing.Title selectedTitle)
\r
29 TimeSpan Duration = TimeSpan.FromSeconds(0.0);
\r
31 // Get the durations between the 2 chapter points and add them together.
\r
32 if (chapter_start != "Auto" && chapter_end != "Auto")
\r
34 int start_chapter, end_chapter;
\r
35 int.TryParse(chapter_start, out start_chapter);
\r
36 int.TryParse(chapter_end, out end_chapter);
\r
38 int position = start_chapter - 1;
\r
40 if (start_chapter <= end_chapter)
\r
42 if (end_chapter > selectedTitle.Chapters.Count)
\r
43 end_chapter = selectedTitle.Chapters.Count;
\r
45 while (position != end_chapter)
\r
47 TimeSpan dur = selectedTitle.Chapters[position].Duration;
\r
48 Duration = Duration + dur;
\r
57 /// Select the longest title in the DVD title dropdown menu on frmMain
\r
59 public static Parsing.Title selectLongestTitle(ComboBox drp_dvdtitle)
\r
61 int current_largest = 0;
\r
62 Parsing.Title title2Select;
\r
64 // Check if there are titles in the DVD title dropdown menu and make sure, it's not just "Automatic"
\r
65 if (drp_dvdtitle.Items[0].ToString() != "Automatic")
\r
66 title2Select = (Parsing.Title)drp_dvdtitle.Items[0];
\r
68 title2Select = null;
\r
70 // So, If there are titles in the DVD Title dropdown menu, lets select the longest.
\r
71 if (title2Select != null)
\r
73 foreach (Parsing.Title x in drp_dvdtitle.Items)
\r
75 string title = x.ToString();
\r
76 if (title != "Automatic")
\r
78 string[] y = title.Split(' ');
\r
79 string time = y[1].Replace("(", "").Replace(")", "");
\r
80 string[] z = time.Split(':');
\r
82 int hours = int.Parse(z[0]) * 60 * 60;
\r
83 int minutes = int.Parse(z[1]) * 60;
\r
84 int seconds = int.Parse(z[2]);
\r
85 int total_sec = hours + minutes + seconds;
\r
87 if (current_largest == 0)
\r
89 current_largest = hours + minutes + seconds;
\r
94 if (total_sec > current_largest)
\r
96 current_largest = total_sec;
\r
103 return title2Select;
\r
107 /// Set's up the DataGridView on the Chapters tab (frmMain)
\r
109 public static DataGridView chapterNaming(DataGridView data_chpt, string chapter_end)
\r
111 int i = 0, finish = 0;
\r
113 if (chapter_end != "Auto")
\r
114 int.TryParse(chapter_end, out finish);
\r
118 int n = data_chpt.Rows.Add();
\r
119 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
120 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
121 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
122 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
130 /// Function which generates the filename and path automatically based on
\r
131 /// the Source Name, DVD title and DVD Chapters
\r
133 public static string autoName(ComboBox drp_dvdtitle, string chapter_start, string chatper_end, string source, string dest, int format)
\r
135 string AutoNamePath = string.Empty;
\r
136 if (drp_dvdtitle.Text != "Automatic")
\r
138 // Get the Source Name
\r
139 string sourceName = Path.GetFileNameWithoutExtension(source);
\r
141 // Get the Selected Title Number
\r
142 string[] titlesplit = drp_dvdtitle.Text.Split(' ');
\r
143 string dvdTitle = titlesplit[0].Replace("Automatic", "");
\r
145 // Get the Chapter Start and Chapter End Numbers
\r
146 string chapterStart = chapter_start.Replace("Auto", "");
\r
147 string chapterFinish = chatper_end.Replace("Auto", "");
\r
148 string combinedChapterTag = chapterStart;
\r
149 if (chapterFinish != chapterStart && chapterFinish != "")
\r
150 combinedChapterTag = chapterStart + "-" + chapterFinish;
\r
152 // Get the destination filename.
\r
153 string destination_filename;
\r
154 if (Properties.Settings.Default.autoNameFormat != "")
\r
156 destination_filename = Properties.Settings.Default.autoNameFormat;
\r
157 destination_filename = destination_filename.Replace("{source}", sourceName).Replace("{title}", dvdTitle).Replace("{chapters}", combinedChapterTag);
\r
160 destination_filename = sourceName + "_T" + dvdTitle + "_C" + combinedChapterTag;
\r
162 // Add the appropriate file extension
\r
164 destination_filename += ".mp4";
\r
165 else if (format == 1)
\r
166 destination_filename += ".m4v";
\r
167 else if (format == 2)
\r
168 destination_filename += ".mkv";
\r
170 // Now work out the path where the file will be stored.
\r
171 // First case: If the destination box doesn't already contain a path, make one.
\r
172 if (!dest.Contains(Path.DirectorySeparatorChar.ToString()))
\r
174 // If there is an auto name path, use it...
\r
175 if (Properties.Settings.Default.autoNamePath.Trim() != "" && Properties.Settings.Default.autoNamePath.Trim() != "Click 'Browse' to set the default location")
\r
176 AutoNamePath = Path.Combine(Properties.Settings.Default.autoNamePath, destination_filename);
\r
177 else // ...otherwise, output to the source directory
\r
178 AutoNamePath = null;
\r
180 else // Otherwise, use the path that is already there.
\r
182 // Use the path and change the file extension to match the previous destination
\r
183 AutoNamePath = Path.Combine(Path.GetDirectoryName(dest), destination_filename);
\r
184 AutoNamePath = Path.ChangeExtension(AutoNamePath, Path.GetExtension(dest));
\r
188 return AutoNamePath;
\r
192 /// Checks for updates and returns true if an update is available.
\r
194 /// <param name="debug">Turns on debug mode. Don't use on program startup</param>
\r
195 /// <returns>Boolean True = Update available</returns>
\r
196 public static Boolean updateCheck(Boolean debug)
\r
200 AppcastReader rssRead = new AppcastReader();
\r
201 rssRead.getInfo(); // Initializes the class.
\r
202 string build = rssRead.build();
\r
204 int latest = int.Parse(build);
\r
205 int current = Properties.Settings.Default.hb_build;
\r
206 int skip = Properties.Settings.Default.skipversion;
\r
208 if (latest == skip)
\r
211 Boolean update = (latest > current);
\r
214 catch (Exception exc)
\r
217 MessageBox.Show("Unable to check for updates, Please try again later. \n" + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
223 /// Get's HandBrakes version data from the CLI.
\r
225 /// <returns>Arraylist of Version Data. 0 = hb_version 1 = hb_build</returns>
\r
226 public static void setCliVersionData()
\r
230 // 0 = SVN Build / Version
\r
232 Process cliProcess = new Process();
\r
233 ProcessStartInfo handBrakeCLI = new ProcessStartInfo("HandBrakeCLI.exe", " -u")
\r
235 UseShellExecute = false,
\r
236 RedirectStandardError = true,
\r
237 RedirectStandardOutput = true,
\r
238 CreateNoWindow = true
\r
240 cliProcess.StartInfo = handBrakeCLI;
\r
244 cliProcess.Start();
\r
245 // Retrieve standard output and report back to parent thread until the process is complete
\r
246 TextReader stdOutput = cliProcess.StandardError;
\r
248 while (!cliProcess.HasExited)
\r
250 line = stdOutput.ReadLine() ?? "";
\r
251 Match m = Regex.Match(line, @"HandBrake ([0-9.]*)(svn[0-9M]*) \([0-9]*\)");
\r
255 string data = line.Replace("(", "").Replace(")", "").Replace("HandBrake ", "");
\r
256 string[] arr = data.Split(' ');
\r
258 Properties.Settings.Default.hb_build = int.Parse(arr[1]);
\r
259 Properties.Settings.Default.hb_version = arr[0];
\r
261 if (cliProcess.TotalProcessorTime.Seconds > 10) // Don't wait longer than 10 seconds.
\r
263 Process cli = Process.GetProcessById(cliProcess.Id);
\r
264 if (!cli.HasExited)
\r
269 catch (Exception e)
\r
271 MessageBox.Show("Unable to retrieve version information from the CLI. \nError:\n" + e);
\r
276 /// Check if the queue recovery file contains records.
\r
277 /// If it does, it means the last queue did not complete before HandBrake closed.
\r
278 /// So, return a boolean if true.
\r
280 public static Boolean check_queue_recovery()
\r
284 string tempPath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");
\r
285 if (File.Exists(tempPath))
\r
287 using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))
\r
289 List<Job> list = ser.Deserialize(strm) as List<Job>;
\r
291 if (list.Count != 0)
\r
299 return false; // Keep quiet about the error.
\r
304 /// Get the Process ID of HandBrakeCLI for the current instance.
\r
306 /// <param name="before">List of processes before the new process was started</param>
\r
307 /// <returns>Int - Process ID</returns>
\r
308 public static int getCliProcess(Process[] before)
\r
310 // This is a bit of a cludge. Maybe someone has a better idea on how to impliment this.
\r
311 // Since we used CMD to start HandBrakeCLI, we don't get the process ID from hbProc.
\r
312 // Instead we take the processes before and after, and get the ID of HandBrakeCLI.exe
\r
313 // avoiding any previous instances of HandBrakeCLI.exe in before.
\r
314 // Kill the current process.
\r
316 Process[] hbProcesses = Process.GetProcessesByName("HandBrakeCLI");
\r
318 // Another hack. We maybe need to wait a few seconds for HandBrakeCLI to launch
\r
319 if (hbProcesses.Length == 0)
\r
321 Thread.Sleep(2000);
\r
322 hbProcesses = Process.GetProcessesByName("HandBrakeCLI");
\r
325 Process hbProcess = null;
\r
326 if (hbProcesses.Length > 0)
\r
327 foreach (Process process in hbProcesses)
\r
329 Boolean found = false;
\r
330 // Check if the current CLI instance was running before we started the current one
\r
331 foreach (Process bprocess in before)
\r
333 if (process.Id == bprocess.Id)
\r
337 // If it wasn't running before, we found the process we want.
\r
340 hbProcess = process;
\r
344 if (hbProcess != null)
\r
345 return hbProcess.Id;
\r