OSDN Git Service

WinGui;
[handbrake-jp/handbrake-jp-git.git] / win / C# / Presets / PlistPresetHandler.cs
1 /*  PlistPresetHandler.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.Presets\r
7 {\r
8     using System;\r
9     using System.Collections;\r
10     using System.IO;\r
11     using System.Text;\r
12     using System.Windows.Forms;\r
13     using System.Xml;\r
14     using Functions;\r
15     using Model;\r
16 \r
17     /// <summary>\r
18     /// Plist Preset Converter\r
19     /// </summary>\r
20     public class PlistPresetHandler\r
21     {\r
22         #region Import\r
23 \r
24         public static QueryParser Import(string filename)\r
25         {\r
26             XmlNode root = loadFile(filename);\r
27             if (root == null) return null;\r
28 \r
29             // We'll query a query parser object and use it's public var structures to store all the data.\r
30             // This will allow the preset loader logic to be used instead of writing custom logic just for this file.\r
31             QueryParser queryParsed = new QueryParser();\r
32             string qualityMode = string.Empty;\r
33 \r
34             #region Get a List of Audio Track Objects\r
35             XmlNode audioListDict = root.ChildNodes[2].ChildNodes[0].FirstChild.ChildNodes[1];\r
36             ArrayList audioTracks = new ArrayList();\r
37 \r
38             for (int i = 0; i < audioListDict.ChildNodes.Count; i++)\r
39             {\r
40                 XmlNode audioChannel = audioListDict.ChildNodes[i];\r
41                 AudioTrack track = new AudioTrack();\r
42 \r
43                 for (int subi = 0; subi < audioChannel.ChildNodes.Count; subi += 2)\r
44                 {\r
45                     // Audio Channel Information is here.\r
46                     string key = audioChannel.ChildNodes[subi].InnerText;\r
47                     string value = audioChannel.ChildNodes[subi + 1].InnerText;\r
48                     switch (key)\r
49                     {\r
50                         case "AudioBitrate":\r
51                             track.Bitrate = value;\r
52                             break;\r
53                         case "AudioEncoder":\r
54                             track.Encoder = value.Replace("AAC (CoreAudio)", "AAC (faac)");\r
55                             break;\r
56                         case "AudioMixdown":\r
57                             track.MixDown = value;\r
58                             break;\r
59                         case "AudioSamplerate":\r
60                             track.SampleRate = value;\r
61                             break;\r
62                         case "AudioTrack":\r
63                             track.Track = value;\r
64                             break;\r
65                         case "AudioTrackDRCSlider":\r
66                             track.DRC = value;\r
67                             break;\r
68                     }\r
69                 }\r
70                 audioTracks.Add(track);\r
71                 queryParsed.AudioInformation = audioTracks;\r
72             }\r
73             #endregion\r
74 \r
75             #region Parse the reset of the plist keys into local variables\r
76 \r
77             XmlNode presetSettings = root.ChildNodes[2].ChildNodes[0].FirstChild;\r
78 \r
79             // Start from 2 to avoid the audio settings which we don't need.\r
80             for (int i = 2; i < presetSettings.ChildNodes.Count; i += 2)\r
81             {\r
82                 string key = presetSettings.ChildNodes[i].InnerText;\r
83                 string value = presetSettings.ChildNodes[i + 1].InnerText;\r
84 \r
85                 switch (key)\r
86                 {\r
87                     // Output Settings\r
88                     case "FileFormat":\r
89                         queryParsed.Format = value;\r
90                         break;\r
91                     case "Mp4HttpOptimize":\r
92                         queryParsed.OptimizeMP4 = value == "1";\r
93                         break;\r
94                     case "Mp4LargeFile":\r
95                         queryParsed.LargeMP4 = value == "1";\r
96                         break;\r
97                     case "Mp4iPodCompatible":\r
98                         queryParsed.IpodAtom = value == "1";\r
99                         break;\r
100 \r
101                     // Picture Settings\r
102                     case "PictureAutoCrop":\r
103                         // Not used\r
104                         break;\r
105                     case "PictureTopCrop":\r
106                         queryParsed.CropTop = value;\r
107                         break;\r
108                     case "PictureBottomCrop":\r
109                         queryParsed.CropBottom = value;\r
110                         break;\r
111                     case "PictureLeftCrop":\r
112                         queryParsed.CropLeft = value;\r
113                         break;\r
114                     case "PictureRightCrop":\r
115                         queryParsed.CropRight = value;\r
116                         break;\r
117                     case "PictureHeight":\r
118                         queryParsed.Height = int.Parse(value);\r
119                         break;\r
120                     case "PictureWidth":\r
121                         queryParsed.Width = int.Parse(value);\r
122                         break;\r
123                     case "PictureKeepRatio":\r
124                         queryParsed.KeepDisplayAsect = value == "1";\r
125                         break;\r
126                     case "PicturePAR":\r
127                         queryParsed.AnamorphicMode = int.Parse(value);\r
128                         break;\r
129 \r
130                     // Filters\r
131                     case "PictureDeblock":\r
132                         queryParsed.DeBlock = int.Parse(value);\r
133                         break;\r
134                     case "PictureDecomb":\r
135                         queryParsed.Decomb = "Off";\r
136                         // Don't place custom here as it's handled in the filter panel\r
137                         if (value == "2") queryParsed.Decomb = "Default";\r
138                         break;\r
139                     case "PictureDecombCustom":\r
140                         if (value != string.Empty)\r
141                             queryParsed.Decomb = value;\r
142                         break;\r
143                     case "PictureDecombDeinterlace":\r
144                         // Not Used\r
145                         break;\r
146                     case "PictureDeinterlace":\r
147                         switch (value)\r
148                         {\r
149                             case "0":\r
150                                 queryParsed.DeInterlace = "Off";\r
151                                 break;\r
152                             // Don't place custom here as it's handled in the filter panel\r
153                             case "2":\r
154                                 queryParsed.DeInterlace = "Fast";\r
155                                 break;\r
156                             case "3":\r
157                                 queryParsed.DeInterlace = "Slow";\r
158                                 break;\r
159                             case "4":\r
160                                 queryParsed.DeInterlace = "Slowest";\r
161                                 break;\r
162                         }\r
163                         break;\r
164                     case "PictureDeinterlaceCustom":\r
165                         if (value != string.Empty)\r
166                             queryParsed.DeInterlace = value;\r
167                         break;\r
168                     case "PictureDenoise":\r
169                         switch (value)\r
170                         {\r
171                             case "0":\r
172                                 queryParsed.DeNoise = "Off";\r
173                                 break;\r
174                             // Don't place custom here as it's handled in the filter panel\r
175                             case "2":\r
176                                 queryParsed.DeNoise = "Weak";\r
177                                 break;\r
178                             case "3":\r
179                                 queryParsed.DeNoise = "Medium";\r
180                                 break;\r
181                             case "4":\r
182                                 queryParsed.DeNoise = "Strong";\r
183                                 break;\r
184                         }\r
185 \r
186                         break;\r
187                     case "PictureDenoiseCustom":\r
188                         if (value != string.Empty)\r
189                             queryParsed.DeNoise = value;\r
190                         break;\r
191                     case "PictureDetelecine":\r
192                         queryParsed.DeTelecine = "Off";\r
193                         if (value == "1") queryParsed.DeTelecine = "Default";\r
194                         break;\r
195                     case "PictureDetelecineCustom":\r
196                         if (value != string.Empty)\r
197                             queryParsed.DeTelecine = value;\r
198                         break;\r
199 \r
200                     // Video Tab\r
201                     case "VideoAvgBitrate":\r
202                         queryParsed.AverageVideoBitrate = value;\r
203                         break;\r
204                     case "VideoEncoder":\r
205                         queryParsed.VideoEncoder = value;\r
206                         break;\r
207                     case "VideoFramerate":\r
208                         queryParsed.VideoFramerate = value;\r
209                         break;\r
210                     case "VideoGrayScale":\r
211                         queryParsed.Grayscale = value == "1";\r
212                         break;\r
213                     case "VideoQualitySlider":\r
214                         queryParsed.VideoQuality = float.Parse(value);\r
215                         break;\r
216                     case "VideoQualityType": // The Type of Quality Mode used\r
217                         qualityMode = value;\r
218                         break;\r
219                     case "VideoTargetSize":\r
220                         queryParsed.VideoTargetSize = value;\r
221                         break;\r
222                     case "VideoTurboTwoPass":\r
223                         queryParsed.TurboFirstPass = value == "1";\r
224                         break;\r
225                     case "VideoTwoPass":\r
226                         queryParsed.TwoPass = value == "1";\r
227                         break;\r
228 \r
229                     // Chapter Markers Tab\r
230                     case "ChapterMarkers":\r
231                         queryParsed.ChapterMarkers = value == "1";\r
232                         break;\r
233 \r
234                     // Advanced x264 tab\r
235                     case "x264Option":\r
236                         queryParsed.H264Query = value;\r
237                         break;\r
238 \r
239                     // Preset Information\r
240                     case "PresetBuildNumber":\r
241                         queryParsed.PresetBuildNumber = int.Parse(value);\r
242                         break;\r
243                     case "PresetDescription":\r
244                         queryParsed.PresetDescription = value;\r
245                         break;\r
246                     case "PresetName":\r
247                         queryParsed.PresetName = value;\r
248                         break;\r
249                     case "Type":\r
250                         queryParsed.Type = value;\r
251                         break;\r
252                     case "UsesMaxPictureSettings":\r
253                         queryParsed.UsesMaxPictureSettings = value == "1";\r
254                         break;\r
255                     case "UsesPictureFilters":\r
256                         queryParsed.UsesPictureFilters = value == "1";\r
257                         break;\r
258                     case "UsesPictureSettings":\r
259                         queryParsed.UsesPictureSettings = value == "1";\r
260                         break;\r
261                 }\r
262             }\r
263 \r
264             // Kill any Quality values we don't need.\r
265             switch (qualityMode)\r
266             {\r
267                 case "0": // FileSize\r
268                     queryParsed.VideoQuality = -1;\r
269                     queryParsed.AverageVideoBitrate = null;\r
270                     break;\r
271                 case "1": // Avg Bitrate\r
272                     queryParsed.VideoQuality = -1;\r
273                     queryParsed.VideoTargetSize = null;\r
274                     break;\r
275                 case "2": // CQ\r
276                     queryParsed.AverageVideoBitrate = null;\r
277                     queryParsed.VideoTargetSize = null;\r
278                     break;\r
279             }\r
280             #endregion\r
281 \r
282             return queryParsed;\r
283         }\r
284 \r
285         private static XmlNode loadFile(string filename)\r
286         {\r
287             try\r
288             {\r
289                 XmlNode root;\r
290 \r
291                 if (!File.Exists(filename))\r
292                     return null;\r
293 \r
294                 StreamReader sr = File.OpenText(filename);\r
295                 string fromfile = string.Empty;\r
296                 int fileChar;\r
297                 while ((fileChar = sr.Read()) != -1)\r
298                     fromfile += Convert.ToChar(fileChar);\r
299 \r
300                 XmlDocument doc = new XmlDocument();\r
301                 doc.LoadXml(fromfile);\r
302 \r
303                 root = doc;\r
304                 if (!root.HasChildNodes)\r
305                 {\r
306                     MessageBox.Show(\r
307                         "The Preset file you selected appears to be invlaid or from an older version of HandBrake",\r
308                         "Error",\r
309                         MessageBoxButtons.OK, MessageBoxIcon.Error);\r
310                     return null;\r
311                 }\r
312 \r
313                 return root;\r
314             }\r
315             catch (Exception)\r
316             {\r
317                 MessageBox.Show(\r
318                     "The Preset file you selected appears to be invlaid or from an older version of HandBrake.\n\n Please note, if you are exporting from the MacGui you may need to rebuild your preset so that it uses the current preset plist format.\n The MacGui does not currently update user presets automatically.",\r
319                     "Error",\r
320                     MessageBoxButtons.OK, MessageBoxIcon.Error);\r
321                 return null;\r
322             }\r
323         }\r
324         #endregion\r
325 \r
326         #region Export\r
327 \r
328         /// <summary>\r
329         /// Export a MacGui style plist preset.\r
330         /// </summary>\r
331         /// <param name="path">\r
332         /// The path.\r
333         /// </param>\r
334         /// <param name="preset">\r
335         /// The preset.\r
336         /// </param>\r
337         public static void Export(string path, Preset preset)\r
338         {\r
339             QueryParser parsed = QueryParser.Parse(preset.Query);\r
340             XmlTextWriter xmlWriter = new XmlTextWriter(path, Encoding.UTF8) { Formatting = Formatting.Indented };\r
341 \r
342             // Header\r
343             xmlWriter.WriteStartDocument();\r
344             xmlWriter.WriteDocType("plist", "-//Apple//DTD PLIST 1.0//EN",\r
345                                 @"http://www.apple.com/DTDs/PropertyList-1.0.dtd", null);\r
346 \r
347             xmlWriter.WriteStartElement("plist");\r
348             xmlWriter.WriteStartElement("array");\r
349 \r
350             // Add New Preset Here. Can write multiple presets here if required in future.\r
351             WritePreset(xmlWriter, parsed, preset);\r
352 \r
353             // Footer\r
354             xmlWriter.WriteEndElement();\r
355             xmlWriter.WriteEndElement();\r
356 \r
357             xmlWriter.WriteEndDocument();\r
358 \r
359             // Closeout\r
360             xmlWriter.Close();\r
361         }\r
362 \r
363         /// <summary>\r
364         /// Write the Preset to a file\r
365         /// </summary>\r
366         /// <param name="xmlWriter">\r
367         /// The xml writer.\r
368         /// </param>\r
369         /// <param name="parsed">\r
370         /// The parsed.\r
371         /// </param>\r
372         /// <param name="preset">\r
373         /// The preset.\r
374         /// </param>\r
375         private static void WritePreset(XmlTextWriter xmlWriter, QueryParser parsed, Preset preset)\r
376         {\r
377             xmlWriter.WriteStartElement("dict");\r
378             AudioListArrayDict(xmlWriter, parsed);\r
379             AddEncodeSettings(xmlWriter, parsed, preset);\r
380 \r
381             xmlWriter.WriteEndElement();\r
382         }\r
383 \r
384         /// <summary>\r
385         /// Add the encode settings to the preset\r
386         /// </summary>\r
387         /// <param name="xmlWriter">\r
388         /// The xml writer.\r
389         /// </param>\r
390         /// <param name="parsed">\r
391         /// The parsed.\r
392         /// </param>\r
393         /// <param name="preset">\r
394         /// The preset.\r
395         /// </param>\r
396         private static void AddEncodeSettings(XmlTextWriter xmlWriter, QueryParser parsed, Preset preset)\r
397         {\r
398             AddEncodeElement(xmlWriter, "ChapterMarkers", "integer", parsed.ChapterMarkers ? "1" : "0");\r
399             AddEncodeElement(xmlWriter, "Default", "integer", "0");\r
400             AddEncodeElement(xmlWriter, "FileFormat", "string", parsed.Format.ToUpper() + " file");\r
401             AddBooleanElement(xmlWriter, "Folder", false);\r
402             AddEncodeElement(xmlWriter, "Mp4HttpOptimize", "integer", parsed.OptimizeMP4 ? "1" : "0");\r
403             AddEncodeElement(xmlWriter, "Mp4LargeFile", "integer", parsed.LargeMP4 ? "1" : "0");\r
404             AddEncodeElement(xmlWriter, "Mp4iPodCompatible", "integer", parsed.IpodAtom ? "1" : "0");\r
405             AddEncodeElement(xmlWriter, "PictureAutoCrop", "integer", "1");\r
406             AddEncodeElement(xmlWriter, "PictureBottomCrop", "integer", parsed.CropBottom);\r
407 \r
408             // Filters\r
409             AddEncodeElement(xmlWriter, "PictureDeblock", "integer", parsed.DeBlock.ToString());\r
410 \r
411             switch (parsed.Decomb)\r
412             {\r
413                 case "Off":\r
414                     AddEncodeElement(xmlWriter, "PictureDecomb", "integer", "0");\r
415                     AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", string.Empty);\r
416                     break;\r
417                 case "Default":\r
418                     AddEncodeElement(xmlWriter, "PictureDecomb", "integer", "1");\r
419                     AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", string.Empty);\r
420                     break;\r
421                 default:\r
422                     AddEncodeElement(xmlWriter, "PictureDecomb", "integer", "2");\r
423                     AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", parsed.Decomb);\r
424                     break;\r
425             }\r
426             AddEncodeElement(xmlWriter, "PictureDecombDeinterlace", "integer", parsed.Decomb != "Off" ? "0" : "1"); \r
427 \r
428             switch (parsed.DeInterlace)\r
429             {\r
430                 case "Off":\r
431                     AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "0");\r
432                     AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty);\r
433                     break;\r
434                 case "Fast":\r
435                     AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "1");\r
436                     AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty);\r
437                     break;\r
438                 case "Slow":\r
439                     AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "2");\r
440                     AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty);\r
441                     break;\r
442                 case "Slower":\r
443                     AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "3");\r
444                     AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty);\r
445                     break;\r
446                 default:\r
447                     AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "4");\r
448                     AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", parsed.DeInterlace);\r
449                     break;\r
450             }\r
451 \r
452             switch (parsed.DeNoise)\r
453             {\r
454                 case "Off":\r
455                     AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "0");\r
456                     AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", string.Empty);\r
457                     break;\r
458                 case "Weak":\r
459                     AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "1");\r
460                     AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", string.Empty);\r
461                     break;\r
462                 case "Medium":\r
463                     AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "2");\r
464                     AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", string.Empty);\r
465                     break;\r
466                 case "Strong":\r
467                     AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "3");\r
468                     AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", string.Empty);\r
469                     break;\r
470                 default:\r
471                     AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "4");\r
472                     AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", parsed.DeNoise);\r
473                     break;\r
474             }\r
475 \r
476             int detelecine;\r
477             switch (parsed.DeTelecine)\r
478             {\r
479                 case "Off":\r
480                     detelecine = 0;\r
481                     break;\r
482                 case "Default":\r
483                     detelecine = 2;\r
484                     break;\r
485                 default:\r
486                     detelecine = 1;\r
487                     break;\r
488             }\r
489             AddEncodeElement(xmlWriter, "PictureDetelecine", "integer", detelecine.ToString());\r
490             AddEncodeElement(xmlWriter, "PictureDetelecineCustom", "string", detelecine == 1 ? parsed.DeTelecine : string.Empty);\r
491 \r
492             // Picture Settings\r
493             AddEncodeElement(xmlWriter, "PictureHeight", "integer", parsed.Height.ToString());\r
494             AddEncodeElement(xmlWriter, "PictureKeepRatio", "integer", parsed.KeepDisplayAsect ? "1" : "0");\r
495             AddEncodeElement(xmlWriter, "PictureLeftCrop", "integer", parsed.CropLeft);\r
496             AddEncodeElement(xmlWriter, "PictureModulus", "integer", parsed.AnamorphicModulus.ToString());\r
497             AddEncodeElement(xmlWriter, "PicturePAR", "integer", parsed.AnamorphicMode.ToString());\r
498             AddEncodeElement(xmlWriter, "PictureRightCrop", "integer", parsed.CropRight);\r
499             AddEncodeElement(xmlWriter, "PictureTopCrop", "integer", parsed.CropTop);\r
500             AddEncodeElement(xmlWriter, "PictureWidth", "integer", parsed.Width.ToString());\r
501 \r
502             // Preset Information\r
503             AddEncodeElement(xmlWriter, "PresetBuildNumber", "string", Properties.Settings.Default.hb_build.ToString());\r
504             AddEncodeElement(xmlWriter, "PresetDescription", "string", "No Description");\r
505             AddEncodeElement(xmlWriter, "PresetName", "string", preset.Name);\r
506             AddEncodeElement(xmlWriter, "Type", "integer", "1"); // 1 is user preset, 0 is built in\r
507 \r
508             // Preset Settings\r
509             AddEncodeElement(xmlWriter, "UsesMaxPictureSettings", "integer", (parsed.MaxWidth != 0 || parsed.MaxHeight != 0) ? "1" : "0");\r
510             AddEncodeElement(xmlWriter, "UsesPictureFilters", "integer", "1");\r
511             AddEncodeElement(xmlWriter, "UsesPictureSettings", "integer", "2");\r
512 \r
513             // Video Settings\r
514             AddEncodeElement(xmlWriter, "VideoAvgBitrate", "string", parsed.AverageVideoBitrate);\r
515             AddEncodeElement(xmlWriter, "VideoEncoder", "string", parsed.VideoEncoder);\r
516             AddEncodeElement(xmlWriter, "VideoFramerate", "string", parsed.VideoFramerate);\r
517             AddEncodeElement(xmlWriter, "VideFrameratePFR", "integer", parsed.Pfr ? "1" : "0");\r
518             AddEncodeElement(xmlWriter, "VideoGrayScale", "integer", parsed.Grayscale ? "1" : "0");\r
519             AddEncodeElement(xmlWriter, "VideoQualitySlider", "real", parsed.VideoQuality.ToString());\r
520 \r
521             int videoQualityType = 0;\r
522             if (!string.IsNullOrEmpty(parsed.VideoTargetSize)) videoQualityType = 0;\r
523             else if (!string.IsNullOrEmpty(parsed.AverageVideoBitrate)) videoQualityType = 1;\r
524             else if (parsed.VideoQuality != 0) videoQualityType = 2;\r
525 \r
526             AddEncodeElement(xmlWriter, "VideoQualityType", "integer", videoQualityType.ToString());\r
527             AddEncodeElement(xmlWriter, "VideoTargetSize", "string", parsed.VideoTargetSize);\r
528             AddEncodeElement(xmlWriter, "VideoTurboTwoPass", "integer", parsed.TurboFirstPass ? "1" : "0");\r
529             AddEncodeElement(xmlWriter, "VideoTwoPass", "integer", parsed.TwoPass ? "1" : "0");\r
530 \r
531             // x264 string\r
532             AddEncodeElement(xmlWriter, "x264Option", "string", parsed.H264Query);\r
533         }\r
534 \r
535         /// <summary>\r
536         /// Add a boolean element\r
537         /// </summary>\r
538         /// <param name="xmlWriter">\r
539         /// The xml writer.\r
540         /// </param>\r
541         /// <param name="keyName">\r
542         /// The key name.\r
543         /// </param>\r
544         /// <param name="value">\r
545         /// The value.\r
546         /// </param>\r
547         private static void AddBooleanElement(XmlTextWriter xmlWriter, string keyName, bool value)\r
548         {\r
549             xmlWriter.WriteStartElement("key");\r
550             xmlWriter.WriteString(keyName);\r
551             xmlWriter.WriteEndElement();\r
552             xmlWriter.WriteStartElement(value ? "true" : "false");\r
553             xmlWriter.WriteEndElement();\r
554         }\r
555 \r
556         /// <summary>\r
557         /// Add an encode setting element\r
558         /// </summary>\r
559         /// <param name="xmlWriter">\r
560         /// The xml writer.\r
561         /// </param>\r
562         /// <param name="keyName">\r
563         /// The key name.\r
564         /// </param>\r
565         /// <param name="type">\r
566         /// The type.\r
567         /// </param>\r
568         /// <param name="value">\r
569         /// The value.\r
570         /// </param>\r
571         private static void AddEncodeElement(XmlTextWriter xmlWriter, string keyName, string type, string value)\r
572         {\r
573             xmlWriter.WriteElementString("key", keyName);\r
574 \r
575             // This is a hack for Apples XML parser. It doesn't understand <integer /> so instead, always set a default value\r
576             // of 0 if the value is empty.\r
577             if (type == "integer" && string.IsNullOrEmpty(value))\r
578             {\r
579                 value = "0";\r
580             }\r
581             xmlWriter.WriteElementString(type, value);\r
582         }\r
583 \r
584         /// <summary>\r
585         /// Add an Audio Track Array Dict\r
586         /// </summary>\r
587         /// <param name="xmlWriter">\r
588         /// The xml writer.\r
589         /// </param>\r
590         /// <param name="parsed">\r
591         /// The parsed.\r
592         /// </param>\r
593         private static void AudioListArrayDict(XmlTextWriter xmlWriter, QueryParser parsed)\r
594         {\r
595             xmlWriter.WriteStartElement("key");\r
596             xmlWriter.WriteString("AudioList");\r
597             xmlWriter.WriteEndElement();\r
598 \r
599             xmlWriter.WriteStartElement("array");\r
600             foreach (AudioTrack track in parsed.AudioInformation)\r
601             {\r
602                 AddAudioItem(xmlWriter, track);\r
603             }\r
604             xmlWriter.WriteEndElement();\r
605         }\r
606 \r
607         /// <summary>\r
608         /// Add an audio track\r
609         /// </summary>\r
610         /// <param name="xmlWriter">\r
611         /// The xml writer.\r
612         /// </param>\r
613         /// <param name="audioTrack">\r
614         /// The audio track.\r
615         /// </param>\r
616         private static void AddAudioItem(XmlTextWriter xmlWriter, AudioTrack audioTrack)\r
617         {\r
618             xmlWriter.WriteStartElement("dict");\r
619 \r
620             xmlWriter.WriteElementString("key", "AudioBitrate");\r
621             xmlWriter.WriteElementString("string", audioTrack.Bitrate);\r
622 \r
623             xmlWriter.WriteElementString("key", "AudioEncoder");\r
624             xmlWriter.WriteElementString("string", audioTrack.Encoder);\r
625 \r
626             xmlWriter.WriteElementString("key", "AudioMixdown");\r
627             xmlWriter.WriteElementString("string", audioTrack.MixDown);\r
628 \r
629             xmlWriter.WriteElementString("key", "AudioSamplerate");\r
630             xmlWriter.WriteElementString("string",  audioTrack.SampleRate);\r
631 \r
632             xmlWriter.WriteElementString("key", "AudioTrack");\r
633             xmlWriter.WriteElementString("integer", audioTrack.Track);\r
634 \r
635             xmlWriter.WriteElementString("key", "AudioTrackDRCSlider");\r
636             xmlWriter.WriteElementString("real", audioTrack.DRC);\r
637 \r
638             xmlWriter.WriteElementString("key", "AudioTrackDescription");\r
639             xmlWriter.WriteElementString("string", "Unknown");\r
640 \r
641             xmlWriter.WriteEndElement();\r
642         }\r
643         #endregion\r
644     }\r
645 }