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 \r
35             #region Get a List of Audio Track Objects\r
36             XmlNode audioListDict = root.ChildNodes[2].ChildNodes[0].FirstChild.ChildNodes[1];\r
37             ArrayList audioTracks = new ArrayList();\r
38 \r
39             for (int i = 0; i < audioListDict.ChildNodes.Count; i++)\r
40             {\r
41                 XmlNode audioChannel = audioListDict.ChildNodes[i];\r
42                 AudioTrack track = new AudioTrack();\r
43 \r
44                 for (int subi = 0; subi < audioChannel.ChildNodes.Count; subi += 2)\r
45                 {\r
46                     // Audio Channel Information is here.\r
47                     string key = audioChannel.ChildNodes[subi].InnerText;\r
48                     string value = audioChannel.ChildNodes[subi + 1].InnerText;\r
49                     switch (key)\r
50                     {\r
51                         case "AudioBitrate":\r
52                             track.Bitrate = value;\r
53                             break;\r
54                         case "AudioEncoder":\r
55                             track.Encoder = value.Replace("AAC (CoreAudio)", "AAC (faac)");\r
56                             break;\r
57                         case "AudioMixdown":\r
58                             track.MixDown = value;\r
59                             break;\r
60                         case "AudioSamplerate":\r
61                             track.SampleRate = value;\r
62                             break;\r
63                         case "AudioTrack":\r
64                             track.Track = value;\r
65                             break;\r
66                         case "AudioTrackDRCSlider":\r
67                             track.DRC = value;\r
68                             break;\r
69                     }\r
70                 }\r
71                 audioTracks.Add(track);\r
72                 queryParsed.AudioInformation = audioTracks;\r
73             }\r
74             #endregion\r
75 \r
76             #region Parse the reset of the plist keys into local variables\r
77 \r
78             XmlNode presetSettings = root.ChildNodes[2].ChildNodes[0].FirstChild;\r
79 \r
80             // Start from 2 to avoid the audio settings which we don't need.\r
81             for (int i = 2; i < presetSettings.ChildNodes.Count; i += 2)\r
82             {\r
83                 string key = presetSettings.ChildNodes[i].InnerText;\r
84                 string value = presetSettings.ChildNodes[i + 1].InnerText;\r
85 \r
86                 switch (key)\r
87                 {\r
88                     // Output Settings\r
89                     case "FileFormat":\r
90                         queryParsed.Format = value;\r
91                         break;\r
92                     case "Mp4HttpOptimize":\r
93                         queryParsed.OptimizeMP4 = value == "1";\r
94                         break;\r
95                     case "Mp4LargeFile":\r
96                         queryParsed.LargeMP4 = value == "1";\r
97                         break;\r
98                     case "Mp4iPodCompatible":\r
99                         queryParsed.IpodAtom = value == "1";\r
100                         break;\r
101 \r
102                     // Picture Settings\r
103                     case "PictureAutoCrop":\r
104                         // Not used\r
105                         break;\r
106                     case "PictureTopCrop":\r
107                         queryParsed.CropTop = value;\r
108                         break;\r
109                     case "PictureBottomCrop":\r
110                         queryParsed.CropBottom = value;\r
111                         break;\r
112                     case "PictureLeftCrop":\r
113                         queryParsed.CropLeft = value;\r
114                         break;\r
115                     case "PictureRightCrop":\r
116                         queryParsed.CropRight = value;\r
117                         break;\r
118                     case "PictureHeight":\r
119                         queryParsed.Height = int.Parse(value);\r
120                         break;\r
121                     case "PictureWidth":\r
122                         queryParsed.Width = int.Parse(value);\r
123                         break;\r
124                     case "PictureKeepRatio":\r
125                         queryParsed.KeepDisplayAsect = value == "1";\r
126                         break;\r
127                     case "PicturePAR":\r
128                         queryParsed.AnamorphicMode = int.Parse(value);\r
129                         break;\r
130 \r
131                     // Filters\r
132                     case "PictureDeblock":\r
133                         queryParsed.DeBlock = int.Parse(value);\r
134                         break;\r
135                     case "PictureDecomb":\r
136                         queryParsed.Decomb = "Off";\r
137                         // Don't place custom here as it's handled in the filter panel\r
138                         if (value == "2") queryParsed.Decomb = "Default";\r
139                         break;\r
140                     case "PictureDecombCustom":\r
141                         if (value != string.Empty)\r
142                             queryParsed.Decomb = value;\r
143                         break;\r
144                     case "PictureDecombDeinterlace":\r
145                         // Not Used\r
146                         break;\r
147                     case "PictureDeinterlace":\r
148                         switch (value)\r
149                         {\r
150                             case "0":\r
151                                 queryParsed.DeInterlace = "Off";\r
152                                 break;\r
153                             // Don't place custom here as it's handled in the filter panel\r
154                             case "2":\r
155                                 queryParsed.DeInterlace = "Fast";\r
156                                 break;\r
157                             case "3":\r
158                                 queryParsed.DeInterlace = "Slow";\r
159                                 break;\r
160                             case "4":\r
161                                 queryParsed.DeInterlace = "Slowest";\r
162                                 break;\r
163                         }\r
164                         break;\r
165                     case "PictureDeinterlaceCustom":\r
166                         if (value != string.Empty)\r
167                             queryParsed.DeInterlace = value;\r
168                         break;\r
169                     case "PictureDenoise":\r
170                         switch (value)\r
171                         {\r
172                             case "0":\r
173                                 queryParsed.DeNoise = "Off";\r
174                                 break;\r
175                             // Don't place custom here as it's handled in the filter panel\r
176                             case "2":\r
177                                 queryParsed.DeNoise = "Weak";\r
178                                 break;\r
179                             case "3":\r
180                                 queryParsed.DeNoise = "Medium";\r
181                                 break;\r
182                             case "4":\r
183                                 queryParsed.DeNoise = "Strong";\r
184                                 break;\r
185                         }\r
186 \r
187                         break;\r
188                     case "PictureDenoiseCustom":\r
189                         if (value != string.Empty)\r
190                             queryParsed.DeNoise = value;\r
191                         break;\r
192                     case "PictureDetelecine":\r
193                         queryParsed.DeTelecine = "Off";\r
194                         if (value == "1") queryParsed.DeTelecine = "Default";\r
195                         break;\r
196                     case "PictureDetelecineCustom":\r
197                         if (value != string.Empty)\r
198                             queryParsed.DeTelecine = value;\r
199                         break;\r
200 \r
201                     // Video Tab\r
202                     case "VideoAvgBitrate":\r
203                         queryParsed.AverageVideoBitrate = value;\r
204                         break;\r
205                     case "VideoEncoder":\r
206                         queryParsed.VideoEncoder = value;\r
207                         break;\r
208                     case "VideoFramerate":\r
209                         queryParsed.VideoFramerate = value;\r
210                         break;\r
211                     case "VideoGrayScale":\r
212                         queryParsed.Grayscale = value == "1";\r
213                         break;\r
214                     case "VideoQualitySlider":\r
215                         queryParsed.VideoQuality = float.Parse(value);\r
216                         break;\r
217                     case "VideoQualityType": // The Type of Quality Mode used\r
218                         qualityMode = value;\r
219                         break;\r
220                     case "VideoTargetSize":\r
221                         queryParsed.VideoTargetSize = value;\r
222                         break;\r
223                     case "VideoTurboTwoPass":\r
224                         queryParsed.TurboFirstPass = value == "1";\r
225                         break;\r
226                     case "VideoTwoPass":\r
227                         queryParsed.TwoPass = value == "1";\r
228                         break;\r
229 \r
230                     // Chapter Markers Tab\r
231                     case "ChapterMarkers":\r
232                         queryParsed.ChapterMarkers = value == "1";\r
233                         break;\r
234 \r
235                     // Advanced x264 tab\r
236                     case "x264Option":\r
237                         queryParsed.H264Query = value;\r
238                         break;\r
239 \r
240                     // Preset Information\r
241                     case "PresetBuildNumber":\r
242                         queryParsed.PresetBuildNumber = int.Parse(value);\r
243                         break;\r
244                     case "PresetDescription":\r
245                         queryParsed.PresetDescription = value;\r
246                         break;\r
247                     case "PresetName":\r
248                         queryParsed.PresetName = value;\r
249                         break;\r
250                     case "Type":\r
251                         queryParsed.Type = value;\r
252                         break;\r
253                     case "UsesMaxPictureSettings":\r
254                         queryParsed.UsesMaxPictureSettings = value == "1";\r
255                         break;\r
256                     case "UsesPictureFilters":\r
257                         queryParsed.UsesPictureFilters = value == "1";\r
258                         break;\r
259                     case "UsesPictureSettings":\r
260                         queryParsed.UsesPictureSettings = value == "1";\r
261                         break;\r
262                 }\r
263             }\r
264 \r
265             // Kill any Quality values we don't need.\r
266             switch (qualityMode)\r
267             {\r
268                 case "0": // FileSize\r
269                     queryParsed.VideoQuality = -1;\r
270                     queryParsed.AverageVideoBitrate = null;\r
271                     break;\r
272                 case "1": // Avg Bitrate\r
273                     queryParsed.VideoQuality = -1;\r
274                     queryParsed.VideoTargetSize = null;\r
275                     break;\r
276                 case "2": // CQ\r
277                     queryParsed.AverageVideoBitrate = null;\r
278                     queryParsed.VideoTargetSize = null;\r
279                     break;\r
280             }\r
281             #endregion\r
282 \r
283             return queryParsed;\r
284         }\r
285 \r
286         private static XmlNode loadFile(string filename)\r
287         {\r
288             try\r
289             {\r
290                 XmlNode root;\r
291 \r
292                 if (!File.Exists(filename))\r
293                     return null;\r
294 \r
295                 StreamReader sr = File.OpenText(filename);\r
296                 string fromfile = string.Empty;\r
297                 int fileChar;\r
298                 while ((fileChar = sr.Read()) != -1)\r
299                     fromfile += Convert.ToChar(fileChar);\r
300 \r
301                 XmlDocument doc = new XmlDocument();\r
302                 doc.LoadXml(fromfile);\r
303 \r
304                 root = doc;\r
305                 if (!root.HasChildNodes)\r
306                 {\r
307                     MessageBox.Show(\r
308                         "The Preset file you selected appears to be invlaid or from an older version of HandBrake",\r
309                         "Error",\r
310                         MessageBoxButtons.OK, MessageBoxIcon.Error);\r
311                     return null;\r
312                 }\r
313 \r
314                 return root;\r
315             }\r
316             catch (Exception)\r
317             {\r
318                 MessageBox.Show(\r
319                     "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
320                     "Error",\r
321                     MessageBoxButtons.OK, MessageBoxIcon.Error);\r
322                 return null;\r
323             } \r
324         }\r
325         #endregion\r
326 \r
327         #region Export\r
328 \r
329         public static void Export(string path, QueryParser parsed)\r
330         {\r
331             XmlTextWriter xmlWriter;\r
332 \r
333             xmlWriter = new XmlTextWriter(path, Encoding.UTF8);\r
334 \r
335             // Header\r
336             xmlWriter.WriteStartDocument();\r
337             xmlWriter.WriteDocType("plist", "-//Apple//DTD PLIST 1.0//EN",\r
338                                 @"http://www.apple.com/DTDs/PropertyList-1.0.dtd", null);\r
339 \r
340             xmlWriter.WriteStartElement("plist");\r
341             xmlWriter.WriteStartElement("array");\r
342 \r
343             // Add New Preset Here. Can write multiple presets here if required in future.\r
344             WritePreset(xmlWriter, parsed);\r
345 \r
346             // Footer\r
347             xmlWriter.WriteEndElement();\r
348             xmlWriter.WriteEndElement();\r
349 \r
350             xmlWriter.WriteEndDocument();\r
351 \r
352             // Closeout\r
353             xmlWriter.Close();\r
354         }\r
355 \r
356         private static void WritePreset(XmlTextWriter xmlWriter, QueryParser parsed)\r
357         {\r
358             xmlWriter.WriteStartElement("dict");\r
359             AudioListArrayDict(xmlWriter, parsed);\r
360             AddEncodeSettings(xmlWriter, parsed);\r
361 \r
362             xmlWriter.WriteEndElement();\r
363         }\r
364 \r
365         private static void AddEncodeSettings(XmlTextWriter xmlWriter, QueryParser parsed)\r
366         {\r
367             AddEncodeElement(xmlWriter, "ChapterMarkers", "integer", parsed.ChapterMarkers ? "1" : "0");\r
368             AddEncodeElement(xmlWriter, "Default", "integer", string.Empty); // TODO\r
369             AddEncodeElement(xmlWriter, "FileFormat", "string", parsed.Format);\r
370             AddBooleanElement(xmlWriter, "Folder", true); // TODO \r
371             AddEncodeElement(xmlWriter, "Mp4HttpOptimize", "integer", parsed.OptimizeMP4 ? "1" : "0");\r
372             AddEncodeElement(xmlWriter, "Mp4LargeFile", "integer", parsed.LargeMP4 ? "1" : "0");\r
373             AddEncodeElement(xmlWriter, "Mp4iPodCompatible", "integer", parsed.IpodAtom ? "1" : "0");\r
374             AddEncodeElement(xmlWriter, "PictureAutoCrop", "integer", string.Empty); // TODO\r
375             AddEncodeElement(xmlWriter, "PictureBottomCrop", "integer", parsed.CropBottom);\r
376 \r
377             // Filters - TODO Requires Some Logic to convert modes\r
378             AddEncodeElement(xmlWriter, "PictureDeblock", "integer", string.Empty);\r
379             AddEncodeElement(xmlWriter, "PictureDecomb", "integer", string.Empty);\r
380             AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", string.Empty);\r
381             AddEncodeElement(xmlWriter, "PictureDecombDeinterlace", "integer", string.Empty); // TODO Requires Logic\r
382             AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", string.Empty);\r
383             AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty);\r
384             AddEncodeElement(xmlWriter, "PictureDenoise", "integer", string.Empty);\r
385             AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", string.Empty);\r
386             AddEncodeElement(xmlWriter, "PictureDetelecine", "integer", string.Empty);\r
387             AddEncodeElement(xmlWriter, "PictureDetelecineCustom", "string", string.Empty);\r
388 \r
389             AddEncodeElement(xmlWriter, "PictureHeight", "integer", parsed.Height.ToString());\r
390             AddEncodeElement(xmlWriter, "PictureKeepRatio", "integer", string.Empty);\r
391             AddEncodeElement(xmlWriter, "PictureLeftCrop", "integer", parsed.CropLeft);\r
392             AddEncodeElement(xmlWriter, "PicturePAR", "integer", string.Empty);\r
393             AddEncodeElement(xmlWriter, "PictureRightCrop", "integer", parsed.CropRight);\r
394             AddEncodeElement(xmlWriter, "PictureTopCrop", "integer", parsed.CropTop);\r
395             AddEncodeElement(xmlWriter, "PictureWidth", "integer", parsed.Width.ToString());\r
396 \r
397             AddEncodeElement(xmlWriter, "PresetBuildNumber", "string", string.Empty);\r
398             AddEncodeElement(xmlWriter, "PresetDescription", "string", string.Empty);\r
399             AddEncodeElement(xmlWriter, "PresetName", "string", string.Empty);\r
400             AddEncodeElement(xmlWriter, "Type", "integer", string.Empty);\r
401 \r
402             AddEncodeElement(xmlWriter, "UsesMaxPictureSettings", "integer", string.Empty);\r
403             AddEncodeElement(xmlWriter, "UsesPictureFilters", "integer", string.Empty);\r
404             AddEncodeElement(xmlWriter, "UsesPictureSettings", "integer", string.Empty);\r
405 \r
406             AddEncodeElement(xmlWriter, "VideoAvgBitrate", "string", string.Empty);\r
407             AddEncodeElement(xmlWriter, "VideoEncoder", "string", string.Empty);\r
408             AddEncodeElement(xmlWriter, "VideoFramerate", "string", string.Empty);\r
409 \r
410             AddEncodeElement(xmlWriter, "VideoGrayScale", "integer", parsed.Grayscale ? "1" : "0");\r
411             AddEncodeElement(xmlWriter, "VideoQualitySlider", "real", parsed.VideoQuality.ToString());\r
412             AddEncodeElement(xmlWriter, "VideoQualityType", "integer", string.Empty); // TODO Requires Logic\r
413             AddEncodeElement(xmlWriter, "VideoTargetSize", "string", parsed.VideoTargetSize);\r
414             AddEncodeElement(xmlWriter, "VideoTurboTwoPass", "integer", parsed.TurboFirstPass ? "1" : "0");\r
415             AddEncodeElement(xmlWriter, "VideoTwoPass", "integer", parsed.TwoPass ? "1" : "0");\r
416 \r
417             AddEncodeElement(xmlWriter, "x264Option", "string", parsed.H264Query);\r
418         }\r
419 \r
420         private static void AddBooleanElement(XmlTextWriter xmlWriter, string keyName, bool value)\r
421         {\r
422             xmlWriter.WriteStartElement("key");\r
423             xmlWriter.WriteString(keyName);\r
424             xmlWriter.WriteEndElement();\r
425             if (value)\r
426             {\r
427                 xmlWriter.WriteStartElement("true");\r
428                 xmlWriter.WriteEndElement();\r
429             }\r
430             else\r
431             {\r
432                 xmlWriter.WriteStartElement("false");\r
433                 xmlWriter.WriteEndElement();\r
434             }\r
435         }\r
436 \r
437         private static void AddEncodeElement(XmlTextWriter xmlWriter, string keyName, string type, string value)\r
438         {\r
439             xmlWriter.WriteElementString("key", keyName);\r
440             xmlWriter.WriteElementString(type, value);\r
441         }\r
442 \r
443         private static void AudioListArrayDict(XmlTextWriter xmlWriter, QueryParser parsed)\r
444         {\r
445             xmlWriter.WriteStartElement("key");\r
446             xmlWriter.WriteString("AudioList");\r
447             xmlWriter.WriteEndElement();\r
448 \r
449             xmlWriter.WriteStartElement("array");\r
450             foreach (AudioTrack track in parsed.AudioInformation)\r
451             {\r
452                 AddAudioItem(xmlWriter, track);\r
453             }\r
454             xmlWriter.WriteEndElement();\r
455         }\r
456 \r
457         private static void AddAudioItem(XmlTextWriter xmlWriter, AudioTrack audioTrack)\r
458         {\r
459             string bitrate = audioTrack.Bitrate;\r
460             string encoder = audioTrack.Encoder;\r
461             string mixdown = audioTrack.MixDown;\r
462             string sample = audioTrack.SampleRate;\r
463             int track;\r
464             int.TryParse(audioTrack.Track, out track);\r
465             string drc = audioTrack.DRC;\r
466             string desc = "Automatic";\r
467 \r
468             xmlWriter.WriteStartElement("dict");\r
469 \r
470             xmlWriter.WriteElementString("key", "AudioBitrate");\r
471             xmlWriter.WriteElementString("string", bitrate);\r
472 \r
473             xmlWriter.WriteElementString("key", "AudioEncoder");\r
474             xmlWriter.WriteElementString("string", encoder);\r
475 \r
476             xmlWriter.WriteElementString("key", "AudioMixdown");\r
477             xmlWriter.WriteElementString("string", mixdown);\r
478 \r
479             xmlWriter.WriteElementString("key", "AudioSamplerate");\r
480             xmlWriter.WriteElementString("string", sample);\r
481 \r
482             xmlWriter.WriteElementString("key", "AudioTrack");\r
483             xmlWriter.WriteElementString("integer", track.ToString());\r
484 \r
485             xmlWriter.WriteElementString("key", "AudioTrackDRCSlider");\r
486             xmlWriter.WriteElementString("real", drc.ToString());\r
487 \r
488             xmlWriter.WriteElementString("key", "AudioTrackDescription");\r
489             xmlWriter.WriteElementString("string", desc);\r
490 \r
491             xmlWriter.WriteEndElement();\r
492         }\r
493         #endregion\r
494     }\r
495 }