OSDN Git Service

Preset updates, including AC3 and AAC for ATV, less insane settings for some others...
[handbrake-jp/handbrake-jp-git.git] / scripts / manicure.rb
1 #! /usr/bin/ruby
2 # manincure.rb version 0.66
3
4 # This file is part of the HandBrake source code.
5 # Homepage: <http://handbrake.m0k.org/>.
6 # It may be used under the terms of the GNU General Public License.
7
8 # This script parses HandBrake's Mac presets into hashes, which can
9 # be displayed in various formats for use by the CLI and its wrappers.
10
11 # For handling command line arguments to the script
12 require 'optparse'
13 require 'ostruct'
14
15 # CLI options: (code based on http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/index.html )
16 def readOptions
17   
18   # --[no-]cli-raw, -r gives raw CLI for wiki
19   # --cli-parse, -p gives CLI strings for wrappers
20   # --api, -a gives preset code for test.c
21   # --api-list, -A gives CLI strings for --preset-list display
22   # --[no-]header, -h turns off banner display
23   options = OpenStruct.new
24   options.cliraw = false
25   options.cliparse = false
26   options.api = false
27   options.apilist = false
28   options.header = false
29   
30   opts = OptionParser.new do |opts|
31     opts.banner = "Usage: manicure.rb [options]"
32     
33     opts.separator ""
34     opts.separator "Options:"
35     
36     opts.on("-r", "--cli-raw", "Gives example strings for the HB wiki") do |raw|
37       options.cliraw = raw
38       option_set = true
39     end
40     
41     opts.on("-p", "--cli-parse", "Gives presets as wrapper-parseable CLI", " option strings") do |par|
42       options.cliparse = par
43     end
44     
45     opts.on("-a", "--api", "Gives preset code for test.c") do |api|
46       options.api = api
47     end
48     
49     opts.on("-A", "--api-list", "Gives code for test.c's --preset-list", " options") do |alist|
50       options.apilist = alist
51     end
52     
53     opts.on("-H", "--Header", "Display a banner before each preset") do |head|
54       options.header = head
55     end
56     
57     opts.on_tail("-h", "--help", "Show this message") do
58         puts opts
59         exit
60     end
61   end.parse!
62   
63   return options
64   
65 end
66
67 # These arrays contain all the other presets and hashes that are going to be used.
68 # Yeah, they're global variables. In an object-oriented scripting language.
69 # Real smooth, huh?
70
71 # This class parses the user's presets .plist into an array of hashes
72 class Presets
73   
74   attr_reader :hashMasterList
75   
76   # Running initialization runs everything.
77   # Calling it will also call the parser
78   # and display output.
79   def initialize
80     
81     # Grab input from the user's presets .plist
82     rawPresets = readPresetPlist
83     
84     # Store all the presets in here
85     presetStew = []
86
87     # Each item in the array is one line from the .plist
88     presetStew = rawPresets.split("\n")
89     
90     # Now get rid of white space
91     presetStew = cleanStew(presetStew)
92     
93     # This stores the offsets between presets.
94     presetBreaks = findPresetBreaks(presetStew)
95
96     # Now it's time to use that info to store each
97     # preset individually, in the master list.
98     @presetMasterList = []
99     i = 0
100     while i <= presetBreaks.size    
101       if i == 0 #first preset
102         # Grab the stew, up to the 1st offset.
103         @presetMasterList[i] = presetStew.slice(0..presetBreaks[i].to_i)
104       elsif i < presetBreaks.size #middle presets
105         # Grab the stew from the last offset to the current..
106         @presetMasterList[i] = presetStew.slice(presetBreaks[i-1].to_i..presetBreaks[i].to_i)
107       else #final preset
108         # Grab the stew, starting at the last offset, all the way to the end.
109         @presetMasterList[i] = presetStew.slice(presetBreaks[i-1].to_i..presetStew.length)
110       end
111       i += 1
112     end
113     
114     # Parse the presets into hashes
115     @hashMasterList = []
116     
117     buildPresetHash
118     
119   end
120
121   def readPresetPlist # Grab the .plist and store it in presets
122     
123     # Grab the user's home path
124     homeLocation = `echo $HOME`.chomp
125     
126     # Use that to build a path to the presets .plist
127     inputFile = homeLocation+'/Library/Application\ Support/HandBrake/UserPresets.plist'
128     
129     # Builds a command that inputs the .plist, but not before stripping all the XML gobbledygook.
130     parseCommand = 'cat '+inputFile+' | sed -e \'s/<[a-z]*>//\' -e \'s/<\/[a-z]*>//\'  -e \'/<[?!]/d\' '
131     
132     puts "\n\n"
133     
134     # Run the command, return the raw presets
135     rawPresets = `#{parseCommand}`
136   end
137
138   def cleanStew(presetStew) #remove tabbed white space
139     presetStew.each do |oneline|
140       oneline.strip!
141     end
142   end
143
144   def findPresetBreaks(presetStew) #figure out where each preset starts and ends
145     i = 0
146     j = 0
147     presetBreaks =[]
148     presetStew.each do |presetLine|
149       if presetLine =~ /AudioBitRate/ # This is the first line of a new preset.
150         presetBreaks[j] = i-1         # So mark down how long the last one was.
151         j += 1
152       end
153     i += 1
154     end
155     return presetBreaks
156   end
157
158   def buildPresetHash #fill up @hashMasterList with hashes of all key/value pairs
159     j = 0
160     
161     # Iterate through all presets, treating each in turn as singleServing
162     @presetMasterList.each do |singleServing|
163       
164       # Initialize the hash for preset j (aka singleServing)
165       @hashMasterList[j] = Hash.new
166       
167       # Each key and value are on sequential lines.
168       # Iterating through by twos, use that to build a hash.
169       # Each key, on line i, paired with its value, on line i+1  
170       i = 1
171       while i < singleServing.length
172         @hashMasterList[j].store( singleServing[i],  singleServing[i+1] )
173         i += 2
174       end
175             
176       j += 1  
177     end   
178   end
179
180 end
181
182 # This class displays the presets to stdout in various formats.
183 class Display
184   
185   
186   def initialize(hashMasterList, options)
187   
188     @hashMasterList = hashMasterList
189     @options = options
190
191     # A width of 40 gives nice, compact output.
192     @columnWidth=40
193     
194     # Print to screen.
195     displayCommandStrings
196     
197   end
198   
199   def displayCommandStrings # prints everything to screen
200     
201     # Iterate through the hashes.    
202     @hashMasterList.each do |hash|
203     
204       # Check to make there are valid contents
205       if hash.key?("PresetName")
206         
207         if @options.header == true
208           # First throw up a header to make each preset distinct
209           displayHeader(hash)
210         end
211         
212         if @options.cliraw == true
213           # Show the preset's full CLI string equivalent
214           generateCLIString(hash)
215         end
216         
217         if @options.cliparse == true
218           generateCLIParse(hash)
219         end
220         
221         if @options.api == true
222           # Show the preset as code for test/test.c, HandBrakeCLI
223           generateAPIcalls(hash)
224         end
225         
226         if @options.apilist == true
227           # Show the preset as print statements, for CLI wrappers to parse.
228           generateAPIList(hash) 
229         end
230       end
231     end    
232   end
233   
234   def displayHeader(hash) # A distinct banner to separate each preset
235     
236     # Print a line of asterisks
237     puts "*" * @columnWidth
238     
239     # Print the name, centered
240     puts '* '+hash["PresetName"].to_s.center(@columnWidth-4)+' *'
241     
242     # Print a line of dashes
243     puts '~' * @columnWidth
244     
245     # Print the description, centered and word-wrapped
246     puts hash["PresetDescription"].to_s.center(@columnWidth).gsub(/\n/," ").scan(/\S.{0,#{@columnWidth-2}}\S(?=\s|$)|\S+/)
247     
248     # Print another line of dashes
249     puts '~' * @columnWidth
250     
251     # Print the formats the preset uses
252     puts "#{hash["FileCodecs"]}".center(@columnWidth)
253     
254     # Note if the preset isn't built-in
255     if hash["Type"].to_i == 1
256       puts "Custom Preset".center(@columnWidth)
257     end
258
259     # Note if the preset is marked as default.
260     if hash["Default"].to_i == 1
261       puts "This is your default preset.".center(@columnWidth)
262     end
263     
264     # End with a line of tildes.  
265     puts "~" * @columnWidth
266     
267   end
268   
269   def generateCLIString(hash) # Makes a full CLI equivalent of a preset
270     commandString = ""
271     commandString << './HandBrakeCLI -i DVD -o ~/Movies/movie.'
272     
273     #Filename suffix
274     case hash["FileFormat"]
275     when /MP4/
276       commandString << "mp4 "
277     when /AVI/
278       commandString << "avi "
279     when /OGM/
280       commandString << "ogm "
281     when /MKV/
282       commandString << "mkv "
283     end
284     
285     #Video encoder
286     if hash["VideoEncoder"] != "FFmpeg"
287       commandString << " -e "
288       commandString << hash["VideoEncoder"].to_s.downcase
289     end
290
291     #VideoRateControl
292     case hash["VideoQualityType"].to_i
293     when 0
294       commandString << " -S " << hash["VideoTargetSize"]
295     when 1
296       commandString << " -b " << hash["VideoAvgBitrate"]
297     when 2
298       commandString << " -q " << hash["VideoQualitySlider"]
299     end
300
301     #FPS
302     if hash["VideoFramerate"] != "Same as source"
303       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
304         commandString << " -r " << "23.976"
305       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
306         commandString << " -r " << "29.97"
307       else
308         commandString << " -r " << hash["VideoFramerate"]
309       end
310     end
311
312     #Audio encoder (only specifiy bitrate and samplerate when not doing AC-3 pass-thru)
313     commandString << " -E "
314     case hash["FileCodecs"]
315     when /AAC + AC3 Audio/
316       commandString << "aac+ac3"
317     when /AC-3 /
318       commandString << "ac3"
319     when /AAC Audio/
320       commandString << "faac" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
321     when /Vorbis/
322       commandString << "vorbis" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
323     when /MP3/
324       commandString << "lame" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
325     end
326     
327     #Container
328     commandString << " -f "
329     case hash["FileFormat"]
330     when /MP4/
331       commandString << "mp4"
332     when /AVI/
333       commandString << "avi"
334     when /OGM/
335       commandString << "ogm"
336     when /MKV/
337       commandString << "mkv"
338     end
339     
340     #iPod MP4 atom
341     if hash["Mp4iPodCompatible"].to_i == 1
342       commandString << " -I"
343     end
344     
345     #Cropping
346     if !hash["PictureAutoCrop"].to_i
347       commandString << " --crop "
348       commandString << hash["PictureTopCrop"]
349       commandString << ":"
350       commandString << hash["PictureBottomCrop"]
351       commandString << ":"
352       commandString << hash["PictureLeftCrop"]
353       commandString << ":"
354       commandString << hash["PictureRightCrop"]
355     end
356     
357     #Dimensions
358     if hash["PictureWidth"].to_i != 0
359       commandString << " -w "
360       commandString << hash["PictureWidth"]
361     end
362     if hash["PictureHeight"].to_i != 0
363       commandString << " -l "
364       commandString << hash["PictureHeight"]
365     end
366     
367     #Subtitles
368     if hash["Subtitles"] != "None"
369       commandString << " -s "
370       commandString << hash["Subtitles"]
371     end
372
373     #Video Filters
374     if hash["UsesPictureFilters"].to_i == 1
375       
376       case hash["PictureDeinterlace"].to_i
377       when 1
378         commandString << " --deinterlace=\"fast\""
379       when 2
380         commandString << " --deinterlace=\slow\""
381       when 3
382         commandString << " --deinterlace=\"slower\""
383       when 4
384         commandString << " --deinterlace=\"slowest\""
385       end
386       
387       case hash["PictureDenoise"].to_i
388       when 1
389         commandString << " --denoise=\"weak\""
390       when 2
391         commandString << " --denoise=\"medium\""
392       when 3
393         commandString << " --denoise=\"strong\""
394       end
395       
396       if hash["PictureDetelecine"].to_i == 1 then commandString << " --detelecine" end
397       if hash["PictureDeblock"].to_i == 1 then commandString << " --deblock" end
398       if hash["VFR"].to_i == 1 then commandString << " --vfr" end
399     end
400
401     #Booleans
402     if hash["ChapterMarkers"].to_i == 1 then commandString << " -m" end
403     if hash["PicturePAR"].to_i == 1 then commandString << " -p" end
404     if hash["VideoGrayScale"].to_i == 1 then commandString << " -g" end
405     if hash["VideoTwoPass"].to_i == 1 then commandString << " -2" end
406     if hash["VideoTurboTwoPass"].to_i == 1 then commandString << " -T" end
407
408     #x264 Options
409     if hash["x264Option"] != ""
410       commandString << " -x "
411       commandString << hash["x264Option"]
412     end
413     
414     # That's it, print to screen now
415     puts commandString
416     
417     #puts "*" * @columnWidth
418
419     puts  "\n"
420   end
421
422   def generateCLIParse(hash) # Makes a CLI equivalent of all user presets, for wrappers to parse
423     commandString = ""
424     commandString << '+ ' << hash["PresetName"] << ":"
425         
426     #Video encoder
427     if hash["VideoEncoder"] != "FFmpeg"
428       commandString << " -e "
429       commandString << hash["VideoEncoder"].to_s.downcase
430     end
431
432     #VideoRateControl
433     case hash["VideoQualityType"].to_i
434     when 0
435       commandString << " -S " << hash["VideoTargetSize"]
436     when 1
437       commandString << " -b " << hash["VideoAvgBitrate"]
438     when 2
439       commandString << " -q " << hash["VideoQualitySlider"]
440     end
441
442     #FPS
443     if hash["VideoFramerate"] != "Same as source"
444       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
445         commandString << " -r " << "23.976"
446       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
447         commandString << " -r " << "29.97"
448       else
449         commandString << " -r " << hash["VideoFramerate"]
450       end
451     end
452     
453     #Audio encoder (only include bitrate and samplerate when not doing AC3 passthru)
454     commandString << " -E "
455     case hash["FileCodecs"]
456     when /AC3 Audio/
457       commandString << "aac+ac3"
458     when /AC-3/
459       commandString << "ac3"
460     when /AAC Audio/
461       commandString << "faac" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
462     when /Vorbis/
463       commandString << "vorbis" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
464     when /MP3/
465       commandString << "lame" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
466     end
467     
468     #Container
469     commandString << " -f "
470     case hash["FileFormat"]
471     when /MP4/
472       commandString << "mp4"
473     when /AVI/
474       commandString << "avi"
475     when /OGM/
476       commandString << "ogm"
477     when /MKV/
478       commandString << "mkv"
479     end
480     
481     #iPod MP4 atom
482     if hash["Mp4iPodCompatible"].to_i == 1
483       commandString << " -I"
484     end
485     
486     #Cropping
487     if !hash["PictureAutoCrop"].to_i
488       commandString << " --crop "
489       commandString << hash["PictureTopCrop"]
490       commandString << ":"
491       commandString << hash["PictureBottomCrop"]
492       commandString << ":"
493       commandString << hash["PictureLeftCrop"]
494       commandString << ":"
495       commandString << hash["PictureRightCrop"]
496     end
497     
498     #Dimensions
499     if hash["PictureWidth"].to_i != 0
500       commandString << " -w "
501       commandString << hash["PictureWidth"]
502     end
503     if hash["PictureHeight"].to_i != 0
504       commandString << " -l "
505       commandString << hash["PictureHeight"]
506     end
507     
508     #Subtitles
509     if hash["Subtitles"] != "None"
510       commandString << " -s "
511       commandString << hash["Subtitles"]
512     end
513     
514     #Video Filters
515     if hash["UsesPictureFilters"].to_i == 1
516       
517       case hash["PictureDeinterlace"].to_i
518       when 1
519         commandString << " --deinterlace=\"fast\""
520       when 2
521         commandString << " --deinterlace=\slow\""
522       when 3
523         commandString << " --deinterlace=\"slower\""
524       when 4
525         commandString << " --deinterlace=\"slowest\""
526       end
527       
528       case hash["PictureDenoise"].to_i
529       when 1
530         commandString << " --denoise=\"weak\""
531       when 2
532         commandString << " --denoise=\"medium\""
533       when 3
534         commandString << " --denoise=\"strong\""
535       end
536       
537       if hash["PictureDetelecine"].to_i == 1 then commandString << " --detelecine" end
538       if hash["PictureDeblock"].to_i == 1 then commandString << " --deblock" end
539       if hash["VFR"].to_i == 1 then commandString << " --vfr" end
540     end
541
542     #Booleans
543     if hash["ChapterMarkers"].to_i == 1 then commandString << " -m" end
544     if hash["PicturePAR"].to_i == 1 then commandString << " -p" end
545     if hash["VideoGrayScale"].to_i == 1 then commandString << " -g" end
546     if hash["VideoTwoPass"].to_i == 1 then commandString << " -2" end
547     if hash["VideoTurboTwoPass"].to_i == 1 then commandString << " -T" end
548
549     #x264 Options
550     if hash["x264Option"] != ""
551       commandString << " -x "
552       commandString << hash["x264Option"]
553     end
554     
555     # That's it, print to screen now
556     puts commandString
557     
558     #puts "*" * @columnWidth
559
560     puts  "\n"
561   end
562
563   def generateAPIcalls(hash) # Makes a C version of the preset ready for coding into the CLI
564     
565     commandString = "if (!strcmp(preset_name, \"" << hash["PresetName"] << "\"))\n{\n    "
566     
567     #Filename suffix
568     case hash["FileFormat"]
569     when /MP4/
570       commandString << "mux = " << "HB_MUX_MP4;\n    "
571     when /AVI/
572       commandString << "mux = " << "HB_MUX_AVI;\n    "
573     when /OGM/
574       commandString << "mux = " << "HB_MUX_OGM;\n    "
575     when /MKV/
576       commandString << "mux = " << "HB_MUX_MKV;\n    "
577     end
578     
579     #iPod MP4 atom
580     if hash["Mp4iPodCompatible"].to_i == 1
581       commandString << "job->ipod_atom = 1;\n   "
582     end
583     
584     #Video encoder
585     if hash["VideoEncoder"] != "FFmpeg"
586       commandString << "vcodec = "
587       if hash["VideoEncoder"] == "x264"
588         commandString << "HB_VCODEC_X264;\n    "
589       elsif hash["VideoEncoder"].to_s.downcase == "xvid"
590         commandString << "HB_VCODEC_XVID;\n    "        
591       end
592     end
593
594     #VideoRateControl
595     case hash["VideoQualityType"].to_i
596     when 0
597       commandString << "size = " << hash["VideoTargetSize"] << ";\n    "
598     when 1
599       commandString << "job->vbitrate = " << hash["VideoAvgBitrate"] << ";\n    "
600     when 2
601       commandString << "job->vquality = " << hash["VideoQualitySlider"] << ";\n    "
602       commandString << "job->crf = 1;\n    "
603     end
604
605     #FPS
606     if hash["VideoFramerate"] != "Same as source"
607       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
608         commandString << "job->vrate_base = " << "1126125;\n    "
609       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
610         commandString << "job->vrate_base = " << "900900;\n    "
611       # Gotta add the rest of the framerates for completion's sake.
612       end
613     end
614     
615     # Only include samplerate and bitrate when not performing AC3 passthru
616     if (hash["FileCodecs"].include? "AC-3") == false
617       #Audio bitrate
618       commandString << "job->abitrate = " << hash["AudioBitRate"] << ";\n    "
619     
620       #Audio samplerate
621       commandString << "job->arate = "
622       case hash["AudioSampleRate"]
623       when /48/
624         commandString << "48000"
625       when /44.1/
626         commandString << "44100"
627       when /32/
628         commandString << "32000"
629       when /24/
630         commandString << "24000"
631       when /22.05/
632         commandString << "22050"
633       end
634       commandString << ";\n    "
635     end
636       
637     #Audio encoder
638     commandString << "acodec = "
639     case hash["FileCodecs"]
640     when /AC3 Audio/
641       commandString << "HB_ACODEC_FAAC;\n    "
642       commandString << "audio_mixdown = HB_AMIXDOWN_DOLBYPLII_AC3;\n    "
643       commandString << "arate = 48000;\n    "
644     when /AAC Audio/
645       commandString << "HB_ACODEC_FAAC;\n    "
646     when /AC-3/
647       commandString << "HB_ACODEC_AC3;\n    "
648     when /Vorbis/
649       commandString << "HB_ACODEC_VORBIS;\n    "
650     when /MP3/
651       commandString << "HB_ACODEC_LAME;\n    "
652     end
653     
654     #Cropping
655     if !hash["PictureAutoCrop"].to_i
656       commandString << "job->crop[0] = " << hash["PictureTopCrop"] << ";\n    "
657       commandString << "job->crop[1] = " << hash["PictureBottomCrop"] << ";\n    "
658       commandString << "job->crop[2] = " << hash["PictureLeftCrop"] << ";\n    "
659       commandString << "job->crop[4] - " << hash["PictureRightCrop"] << ";\n    "
660     end
661     
662     #Dimensions
663     if hash["PictureWidth"].to_i != 0
664       commandString << "job->width = "
665       commandString << hash["PictureWidth"] << ";\n    "
666     end
667     if hash["PictureHeight"].to_i != 0
668       commandString << "job->height = "
669       commandString << hash["PictureHeight"] << ";\n    "
670     end
671     
672     #Subtitles
673     if hash["Subtitles"] != "None"
674       commandString << "job->subtitle = "
675       commandString << ( hash["Subtitles"].to_i - 1).to_s << ";\n    "
676     end
677     
678     #x264 Options
679     if hash["x264Option"] != ""
680       commandString << "x264opts = strdup(\""
681       commandString << hash["x264Option"] << "\");\n    "
682     end
683     
684     #Video Filters
685     if hash["UsesPictureFilters"].to_i == 1
686       
687       case hash["PictureDeinterlace"].to_i
688       when 1
689         commandString << "deinterlace = 1;\n    "
690         commandString << "deinterlace_opt = \"-1\";\n    "
691       when 2
692         commandString << "deinterlace = 1;\n    "
693         commandString << "deinterlace_opt = \"2\";\n    "
694       when 3
695         commandString << "deinterlace = 1;\n    "
696         commandString << "deinterlace_opt = \"0\";\n    "
697       when 4
698         commandString << "deinterlace = 1;\n    "
699         commandString << "deinterlace_opt = \"1:-1:1\";\n    "
700       end
701       
702       case hash["PictureDenoise"].to_i
703       when 1
704         commandString << "denoise = 1;\n    "
705         commandString << "denoise_opt = \"2:1:2:3\";\n    "
706       when 2
707         commandString << "denoise = 1;\n    "
708         commandString << "denoise_opt = \"3:2:2:3\";\n    "
709       when 3
710         commandString << "denoise = 1;\n    "
711         commandString << "denoise_opt = \"7:7:5:5\";\n    "
712       end
713       
714       if hash["PictureDetelecine"].to_i == 1 then commandString << "detelecine = 1;\n    " end
715       if hash["PictureDeblock"].to_i == 1 then commandString << "deblock = 1;\n    " end
716       if hash["VFR"].to_i == 1 then commandString << "vfr = 1;\n    " end
717     end
718     
719     #Booleans
720     if hash["ChapterMarkers"].to_i == 1 then commandString << "job->chapter_markers = 1;\n    " end
721     if hash["PicturePAR"].to_i == 1 then commandString << "pixelratio = 1;\n    " end
722     if hash["VideoGrayScale"].to_i == 1 then commandString << "job->grayscale = 1;\n    " end
723     if hash["VideoTwoPass"].to_i == 1 then commandString << "twoPass = 1;\n    " end
724     if hash["VideoTurboTwoPass"].to_i == 1 then commandString << "turbo_opts_enabled = 1;\n" end
725     
726     commandString << "}"
727     
728     # That's it, print to screen now
729     puts commandString
730     #puts "*" * @columnWidth
731     puts  "\n"
732   end
733
734   def generateAPIList(hash) # Makes a list of the CLI options a built-in CLI preset uses, for wrappers to parse
735     commandString = ""
736     commandString << "    printf(\"\\n+ " << hash["PresetName"] << ": "
737         
738     #Video encoder
739     if hash["VideoEncoder"] != "FFmpeg"
740       commandString << " -e "
741       commandString << hash["VideoEncoder"].to_s.downcase
742     end
743
744     #VideoRateControl
745     case hash["VideoQualityType"].to_i
746     when 0
747       commandString << " -S " << hash["VideoTargetSize"]
748     when 1
749       commandString << " -b " << hash["VideoAvgBitrate"]
750     when 2
751       commandString << " -q " << hash["VideoQualitySlider"]
752     end
753
754     #FPS
755     if hash["VideoFramerate"] != "Same as source"
756       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
757         commandString << " -r " << "23.976"
758       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
759         commandString << " -r " << "29.97"
760       else
761         commandString << " -r " << hash["VideoFramerate"]
762       end
763     end
764     
765     # Only include samplerate and bitrate when not performing AC-3 passthru
766     if (hash["FileCodecs"].include? "AC-3") == false
767       #Audio bitrate
768       commandString << " -B " << hash["AudioBitRate"]
769       #Audio samplerate
770       commandString << " -R " << hash["AudioSampleRate"]
771     end
772     
773     #Audio encoder
774     commandString << " -E "
775     case hash["FileCodecs"]
776     when /AC3 Audio/
777       commandString << "aac+ac3"
778     when /AAC Audio/
779       commandString << "faac"
780     when /AC-3/
781       commandString << "ac3"
782     when /Vorbis/
783       commandString << "vorbis"
784     when /MP3/
785       commandString << "lame"
786     end
787     
788     #Container
789     commandString << " -f "
790     case hash["FileFormat"]
791     when /MP4/
792       commandString << "mp4"
793     when /AVI/
794       commandString << "avi"
795     when /OGM/
796       commandString << "ogm"
797     when /MKV/
798       commandString << "mkv"
799     end
800     
801     #iPod MP4 atom
802     if hash["Mp4iPodCompatible"].to_i == 1
803       commandString << " -I"
804     end
805     
806     #Cropping
807     if !hash["PictureAutoCrop"].to_i
808       commandString << " --crop "
809       commandString << hash["PictureTopCrop"]
810       commandString << ":"
811       commandString << hash["PictureBottomCrop"]
812       commandString << ":"
813       commandString << hash["PictureLeftCrop"]
814       commandString << ":"
815       commandString << hash["PictureRightCrop"]
816     end
817     
818     #Dimensions
819     if hash["PictureWidth"].to_i != 0
820       commandString << " -w "
821       commandString << hash["PictureWidth"]
822     end
823     if hash["PictureHeight"].to_i != 0
824       commandString << " -l "
825       commandString << hash["PictureHeight"]
826     end
827     
828     #Subtitles
829     if hash["Subtitles"] != "None"
830       commandString << " -s "
831       commandString << hash["Subtitles"]
832     end
833     
834     #Video Filters
835     if hash["UsesPictureFilters"].to_i == 1
836       
837       case hash["PictureDeinterlace"].to_i
838       when 1
839         commandString << " --deinterlace=\\\"fast\\\""
840       when 2
841         commandString << " --deinterlace=\\\slow\\\""
842       when 3
843         commandString << " --deinterlace=\\\"slower\\\""
844       when 4
845         commandString << " --deinterlace=\\\"slowest\\\""
846       end
847       
848       case hash["PictureDenoise"].to_i
849       when 1
850         commandString << " --denoise=\\\"weak\\\""
851       when 2
852         commandString << " --denoise=\\\"medium\\\""
853       when 3
854         commandString << " --denoise=\\\"strong\\\""
855       end
856       
857       if hash["PictureDetelecine"].to_i == 1 then commandString << " --detelecine" end
858       if hash["PictureDeblock"].to_i == 1 then commandString << " --deblock" end
859       if hash["VFR"].to_i == 1 then commandString << " --vfr" end
860     end
861     
862     #Booleans
863     if hash["ChapterMarkers"].to_i == 1 then commandString << " -m" end
864     if hash["PicturePAR"].to_i == 1 then commandString << " -p" end
865     if hash["VideoGrayScale"].to_i == 1 then commandString << " -g" end
866     if hash["VideoTwoPass"].to_i == 1 then commandString << " -2" end
867     if hash["VideoTurboTwoPass"].to_i == 1 then commandString << " -T" end
868     
869       #x264 Options
870       if hash["x264Option"] != ""
871         commandString << " -x "
872         commandString << hash["x264Option"]
873       end
874     
875     commandString << "\\n\");"
876     
877     # That's it, print to screen now
878     puts commandString
879     puts  "\n"
880   end
881   
882 end
883
884 # First grab the specified CLI options
885 options = readOptions
886
887 # Only run if one of the useful CLI flags have been passed
888 if options.cliraw == true || options.cliparse == true || options.api == true || options.apilist == true
889   # This line is the ignition -- generates hashes of
890   # presets and then displays them to the screen
891   # with the options the user selects on the CLI. 
892   Display.new( Presets.new.hashMasterList, options )
893 else
894   # Direct the user to the help
895   puts "\n\tUsage: manicure.rb [options]"
896   puts "\tSee help with -h or --help"
897 end