/* PlistPresetHandler.cs $
This file is part of the HandBrake source code.
Homepage: .
It may be used under the terms of the GNU General Public License. */
namespace Handbrake.Presets
{
using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using Functions;
using Model;
public class PlistPresetHandler
{
/* WARNING This file is not complete!!!!!!
*
* TODO
* 1. Hookup all the widgets in the GUI so it exports real values.
* 2. Check for any missing key/value pairs
* 3. Test with MacGui / Cleanup code / Retest
*/
private XmlTextWriter Writer;
///
/// Import a Plist preset generated by the Mac or Linux GUI
///
///
///
public static QueryParser Import(string filename)
{
XmlNode root = null;
try
{
if (!File.Exists(filename))
return null;
StreamReader sr = File.OpenText(filename);
string fromfile = string.Empty;
int fileChar;
while ((fileChar = sr.Read()) != -1)
fromfile += Convert.ToChar(fileChar);
XmlDocument doc = new XmlDocument();
doc.LoadXml(fromfile);
root = doc;
if (!root.HasChildNodes)
{
MessageBox.Show(
"The Preset file you selected appears to be invlaid or from an older version of HandBrake",
"Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
}
catch (Exception)
{
MessageBox.Show(
"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.",
"Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// We'll query a query parser object and use it's public var structures to store all the data.
// This will allow the preset loader logic to be used instead of writing custom logic just for this file.
QueryParser queryParsed = new QueryParser();
string QualityMode = string.Empty;
/***** Get the Audio Tracks *****/
XmlNode audioListDict = root.ChildNodes[2].ChildNodes[0].FirstChild.ChildNodes[1];
ArrayList AudioInfo = new ArrayList();
for (int i = 0; i < audioListDict.ChildNodes.Count; i++)
{
XmlNode audioChannel = audioListDict.ChildNodes[i];
AudioTrack track = new AudioTrack();
for (int subi = 0; subi < audioChannel.ChildNodes.Count; subi += 2)
{
// Audio Channel Information is here.
string key = audioChannel.ChildNodes[subi].InnerText;
string value = audioChannel.ChildNodes[subi + 1].InnerText;
switch (key)
{
case "AudioBitrate":
track.Bitrate = value;
break;
case "AudioEncoder":
track.Encoder = value.Replace("AAC (CoreAudio)", "AAC (faac)");
break;
case "AudioMixdown":
track.MixDown = value;
break;
case "AudioSamplerate":
track.SampleRate = value;
break;
case "AudioTrack":
track.Track = value;
break;
case "AudioTrackDRCSlider":
track.DRC = value;
break;
}
}
AudioInfo.Add(track);
}
queryParsed.AudioInformation = AudioInfo;
/***** Get the rest of the settings. *****/
XmlNode presetSettings = root.ChildNodes[2].ChildNodes[0].FirstChild;
for (int i = 2; i < presetSettings.ChildNodes.Count; i += 2)
// Start from 2 to avoid the audio settings which we don't need.
{
string key = presetSettings.ChildNodes[i].InnerText;
string value = presetSettings.ChildNodes[i + 1].InnerText;
switch (key)
{
// Output Settings
case "FileFormat":
queryParsed.Format = value;
break;
case "Mp4HttpOptimize":
queryParsed.OptimizeMP4 = value == "1";
break;
case "Mp4LargeFile":
queryParsed.LargeMP4 = value == "1";
break;
case "Mp4iPodCompatible":
queryParsed.IpodAtom = value == "1";
break;
// Picture Settings
case "PictureAutoCrop":
break;
case "PictureTopCrop":
queryParsed.CropTop = value;
break;
case "PictureBottomCrop":
queryParsed.CropBottom = value;
break;
case "PictureLeftCrop":
queryParsed.CropLeft = value;
break;
case "PictureRightCrop":
queryParsed.CropRight = value;
break;
case "PictureHeight":
queryParsed.Height = int.Parse(value);
break;
case "PictureWidth":
queryParsed.Width = int.Parse(value);
break;
case "PictureKeepRatio":
queryParsed.KeepDisplayAsect = value == "1";
break;
case "PicturePAR":
queryParsed.AnamorphicMode = int.Parse(value);
break;
// Filters
case "PictureDeblock":
queryParsed.DeBlock = int.Parse(value);
break;
case "PictureDecomb":
queryParsed.Decomb = "Off";
if (value == "2") queryParsed.Decomb = "Default";
break;
case "PictureDecombCustom":
if (value != string.Empty)
queryParsed.Decomb = value;
break;
case "PictureDecombDeinterlace":
// Not Used
break;
case "PictureDeinterlace":
switch (value)
{
case "0":
queryParsed.DeInterlace = "Off";
break;
case "2":
queryParsed.DeInterlace = "Fast";
break;
case "3":
queryParsed.DeInterlace = "Slow";
break;
case "4":
queryParsed.DeInterlace = "Slowest";
break;
}
break;
case "PictureDeinterlaceCustom":
if (value != string.Empty)
queryParsed.DeInterlace = value;
break;
case "PictureDenoise":
switch (value)
{
case "0":
queryParsed.DeNoise = "Off";
break;
case "2":
queryParsed.DeNoise = "Weak";
break;
case "3":
queryParsed.DeNoise = "Medium";
break;
case "4":
queryParsed.DeNoise = "Strong";
break;
}
break;
case "PictureDenoiseCustom":
if (value != string.Empty)
queryParsed.DeNoise = value;
break;
case "PictureDetelecine":
queryParsed.DeTelecine = "Off";
if (value == "1") queryParsed.DeTelecine = "Default";
break;
case "PictureDetelecineCustom":
if (value != string.Empty)
queryParsed.DeTelecine = value;
break;
// Video Tab
case "VideoAvgBitrate":
queryParsed.AverageVideoBitrate = value;
break;
case "VideoEncoder":
queryParsed.VideoEncoder = value;
break;
case "VideoFramerate":
queryParsed.VideoFramerate = value;
break;
case "VideoGrayScale":
queryParsed.Grayscale = value == "1";
break;
case "VideoQualitySlider":
queryParsed.VideoQuality = float.Parse(value);
break;
case "VideoQualityType": // The Type of Quality Mode used
QualityMode = value;
break;
case "VideoTargetSize":
queryParsed.VideoTargetSize = value;
break;
case "VideoTurboTwoPass":
queryParsed.TurboFirstPass = value == "1";
break;
case "VideoTwoPass":
queryParsed.TwoPass = value == "1";
break;
// Chapter Markers Tab
case "ChapterMarkers":
queryParsed.ChapterMarkers = value == "1";
break;
// Advanced x264 tab
case "x264Option":
queryParsed.H264Query = value;
break;
// Preset Information
case "PresetBuildNumber":
queryParsed.PresetBuildNumber = int.Parse(value);
break;
case "PresetDescription":
queryParsed.PresetDescription = value;
break;
case "PresetName":
queryParsed.PresetName = value;
break;
case "Type":
queryParsed.Type = value;
break;
case "UsesMaxPictureSettings":
queryParsed.UsesMaxPictureSettings = value == "1";
break;
case "UsesPictureFilters":
queryParsed.UsesPictureFilters = value == "1";
break;
case "UsesPictureSettings":
queryParsed.UsesPictureSettings = value == "1";
break;
}
}
// Kill any Quality values we don't need.
switch (QualityMode)
{
case "0": // FileSize
queryParsed.VideoQuality = -1;
queryParsed.AverageVideoBitrate = null;
break;
case "1": // Avg Bitrate
queryParsed.VideoQuality = -1;
queryParsed.VideoTargetSize = null;
break;
case "2": // CQ
queryParsed.AverageVideoBitrate = null;
queryParsed.VideoTargetSize = null;
break;
}
return queryParsed;
}
///
/// Export a preset to a Plist file readable by the Mac and Linux GUI's
///
///
public void Export(string path)
{
Writer = new XmlTextWriter("C:\\test.xml", Encoding.UTF8);
// Header
Writer.WriteStartDocument();
Writer.WriteDocType("plist", "-//Apple//DTD PLIST 1.0//EN",
@"http://www.apple.com/DTDs/PropertyList-1.0.dtd", null);
Writer.WriteStartElement("plist");
Writer.WriteStartElement("array");
// Add New Preset Here. Can write multiple presets here if required in future.
WritePreset();
// Footer
Writer.WriteEndElement();
Writer.WriteEndElement();
Writer.WriteEndDocument();
// Closeout
Writer.Close();
}
///
/// Write a Plist file
///
private void WritePreset()
{
Writer.WriteStartElement("dict");
AudioListArrayDict();
AddEncodeSettings();
Writer.WriteEndElement();
}
///
/// Add all the encode settings to the preset
///
private void AddEncodeSettings()
{
AddEncodeElement("ChapterMarkers", "integer", string.Empty);
AddEncodeElement("Default", "integer", string.Empty);
AddEncodeElement("FileFormat", "String", string.Empty);
AddBooleanElement("Folder", true);
AddEncodeElement("Mp4HttpOptimize", "integer", string.Empty);
AddEncodeElement("Mp4LargeFile", "integer", string.Empty);
AddEncodeElement("Mp4iPodCompatible", "integer", string.Empty);
AddEncodeElement("PictureAutoCrop", "integer", string.Empty);
AddEncodeElement("PictureBottomCrop", "integer", string.Empty);
AddEncodeElement("PictureDeblock", "integer", string.Empty);
AddEncodeElement("PictureDecomb", "integer", string.Empty);
AddEncodeElement("PictureDecombCustom", "string", string.Empty);
AddEncodeElement("PictureDecombDeinterlace", "integer", string.Empty);
AddEncodeElement("PictureDeinterlace", "integer", string.Empty);
AddEncodeElement("PictureDeinterlaceCustom", "string", string.Empty);
AddEncodeElement("PictureDenoise", "integer", string.Empty);
AddEncodeElement("PictureDenoiseCustom", "string", string.Empty);
AddEncodeElement("PictureDetelecine", "integer", string.Empty);
AddEncodeElement("PictureDetelecineCustom", "string", string.Empty);
AddEncodeElement("PictureHeight", "integer", string.Empty);
AddEncodeElement("PictureKeepRatio", "integer", string.Empty);
AddEncodeElement("PictureLeftCrop", "integer", string.Empty);
AddEncodeElement("PicturePAR", "integer", string.Empty);
AddEncodeElement("PictureRightCrop", "integer", string.Empty);
AddEncodeElement("PictureTopCrop", "integer", string.Empty);
AddEncodeElement("PictureWidth", "integer", string.Empty);
AddEncodeElement("PresetBuildNumber", "string", string.Empty);
AddEncodeElement("PresetDescription", "string", string.Empty);
AddEncodeElement("PresetName", "string", string.Empty);
AddEncodeElement("Type", "integer", string.Empty);
AddEncodeElement("UsesMaxPictureSettings", "integer", string.Empty);
AddEncodeElement("UsesPictureFilters", "integer", string.Empty);
AddEncodeElement("UsesPictureSettings", "integer", string.Empty);
AddEncodeElement("VideoAvgBitrate", "string", string.Empty);
AddEncodeElement("VideoEncoder", "string", string.Empty);
AddEncodeElement("VideoFramerate", "string", string.Empty);
AddEncodeElement("VideoGrayScale", "integer", string.Empty);
AddEncodeElement("VideoQualitySlider", "real", string.Empty);
AddEncodeElement("VideoQualityType", "integer", string.Empty);
AddEncodeElement("VideoTargetSize", "string", string.Empty);
AddEncodeElement("VideoTurboTwoPass", "integer", string.Empty);
AddEncodeElement("VideoTwoPass", "integer", string.Empty);
AddEncodeElement("x264Option", "string", string.Empty);
}
///
/// Add Preset setting + value
///
///
///
private void AddBooleanElement(string keyName, bool value)
{
Writer.WriteStartElement("key");
Writer.WriteString(keyName);
Writer.WriteEndElement();
if (value)
{
Writer.WriteStartElement("true");
Writer.WriteEndElement();
}
else
{
Writer.WriteStartElement("false");
Writer.WriteEndElement();
}
}
///
/// Add Preset setting + value
///
///
///
///
private void AddEncodeElement(string keyName, string type, string value)
{
Writer.WriteElementString("key", keyName);
Writer.WriteElementString(type, value);
}
///
/// Add List of audio tracks
///
private void AudioListArrayDict()
{
Writer.WriteStartElement("key");
Writer.WriteString("AudioList");
Writer.WriteEndElement();
Writer.WriteStartElement("array");
AddAudioItem();
AddAudioItem();
Writer.WriteEndElement();
}
///
/// Add List of audio tracks
///
private void AddAudioItem()
{
int bitrate = 448;
string encoder = "AC3 Passthru";
string mixdown = "AC3 Passthru";
string sample = "Auto";
int track = 1;
double drc = 0.0;
string desc = "English (AC3) (5.1 ch)";
Writer.WriteStartElement("dict");
Writer.WriteElementString("key", "AudioBitrate");
Writer.WriteElementString("string", bitrate.ToString());
Writer.WriteElementString("key", "AudioEncoder");
Writer.WriteElementString("string", encoder);
Writer.WriteElementString("key", "AudioMixdown");
Writer.WriteElementString("string", mixdown);
Writer.WriteElementString("key", "AudioSamplerate");
Writer.WriteElementString("string", sample);
Writer.WriteElementString("key", "AudioTrack");
Writer.WriteElementString("integer", track.ToString());
Writer.WriteElementString("key", "AudioTrackDRCSlider");
Writer.WriteElementString("real", drc.ToString());
Writer.WriteElementString("key", "AudioTrackDescription");
Writer.WriteElementString("string", desc);
Writer.WriteEndElement();
}
}
}