OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Functions / Main.cs
1 /*  Main.cs $\r
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
5 \r
6 namespace Handbrake.Functions\r
7 {\r
8     using System;\r
9     using System.Collections.Generic;\r
10     using System.Diagnostics;\r
11     using System.IO;\r
12     using System.Net;\r
13     using System.Text.RegularExpressions;\r
14     using System.Threading;\r
15     using System.Windows.Forms;\r
16     using System.Xml.Serialization;\r
17     using EncodeQueue;\r
18     using Model;\r
19 \r
20     /// <summary>\r
21     /// Useful functions which various screens can use.\r
22     /// </summary>\r
23     public static class Main\r
24     {\r
25         /// <summary>\r
26         /// The XML Serializer\r
27         /// </summary>\r
28         private static readonly XmlSerializer Ser = new XmlSerializer(typeof(List<Job>));\r
29 \r
30         /// <summary>\r
31         /// Calculate the duration of the selected title and chapters\r
32         /// </summary>\r
33         /// <param name="chapterStart">\r
34         /// The chapter Start.\r
35         /// </param>\r
36         /// <param name="chapterEnd">\r
37         /// The chapter End.\r
38         /// </param>\r
39         /// <param name="selectedTitle">\r
40         /// The selected Title.\r
41         /// </param>\r
42         /// <returns>\r
43         /// The calculated duration.\r
44         /// </returns>\r
45         public static TimeSpan CalculateDuration(int chapterStart, int chapterEnd, Parsing.Title selectedTitle)\r
46         {\r
47             TimeSpan duration = TimeSpan.FromSeconds(0.0);\r
48             chapterStart++;\r
49             chapterEnd++;\r
50             if (chapterStart != 0 && chapterEnd != 0 && chapterEnd <= selectedTitle.Chapters.Count)\r
51             {\r
52                 for (int i = chapterStart; i <= chapterEnd; i++)\r
53                     duration += selectedTitle.Chapters[i - 1].Duration;\r
54             }\r
55 \r
56             return duration;\r
57         }\r
58 \r
59         /// <summary>\r
60         /// Select the longest title in the DVD title dropdown menu on frmMain\r
61         /// </summary>\r
62         /// <param name="source">\r
63         /// The Source.\r
64         /// </param>\r
65         /// <returns>\r
66         /// The longest title.\r
67         /// </returns>\r
68         public static Parsing.Title SelectLongestTitle(Parsing.DVD source)\r
69         {\r
70             TimeSpan longestDurationFound = TimeSpan.FromSeconds(0.0);\r
71             Parsing.Title returnTitle = null;\r
72 \r
73             foreach (Parsing.Title item in source.Titles)\r
74             {\r
75                 if (item.Duration > longestDurationFound)\r
76                 {\r
77                     returnTitle = item;\r
78                     longestDurationFound = item.Duration;\r
79                 }\r
80             }\r
81             return returnTitle;\r
82         }\r
83 \r
84         /// <summary>\r
85         /// Set's up the DataGridView on the Chapters tab (frmMain)\r
86         /// </summary>\r
87         /// <param name="dataChpt">\r
88         /// The DataGridView Control\r
89         /// </param>\r
90         /// <param name="chapterEnd">\r
91         /// The chapter End.\r
92         /// </param>\r
93         /// <returns>\r
94         /// The chapter naming.\r
95         /// </returns>\r
96         public static DataGridView ChapterNaming(DataGridView dataChpt, string chapterEnd)\r
97         {\r
98             int i = 0, finish = 0;\r
99 \r
100             if (chapterEnd != "Auto")\r
101                 int.TryParse(chapterEnd, out finish);\r
102 \r
103             while (i < finish)\r
104             {\r
105                 int n = dataChpt.Rows.Add();\r
106                 dataChpt.Rows[n].Cells[0].Value = i + 1;\r
107                 dataChpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);\r
108                 dataChpt.Rows[n].Cells[0].ValueType = typeof(int);\r
109                 dataChpt.Rows[n].Cells[1].ValueType = typeof(string);\r
110                 i++;\r
111             }\r
112 \r
113             return dataChpt;\r
114         }\r
115 \r
116         /// <summary>\r
117         /// Import a CSV file which contains Chapter Names\r
118         /// </summary>\r
119         /// <param name="dataChpt">\r
120         /// The DataGridView Control\r
121         /// </param>\r
122         /// <param name="filename">\r
123         /// The filepath and name\r
124         /// </param>\r
125         /// <returns>A Populated DataGridView</returns>\r
126         public static DataGridView ImportChapterNames(DataGridView dataChpt, string filename)\r
127         {\r
128             IDictionary<int, string> chapterMap = new Dictionary<int, string>();\r
129             try\r
130             {\r
131                 StreamReader sr = new StreamReader(filename);\r
132                 string csv = sr.ReadLine();\r
133                 while (csv != null)\r
134                 {\r
135                     if (csv.Trim() != string.Empty)\r
136                     {\r
137                         csv = csv.Replace("\\,", "<!comma!>");\r
138                         string[] contents = csv.Split(',');\r
139                         int chapter;\r
140                         int.TryParse(contents[0], out chapter);\r
141                         chapterMap.Add(chapter, contents[1].Replace("<!comma!>", ","));\r
142                     }\r
143                     csv = sr.ReadLine();\r
144                 }\r
145             }\r
146             catch (Exception)\r
147             {\r
148                 return null;\r
149             }\r
150 \r
151             foreach (DataGridViewRow item in dataChpt.Rows)\r
152             {\r
153                 string name;\r
154                 chapterMap.TryGetValue((int)item.Cells[0].Value, out name);\r
155                 item.Cells[1].Value = name ?? "Chapter " + item.Cells[0].Value;\r
156             }\r
157 \r
158             return dataChpt;\r
159         }\r
160 \r
161         /// <summary>\r
162         /// Function which generates the filename and path automatically based on \r
163         /// the Source Name, DVD title and DVD Chapters\r
164         /// </summary>\r
165         /// <param name="mainWindow">\r
166         /// The main Window.\r
167         /// </param>\r
168         /// <returns>\r
169         /// The Generated FileName\r
170         /// </returns>\r
171         public static string AutoName(frmMain mainWindow)\r
172         {\r
173             string autoNamePath = string.Empty;\r
174             if (mainWindow.drp_dvdtitle.Text != "Automatic")\r
175             {\r
176                 // Get the Source Name \r
177                 string sourceName = mainWindow.SourceName;\r
178 \r
179                 // Get the Selected Title Number\r
180                 string[] titlesplit = mainWindow.drp_dvdtitle.Text.Split(' ');\r
181                 string dvdTitle = titlesplit[0].Replace("Automatic", string.Empty);\r
182 \r
183                 // Get the Chapter Start and Chapter End Numbers\r
184                 string chapterStart = mainWindow.drop_chapterStart.Text.Replace("Auto", string.Empty);\r
185                 string chapterFinish = mainWindow.drop_chapterFinish.Text.Replace("Auto", string.Empty);\r
186                 string combinedChapterTag = chapterStart;\r
187                 if (chapterFinish != chapterStart && chapterFinish != string.Empty)\r
188                     combinedChapterTag = chapterStart + "-" + chapterFinish;\r
189 \r
190                 // Get the destination filename.\r
191                 string destinationFilename;\r
192                 if (Properties.Settings.Default.autoNameFormat != string.Empty)\r
193                 {\r
194                     destinationFilename = Properties.Settings.Default.autoNameFormat;\r
195                     destinationFilename = destinationFilename.Replace("{source}", sourceName).Replace("{title}", dvdTitle).Replace("{chapters}", combinedChapterTag);\r
196                 }\r
197                 else\r
198                     destinationFilename = sourceName + "_T" + dvdTitle + "_C" + combinedChapterTag;\r
199 \r
200                 // Add the appropriate file extension\r
201                 if (mainWindow.drop_format.SelectedIndex == 0)\r
202                 {\r
203                     if (Properties.Settings.Default.useM4v || mainWindow.Check_ChapterMarkers.Checked || mainWindow.AudioSettings.RequiresM4V() || mainWindow.Subtitles.RequiresM4V())\r
204                         destinationFilename += ".m4v";\r
205                     else\r
206                         destinationFilename += ".mp4";\r
207                 }\r
208                 else if (mainWindow.drop_format.SelectedIndex == 1)\r
209                     destinationFilename += ".mkv";\r
210 \r
211                 // Now work out the path where the file will be stored.\r
212                 // First case: If the destination box doesn't already contain a path, make one.\r
213                 if (!mainWindow.text_destination.Text.Contains(Path.DirectorySeparatorChar.ToString()))\r
214                 {\r
215                     // If there is an auto name path, use it...\r
216                     if (Properties.Settings.Default.autoNamePath.Trim() != string.Empty && Properties.Settings.Default.autoNamePath.Trim() != "Click 'Browse' to set the default location")\r
217                         autoNamePath = Path.Combine(Properties.Settings.Default.autoNamePath, destinationFilename);\r
218                     else // ...otherwise, output to the source directory\r
219                         autoNamePath = null;\r
220                 }\r
221                 else // Otherwise, use the path that is already there.\r
222                 {\r
223                     // Use the path and change the file extension to match the previous destination\r
224                     autoNamePath = Path.Combine(Path.GetDirectoryName(mainWindow.text_destination.Text), destinationFilename);\r
225 \r
226                     if (Path.HasExtension(mainWindow.text_destination.Text))\r
227                         autoNamePath = Path.ChangeExtension(autoNamePath, Path.GetExtension(mainWindow.text_destination.Text));\r
228                 }\r
229             }\r
230 \r
231             return autoNamePath;\r
232         }\r
233 \r
234         /// <summary>\r
235         /// Get's HandBrakes version data from the CLI.\r
236         /// </summary>\r
237         public static void SetCliVersionData()\r
238         {\r
239             string line;\r
240 \r
241             // 0 = SVN Build / Version\r
242             // 1 = Build Date\r
243             DateTime lastModified = File.GetLastWriteTime("HandBrakeCLI.exe");\r
244 \r
245             if (Properties.Settings.Default.cliLastModified == lastModified && Properties.Settings.Default.hb_build != 0)\r
246                 return;\r
247 \r
248             Properties.Settings.Default.cliLastModified = lastModified;\r
249 \r
250             Process cliProcess = new Process();\r
251             ProcessStartInfo handBrakeCli = new ProcessStartInfo("HandBrakeCLI.exe", " -u -v0")\r
252                                                 {\r
253                                                     UseShellExecute = false,\r
254                                                     RedirectStandardError = true,\r
255                                                     RedirectStandardOutput = true,\r
256                                                     CreateNoWindow = true\r
257                                                 };\r
258             cliProcess.StartInfo = handBrakeCli;\r
259 \r
260             try\r
261             {\r
262                 cliProcess.Start();\r
263 \r
264                 // Retrieve standard output and report back to parent thread until the process is complete\r
265                 TextReader stdOutput = cliProcess.StandardError;\r
266 \r
267                 while (!cliProcess.HasExited)\r
268                 {\r
269                     line = stdOutput.ReadLine() ?? string.Empty;\r
270                     Match m = Regex.Match(line, @"HandBrake ([svnM0-9.]*) \([0-9]*\)");\r
271                     Match platform = Regex.Match(line, @"- ([A-Za-z0-9\s ]*) -");\r
272 \r
273                     if (m.Success)\r
274                     {\r
275                         string data = line.Replace("(", string.Empty).Replace(")", string.Empty).Replace("HandBrake ", string.Empty);\r
276                         string[] arr = data.Split(' ');\r
277 \r
278                         Properties.Settings.Default.hb_build = int.Parse(arr[1]);\r
279                         Properties.Settings.Default.hb_version = arr[0];\r
280                     }\r
281 \r
282                     if (platform.Success)\r
283                     {\r
284                         Properties.Settings.Default.hb_platform = platform.Value.Replace("-", string.Empty).Trim();\r
285                     }\r
286 \r
287                     if (cliProcess.TotalProcessorTime.Seconds > 10) // Don't wait longer than 10 seconds.\r
288                     {\r
289                         Process cli = Process.GetProcessById(cliProcess.Id);\r
290                         if (!cli.HasExited)\r
291                         {\r
292                             cli.Kill();\r
293                         }\r
294                     }\r
295                 }\r
296 \r
297                 Properties.Settings.Default.Save();\r
298             }\r
299             catch (Exception e)\r
300             {\r
301                 MessageBox.Show("Unable to retrieve version information from the CLI. \nError:\n" + e);\r
302             }\r
303         }\r
304 \r
305         /// <summary>\r
306         /// Check if the queue recovery file contains records.\r
307         /// If it does, it means the last queue did not complete before HandBrake closed.\r
308         /// So, return a boolean if true. \r
309         /// </summary>\r
310         /// <returns>\r
311         /// True if there is a queue to recover.\r
312         /// </returns>\r
313         public static bool CheckQueueRecovery()\r
314         {\r
315             try\r
316             {\r
317                 string tempPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\hb_queue_recovery.xml");\r
318                 if (File.Exists(tempPath))\r
319                 {\r
320                     using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))\r
321                     {\r
322                         List<Job> list = Ser.Deserialize(strm) as List<Job>;\r
323                         if (list != null)\r
324                             if (list.Count != 0)\r
325                                 return true;\r
326                     }\r
327                 }\r
328                 return false;\r
329             }\r
330             catch (Exception)\r
331             {\r
332                 return false; // Keep quiet about the error.\r
333             }\r
334         }\r
335 \r
336         /// <summary>\r
337         /// Get the Process ID of HandBrakeCLI for the current instance.\r
338         /// </summary>\r
339         /// <param name="before">List of processes before the new process was started</param>\r
340         /// <returns>Int - Process ID</returns>\r
341         public static int GetCliProcess(Process[] before)\r
342         {\r
343             // This is a bit of a cludge. Maybe someone has a better idea on how to impliment this.\r
344             // Since we used CMD to start HandBrakeCLI, we don't get the process ID from hbProc.\r
345             // Instead we take the processes before and after, and get the ID of HandBrakeCLI.exe\r
346             // avoiding any previous instances of HandBrakeCLI.exe in before.\r
347             // Kill the current process.\r
348 \r
349             DateTime startTime = DateTime.Now;\r
350             TimeSpan duration;\r
351 \r
352             Process[] hbProcesses = Process.GetProcessesByName("HandBrakeCLI");\r
353             while (hbProcesses.Length == 0)\r
354             {\r
355                 hbProcesses = Process.GetProcessesByName("HandBrakeCLI");\r
356                 duration = DateTime.Now - startTime;\r
357                 if (duration.Seconds > 5 && hbProcesses.Length == 0) // Make sure we don't wait forever if the process doesn't start\r
358                     return -1;\r
359             }\r
360 \r
361             Process hbProcess = null;\r
362             foreach (Process process in hbProcesses)\r
363             {\r
364                 bool found = false;\r
365                 // Check if the current CLI instance was running before we started the current one\r
366                 foreach (Process bprocess in before)\r
367                 {\r
368                     if (process.Id == bprocess.Id)\r
369                         found = true;\r
370                 }\r
371 \r
372                 // If it wasn't running before, we found the process we want.\r
373                 if (!found)\r
374                 {\r
375                     hbProcess = process;\r
376                     break;\r
377                 }\r
378             }\r
379             if (hbProcess != null)\r
380                 return hbProcess.Id;\r
381 \r
382             return -1;\r
383         }\r
384 \r
385         /// <summary>\r
386         ///  Clear all the encode log files.\r
387         /// </summary>\r
388         public static void ClearLogs()\r
389         {\r
390             string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
391             if (Directory.Exists(logDir))\r
392             {\r
393                 DirectoryInfo info = new DirectoryInfo(logDir);\r
394                 FileInfo[] logFiles = info.GetFiles("*.txt");\r
395                 foreach (FileInfo file in logFiles)\r
396                 {\r
397                     if (!file.Name.Contains("last_scan_log") && !file.Name.Contains("last_encode_log") && !file.Name.Contains("tmp_appReadable_log.txt"))\r
398                         File.Delete(file.FullName);\r
399                 }\r
400             }\r
401         }\r
402 \r
403         /// <summary>\r
404         /// Clear old log files x days in the past\r
405         /// </summary>\r
406         public static void ClearOldLogs()\r
407         {\r
408             string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
409             if (Directory.Exists(logDir))\r
410             {\r
411                 DirectoryInfo info = new DirectoryInfo(logDir);\r
412                 FileInfo[] logFiles = info.GetFiles("*.txt");\r
413 \r
414                 foreach (FileInfo file in logFiles)\r
415                 {\r
416                     if (file.LastWriteTime < DateTime.Now.AddDays(-30))\r
417                     {\r
418                         if (!file.Name.Contains("last_scan_log") && !file.Name.Contains("last_encode_log") && !file.Name.Contains("tmp_appReadable_log.txt"))\r
419                             File.Delete(file.FullName);\r
420                     }\r
421                 }\r
422             }\r
423         }\r
424 \r
425         /// <summary>\r
426         /// Begins checking for an update to HandBrake.\r
427         /// </summary>\r
428         /// <param name="callback">The method that will be called when the check is finished.</param>\r
429         /// <param name="debug">Whether or not to execute this in debug mode.</param>\r
430         public static void BeginCheckForUpdates(AsyncCallback callback, bool debug)\r
431         {\r
432             ThreadPool.QueueUserWorkItem(new WaitCallback(delegate\r
433                                                               {\r
434                                                                   try\r
435                                                                   {\r
436                                                                       // Is this a stable or unstable build?\r
437                                                                       string url =\r
438                                                                           Properties.Settings.Default.hb_build.ToString()\r
439                                                                               .EndsWith("1")\r
440                                                                               ? Properties.Settings.Default.\r
441                                                                                     appcast_unstable\r
442                                                                               : Properties.Settings.Default.appcast;\r
443 \r
444                                                                       // Initialize variables\r
445                                                                       WebRequest request = WebRequest.Create(url);\r
446                                                                       WebResponse response = request.GetResponse();\r
447                                                                       AppcastReader reader = new AppcastReader();\r
448 \r
449                                                                       // Get the data, convert it to a string, and parse it into the AppcastReader\r
450                                                                       reader.GetInfo(\r
451                                                                           new StreamReader(response.GetResponseStream())\r
452                                                                               .ReadToEnd());\r
453 \r
454                                                                       // Further parse the information\r
455                                                                       string build = reader.Build;\r
456 \r
457                                                                       int latest = int.Parse(build);\r
458                                                                       int current = Properties.Settings.Default.hb_build;\r
459                                                                       int skip = Properties.Settings.Default.skipversion;\r
460 \r
461                                                                       // If the user wanted to skip this version, don't report the update\r
462                                                                       if (latest == skip)\r
463                                                                       {\r
464                                                                           UpdateCheckInformation info =\r
465                                                                               new UpdateCheckInformation\r
466                                                                                   {\r
467                                                                                       NewVersionAvailable = false,\r
468                                                                                       BuildInformation = null\r
469                                                                                   };\r
470                                                                           callback(new UpdateCheckResult(debug, info));\r
471                                                                           return;\r
472                                                                       }\r
473 \r
474                                                                       // Set when the last update was\r
475                                                                       Properties.Settings.Default.lastUpdateCheckDate =\r
476                                                                           DateTime.Now;\r
477                                                                       Properties.Settings.Default.Save();\r
478 \r
479                                                                       UpdateCheckInformation info2 =\r
480                                                                           new UpdateCheckInformation\r
481                                                                               {\r
482                                                                                   NewVersionAvailable = latest > current,\r
483                                                                                   BuildInformation = reader\r
484                                                                               };\r
485                                                                       callback(new UpdateCheckResult(debug, info2));\r
486                                                                   }\r
487                                                                   catch (Exception exc)\r
488                                                                   {\r
489                                                                       callback(new UpdateCheckResult(debug, new UpdateCheckInformation{Error = exc}));\r
490                                                                   }\r
491                                                               }));\r
492         }\r
493 \r
494         /// <summary>\r
495         /// End Check for Updates\r
496         /// </summary>\r
497         /// <param name="result">\r
498         /// The result.\r
499         /// </param>\r
500         /// <returns>\r
501         /// Update Check information\r
502         /// </returns>\r
503         public static UpdateCheckInformation EndCheckForUpdates(IAsyncResult result)\r
504         {\r
505             UpdateCheckResult checkResult = (UpdateCheckResult)result;\r
506             return checkResult.Result;\r
507         }\r
508 \r
509         /// <summary>\r
510         /// Map languages and their iso639_2 value into a IDictionary\r
511         /// </summary>\r
512         /// <returns>A Dictionary containing the language and iso code</returns>\r
513         public static IDictionary<string, string> MapLanguages()\r
514         {\r
515             IDictionary<string, string> languageMap = new Dictionary<string, string>\r
516                                                           {\r
517                                                               {"Any", "und"},\r
518                                                               {"Afar", "aar"},\r
519                                                               {"Abkhazian", "abk"},\r
520                                                               {"Afrikaans", "afr"},\r
521                                                               {"Akan", "aka"},\r
522                                                               {"Albanian", "sqi"},\r
523                                                               {"Amharic", "amh"},\r
524                                                               {"Arabic", "ara"},\r
525                                                               {"Aragonese", "arg"},\r
526                                                               {"Armenian", "hye"},\r
527                                                               {"Assamese", "asm"},\r
528                                                               {"Avaric", "ava"},\r
529                                                               {"Avestan", "ave"},\r
530                                                               {"Aymara", "aym"},\r
531                                                               {"Azerbaijani", "aze"},\r
532                                                               {"Bashkir", "bak"},\r
533                                                               {"Bambara", "bam"},\r
534                                                               {"Basque", "eus"},\r
535                                                               {"Belarusian", "bel"},\r
536                                                               {"Bengali", "ben"},\r
537                                                               {"Bihari", "bih"},\r
538                                                               {"Bislama", "bis"},\r
539                                                               {"Bosnian", "bos"},\r
540                                                               {"Breton", "bre"},\r
541                                                               {"Bulgarian", "bul"},\r
542                                                               {"Burmese", "mya"},\r
543                                                               {"Catalan", "cat"},\r
544                                                               {"Chamorro", "cha"},\r
545                                                               {"Chechen", "che"},\r
546                                                               {"Chinese", "zho"},\r
547                                                               {"Church Slavic", "chu"},\r
548                                                               {"Chuvash", "chv"},\r
549                                                               {"Cornish", "cor"},\r
550                                                               {"Corsican", "cos"},\r
551                                                               {"Cree", "cre"},\r
552                                                               {"Czech", "ces"},\r
553                                                               {"Dansk", "dan"},\r
554                                                               {"Divehi", "div"},\r
555                                                               {"Nederlands", "nld"},\r
556                                                               {"Dzongkha", "dzo"},\r
557                                                               {"English", "eng"},\r
558                                                               {"Esperanto", "epo"},\r
559                                                               {"Estonian", "est"},\r
560                                                               {"Ewe", "ewe"},\r
561                                                               {"Faroese", "fao"},\r
562                                                               {"Fijian", "fij"},\r
563                                                               {"Suomi", "fin"},\r
564                                                               {"Francais", "fra"},\r
565                                                               {"Western Frisian", "fry"},\r
566                                                               {"Fulah", "ful"},\r
567                                                               {"Georgian", "kat"},\r
568                                                               {"Deutsch", "deu"},\r
569                                                               {"Gaelic (Scots)", "gla"},\r
570                                                               {"Irish", "gle"},\r
571                                                               {"Galician", "glg"},\r
572                                                               {"Manx", "glv"},\r
573                                                               {"Greek Modern", "ell"},\r
574                                                               {"Guarani", "grn"},\r
575                                                               {"Gujarati", "guj"},\r
576                                                               {"Haitian", "hat"},\r
577                                                               {"Hausa", "hau"},\r
578                                                               {"Hebrew", "heb"},\r
579                                                               {"Herero", "her"},\r
580                                                               {"Hindi", "hin"},\r
581                                                               {"Hiri Motu", "hmo"},\r
582                                                               {"Magyar", "hun"},\r
583                                                               {"Igbo", "ibo"},\r
584                                                               {"Islenska", "isl"},\r
585                                                               {"Ido", "ido"},\r
586                                                               {"Sichuan Yi", "iii"},\r
587                                                               {"Inuktitut", "iku"},\r
588                                                               {"Interlingue", "ile"},\r
589                                                               {"Interlingua", "ina"},\r
590                                                               {"Indonesian", "ind"},\r
591                                                               {"Inupiaq", "ipk"},\r
592                                                               {"Italiano", "ita"},\r
593                                                               {"Javanese", "jav"},\r
594                                                               {"Japanese", "jpn"},\r
595                                                               {"Kalaallisut", "kal"},\r
596                                                               {"Kannada", "kan"},\r
597                                                               {"Kashmiri", "kas"},\r
598                                                               {"Kanuri", "kau"},\r
599                                                               {"Kazakh", "kaz"},\r
600                                                               {"Central Khmer", "khm"},\r
601                                                               {"Kikuyu", "kik"},\r
602                                                               {"Kinyarwanda", "kin"},\r
603                                                               {"Kirghiz", "kir"},\r
604                                                               {"Komi", "kom"},\r
605                                                               {"Kongo", "kon"},\r
606                                                               {"Korean", "kor"},\r
607                                                               {"Kuanyama", "kua"},\r
608                                                               {"Kurdish", "kur"},\r
609                                                               {"Lao", "lao"},\r
610                                                               {"Latin", "lat"},\r
611                                                               {"Latvian", "lav"},\r
612                                                               {"Limburgan", "lim"},\r
613                                                               {"Lingala", "lin"},\r
614                                                               {"Lithuanian", "lit"},\r
615                                                               {"Luxembourgish", "ltz"},\r
616                                                               {"Luba-Katanga", "lub"},\r
617                                                               {"Ganda", "lug"},\r
618                                                               {"Macedonian", "mkd"},\r
619                                                               {"Marshallese", "mah"},\r
620                                                               {"Malayalam", "mal"},\r
621                                                               {"Maori", "mri"},\r
622                                                               {"Marathi", "mar"},\r
623                                                               {"Malay", "msa"},\r
624                                                               {"Malagasy", "mlg"},\r
625                                                               {"Maltese", "mlt"},\r
626                                                               {"Moldavian", "mol"},\r
627                                                               {"Mongolian", "mon"},\r
628                                                               {"Nauru", "nau"},\r
629                                                               {"Navajo", "nav"},\r
630                                                               {"Ndebele, South", "nbl"},\r
631                                                               {"Ndebele, North", "nde"},\r
632                                                               {"Ndonga", "ndo"},\r
633                                                               {"Nepali", "nep"},\r
634                                                               {"Norwegian Nynorsk", "nno"},\r
635                                                               {"Norwegian Bokmål", "nob"},\r
636                                                               {"Norsk", "nor"},\r
637                                                               {"Chichewa; Nyanja", "nya"},\r
638                                                               {"Occitan", "oci"},\r
639                                                               {"Ojibwa", "oji"},\r
640                                                               {"Oriya", "ori"},\r
641                                                               {"Oromo", "orm"},\r
642                                                               {"Ossetian", "oss"},\r
643                                                               {"Panjabi", "pan"},\r
644                                                               {"Persian", "fas"},\r
645                                                               {"Pali", "pli"},\r
646                                                               {"Polish", "pol"},\r
647                                                               {"Portugues", "por"},\r
648                                                               {"Pushto", "pus"},\r
649                                                               {"Quechua", "que"},\r
650                                                               {"Romansh", "roh"},\r
651                                                               {"Romanian", "ron"},\r
652                                                               {"Rundi", "run"},\r
653                                                               {"Russian", "rus"},\r
654                                                               {"Sango", "sag"},\r
655                                                               {"Sanskrit", "san"},\r
656                                                               {"Serbian", "srp"},\r
657                                                               {"Hrvatski", "hrv"},\r
658                                                               {"Sinhala", "sin"},\r
659                                                               {"Slovak", "slk"},\r
660                                                               {"Slovenian", "slv"},\r
661                                                               {"Northern Sami", "sme"},\r
662                                                               {"Samoan", "smo"},\r
663                                                               {"Shona", "sna"},\r
664                                                               {"Sindhi", "snd"},\r
665                                                               {"Somali", "som"},\r
666                                                               {"Sotho Southern", "sot"},\r
667                                                               {"Espanol", "spa"},\r
668                                                               {"Sardinian", "srd"},\r
669                                                               {"Swati", "ssw"},\r
670                                                               {"Sundanese", "sun"},\r
671                                                               {"Swahili", "swa"},\r
672                                                               {"Svenska", "swe"},\r
673                                                               {"Tahitian", "tah"},\r
674                                                               {"Tamil", "tam"},\r
675                                                               {"Tatar", "tat"},\r
676                                                               {"Telugu", "tel"},\r
677                                                               {"Tajik", "tgk"},\r
678                                                               {"Tagalog", "tgl"},\r
679                                                               {"Thai", "tha"},\r
680                                                               {"Tibetan", "bod"},\r
681                                                               {"Tigrinya", "tir"},\r
682                                                               {"Tonga", "ton"},\r
683                                                               {"Tswana", "tsn"},\r
684                                                               {"Tsonga", "tso"},\r
685                                                               {"Turkmen", "tuk"},\r
686                                                               {"Turkish", "tur"},\r
687                                                               {"Twi", "twi"},\r
688                                                               {"Uighur", "uig"},\r
689                                                               {"Ukrainian", "ukr"},\r
690                                                               {"Urdu", "urd"},\r
691                                                               {"Uzbek", "uzb"},\r
692                                                               {"Venda", "ven"},\r
693                                                               {"Vietnamese", "vie"},\r
694                                                               {"Volapük", "vol"},\r
695                                                               {"Welsh", "cym"},\r
696                                                               {"Walloon", "wln"},\r
697                                                               {"Wolof", "wol"},\r
698                                                               {"Xhosa", "xho"},\r
699                                                               {"Yiddish", "yid"},\r
700                                                               {"Yoruba", "yor"},\r
701                                                               {"Zhuang", "zha"},\r
702                                                               {"Zulu", "zul"}\r
703                                                           };\r
704             return languageMap;\r
705         }\r
706 \r
707         /// <summary>\r
708         /// Get a list of available DVD drives which are ready and contain DVD content.\r
709         /// </summary>\r
710         /// <returns>A List of Drives with their details</returns>\r
711         public static List<DriveInformation> GetDrives()\r
712         {\r
713             List<DriveInformation> drives = new List<DriveInformation>();\r
714             DriveInfo[] theCollectionOfDrives = DriveInfo.GetDrives();\r
715             foreach (DriveInfo curDrive in theCollectionOfDrives)\r
716             {\r
717                 if (curDrive.DriveType == DriveType.CDRom && curDrive.IsReady && File.Exists(curDrive.RootDirectory + "VIDEO_TS\\VIDEO_TS.IFO"))\r
718                 {\r
719                     drives.Add(new DriveInformation\r
720                                    {\r
721                                        VolumeLabel = curDrive.VolumeLabel,\r
722                                        RootDirectory = curDrive.RootDirectory + "VIDEO_TS"\r
723                                    });\r
724                 }\r
725             }\r
726             return drives;\r
727         }\r
728     }\r
729 }