OSDN Git Service

Set an minimum subtitle display time of three seconds *or* until the next subtitle...
[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     # 64-bit files
346     if hash["Mp4LargeFile"].to_i == 1
347       commandString << " -4"
348     end
349     
350     #Cropping
351     if !hash["PictureAutoCrop"].to_i
352       commandString << " --crop "
353       commandString << hash["PictureTopCrop"]
354       commandString << ":"
355       commandString << hash["PictureBottomCrop"]
356       commandString << ":"
357       commandString << hash["PictureLeftCrop"]
358       commandString << ":"
359       commandString << hash["PictureRightCrop"]
360     end
361     
362     #Dimensions
363     if hash["PictureWidth"].to_i != 0
364       commandString << " -w "
365       commandString << hash["PictureWidth"]
366     end
367     if hash["PictureHeight"].to_i != 0
368       commandString << " -l "
369       commandString << hash["PictureHeight"]
370     end
371     
372     #Subtitles
373     if hash["Subtitles"] != "None"
374       commandString << " -s "
375       commandString << hash["Subtitles"]
376     end
377
378     #Video Filters
379     if hash["UsesPictureFilters"].to_i == 1
380       
381       case hash["PictureDeinterlace"].to_i
382       when 1
383         commandString << " --deinterlace=\"fast\""
384       when 2
385         commandString << " --deinterlace=\slow\""
386       when 3
387         commandString << " --deinterlace=\"slower\""
388       when 4
389         commandString << " --deinterlace=\"slowest\""
390       end
391       
392       case hash["PictureDenoise"].to_i
393       when 1
394         commandString << " --denoise=\"weak\""
395       when 2
396         commandString << " --denoise=\"medium\""
397       when 3
398         commandString << " --denoise=\"strong\""
399       end
400       
401       if hash["PictureDetelecine"].to_i == 1 then commandString << " --detelecine" end
402       if hash["PictureDeblock"].to_i == 1 then commandString << " --deblock" end
403       if hash["VFR"].to_i == 1 then commandString << " --vfr" end
404     end
405
406     #Booleans
407     if hash["ChapterMarkers"].to_i == 1 then commandString << " -m" end
408     if hash["PicturePAR"].to_i == 1 then commandString << " -p" end
409     if hash["VideoGrayScale"].to_i == 1 then commandString << " -g" end
410     if hash["VideoTwoPass"].to_i == 1 then commandString << " -2" end
411     if hash["VideoTurboTwoPass"].to_i == 1 then commandString << " -T" end
412
413     #x264 Options
414     if hash["x264Option"] != ""
415       commandString << " -x "
416       commandString << hash["x264Option"]
417     end
418     
419     # That's it, print to screen now
420     puts commandString
421     
422     #puts "*" * @columnWidth
423
424     puts  "\n"
425   end
426
427   def generateCLIParse(hash) # Makes a CLI equivalent of all user presets, for wrappers to parse
428     commandString = ""
429     commandString << '+ ' << hash["PresetName"] << ":"
430         
431     #Video encoder
432     if hash["VideoEncoder"] != "FFmpeg"
433       commandString << " -e "
434       commandString << hash["VideoEncoder"].to_s.downcase
435     end
436
437     #VideoRateControl
438     case hash["VideoQualityType"].to_i
439     when 0
440       commandString << " -S " << hash["VideoTargetSize"]
441     when 1
442       commandString << " -b " << hash["VideoAvgBitrate"]
443     when 2
444       commandString << " -q " << hash["VideoQualitySlider"]
445     end
446
447     #FPS
448     if hash["VideoFramerate"] != "Same as source"
449       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
450         commandString << " -r " << "23.976"
451       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
452         commandString << " -r " << "29.97"
453       else
454         commandString << " -r " << hash["VideoFramerate"]
455       end
456     end
457     
458     #Audio encoder (only include bitrate and samplerate when not doing AC3 passthru)
459     commandString << " -E "
460     case hash["FileCodecs"]
461     when /AC3 Audio/
462       commandString << "aac+ac3"
463     when /AC-3/
464       commandString << "ac3"
465     when /AAC Audio/
466       commandString << "faac" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
467     when /Vorbis/
468       commandString << "vorbis" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
469     when /MP3/
470       commandString << "lame" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
471     end
472     
473     #Container
474     commandString << " -f "
475     case hash["FileFormat"]
476     when /MP4/
477       commandString << "mp4"
478     when /AVI/
479       commandString << "avi"
480     when /OGM/
481       commandString << "ogm"
482     when /MKV/
483       commandString << "mkv"
484     end
485     
486     #iPod MP4 atom
487     if hash["Mp4iPodCompatible"].to_i == 1
488       commandString << " -I"
489     end
490     
491     # 64-bit files
492     if hash["Mp4LargeFile"].to_i == 1
493       commandString << " -4"
494     end
495     
496     #Cropping
497     if !hash["PictureAutoCrop"].to_i
498       commandString << " --crop "
499       commandString << hash["PictureTopCrop"]
500       commandString << ":"
501       commandString << hash["PictureBottomCrop"]
502       commandString << ":"
503       commandString << hash["PictureLeftCrop"]
504       commandString << ":"
505       commandString << hash["PictureRightCrop"]
506     end
507     
508     #Dimensions
509     if hash["PictureWidth"].to_i != 0
510       commandString << " -w "
511       commandString << hash["PictureWidth"]
512     end
513     if hash["PictureHeight"].to_i != 0
514       commandString << " -l "
515       commandString << hash["PictureHeight"]
516     end
517     
518     #Subtitles
519     if hash["Subtitles"] != "None"
520       commandString << " -s "
521       commandString << hash["Subtitles"]
522     end
523     
524     #Video Filters
525     if hash["UsesPictureFilters"].to_i == 1
526       
527       case hash["PictureDeinterlace"].to_i
528       when 1
529         commandString << " --deinterlace=\"fast\""
530       when 2
531         commandString << " --deinterlace=\slow\""
532       when 3
533         commandString << " --deinterlace=\"slower\""
534       when 4
535         commandString << " --deinterlace=\"slowest\""
536       end
537       
538       case hash["PictureDenoise"].to_i
539       when 1
540         commandString << " --denoise=\"weak\""
541       when 2
542         commandString << " --denoise=\"medium\""
543       when 3
544         commandString << " --denoise=\"strong\""
545       end
546       
547       if hash["PictureDetelecine"].to_i == 1 then commandString << " --detelecine" end
548       if hash["PictureDeblock"].to_i == 1 then commandString << " --deblock" end
549       if hash["VFR"].to_i == 1 then commandString << " --vfr" end
550     end
551
552     #Booleans
553     if hash["ChapterMarkers"].to_i == 1 then commandString << " -m" end
554     if hash["PicturePAR"].to_i == 1 then commandString << " -p" end
555     if hash["VideoGrayScale"].to_i == 1 then commandString << " -g" end
556     if hash["VideoTwoPass"].to_i == 1 then commandString << " -2" end
557     if hash["VideoTurboTwoPass"].to_i == 1 then commandString << " -T" end
558
559     #x264 Options
560     if hash["x264Option"] != ""
561       commandString << " -x "
562       commandString << hash["x264Option"]
563     end
564     
565     # That's it, print to screen now
566     puts commandString
567     
568     #puts "*" * @columnWidth
569
570     puts  "\n"
571   end
572
573   def generateAPIcalls(hash) # Makes a C version of the preset ready for coding into the CLI
574     
575     commandString = "if (!strcmp(preset_name, \"" << hash["PresetName"] << "\"))\n{\n    "
576     
577     #Filename suffix
578     case hash["FileFormat"]
579     when /MP4/
580       commandString << "mux = " << "HB_MUX_MP4;\n    "
581     when /AVI/
582       commandString << "mux = " << "HB_MUX_AVI;\n    "
583     when /OGM/
584       commandString << "mux = " << "HB_MUX_OGM;\n    "
585     when /MKV/
586       commandString << "mux = " << "HB_MUX_MKV;\n    "
587     end
588     
589     #iPod MP4 atom
590     if hash["Mp4iPodCompatible"].to_i == 1
591       commandString << "job->ipod_atom = 1;\n   "
592     end
593     
594     # 64-bit files
595     if hash["Mp4LargeFile"].to_i == 1
596       commandString << "job->largeFileSize = 1;\n"
597     end
598     
599     #Video encoder
600     if hash["VideoEncoder"] != "FFmpeg"
601       commandString << "vcodec = "
602       if hash["VideoEncoder"] == "x264"
603         commandString << "HB_VCODEC_X264;\n    "
604       elsif hash["VideoEncoder"].to_s.downcase == "xvid"
605         commandString << "HB_VCODEC_XVID;\n    "        
606       end
607     end
608
609     #VideoRateControl
610     case hash["VideoQualityType"].to_i
611     when 0
612       commandString << "size = " << hash["VideoTargetSize"] << ";\n    "
613     when 1
614       commandString << "job->vbitrate = " << hash["VideoAvgBitrate"] << ";\n    "
615     when 2
616       commandString << "job->vquality = " << hash["VideoQualitySlider"] << ";\n    "
617       commandString << "job->crf = 1;\n    "
618     end
619
620     #FPS
621     if hash["VideoFramerate"] != "Same as source"
622       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
623         commandString << "job->vrate_base = " << "1126125;\n    "
624       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
625         commandString << "job->vrate_base = " << "900900;\n    "
626       # Gotta add the rest of the framerates for completion's sake.
627       end
628     end
629     
630     # Only include samplerate and bitrate when not performing AC3 passthru
631     if (hash["FileCodecs"].include? "AC-3") == false
632       #Audio bitrate
633       commandString << "job->abitrate = " << hash["AudioBitRate"] << ";\n    "
634     
635       #Audio samplerate
636       commandString << "job->arate = "
637       case hash["AudioSampleRate"]
638       when /48/
639         commandString << "48000"
640       when /44.1/
641         commandString << "44100"
642       when /32/
643         commandString << "32000"
644       when /24/
645         commandString << "24000"
646       when /22.05/
647         commandString << "22050"
648       end
649       commandString << ";\n    "
650     end
651       
652     #Audio encoder
653     commandString << "acodec = "
654     case hash["FileCodecs"]
655     when /AC3 Audio/
656       commandString << "HB_ACODEC_FAAC;\n    "
657       commandString << "audio_mixdown = HB_AMIXDOWN_DOLBYPLII_AC3;\n    "
658       commandString << "arate = 48000;\n    "
659     when /AAC Audio/
660       commandString << "HB_ACODEC_FAAC;\n    "
661     when /AC-3/
662       commandString << "HB_ACODEC_AC3;\n    "
663     when /Vorbis/
664       commandString << "HB_ACODEC_VORBIS;\n    "
665     when /MP3/
666       commandString << "HB_ACODEC_LAME;\n    "
667     end
668     
669     #Cropping
670     if !hash["PictureAutoCrop"].to_i
671       commandString << "job->crop[0] = " << hash["PictureTopCrop"] << ";\n    "
672       commandString << "job->crop[1] = " << hash["PictureBottomCrop"] << ";\n    "
673       commandString << "job->crop[2] = " << hash["PictureLeftCrop"] << ";\n    "
674       commandString << "job->crop[4] - " << hash["PictureRightCrop"] << ";\n    "
675     end
676     
677     #Dimensions
678     if hash["PictureWidth"].to_i != 0
679       commandString << "job->width = "
680       commandString << hash["PictureWidth"] << ";\n    "
681     end
682     if hash["PictureHeight"].to_i != 0
683       commandString << "job->height = "
684       commandString << hash["PictureHeight"] << ";\n    "
685     end
686     
687     #Subtitles
688     if hash["Subtitles"] != "None"
689       commandString << "job->subtitle = "
690       commandString << ( hash["Subtitles"].to_i - 1).to_s << ";\n    "
691     end
692     
693     #x264 Options
694     if hash["x264Option"] != ""
695       commandString << "x264opts = strdup(\""
696       commandString << hash["x264Option"] << "\");\n    "
697     end
698     
699     #Video Filters
700     if hash["UsesPictureFilters"].to_i == 1
701       
702       case hash["PictureDeinterlace"].to_i
703       when 1
704         commandString << "deinterlace = 1;\n    "
705         commandString << "deinterlace_opt = \"-1\";\n    "
706       when 2
707         commandString << "deinterlace = 1;\n    "
708         commandString << "deinterlace_opt = \"2\";\n    "
709       when 3
710         commandString << "deinterlace = 1;\n    "
711         commandString << "deinterlace_opt = \"0\";\n    "
712       when 4
713         commandString << "deinterlace = 1;\n    "
714         commandString << "deinterlace_opt = \"1:-1:1\";\n    "
715       end
716       
717       case hash["PictureDenoise"].to_i
718       when 1
719         commandString << "denoise = 1;\n    "
720         commandString << "denoise_opt = \"2:1:2:3\";\n    "
721       when 2
722         commandString << "denoise = 1;\n    "
723         commandString << "denoise_opt = \"3:2:2:3\";\n    "
724       when 3
725         commandString << "denoise = 1;\n    "
726         commandString << "denoise_opt = \"7:7:5:5\";\n    "
727       end
728       
729       if hash["PictureDetelecine"].to_i == 1 then commandString << "detelecine = 1;\n    " end
730       if hash["PictureDeblock"].to_i == 1 then commandString << "deblock = 1;\n    " end
731       if hash["VFR"].to_i == 1 then commandString << "vfr = 1;\n    " end
732     end
733     
734     #Booleans
735     if hash["ChapterMarkers"].to_i == 1 then commandString << "job->chapter_markers = 1;\n    " end
736     if hash["PicturePAR"].to_i == 1 then commandString << "pixelratio = 1;\n    " end
737     if hash["VideoGrayScale"].to_i == 1 then commandString << "job->grayscale = 1;\n    " end
738     if hash["VideoTwoPass"].to_i == 1 then commandString << "twoPass = 1;\n    " end
739     if hash["VideoTurboTwoPass"].to_i == 1 then commandString << "turbo_opts_enabled = 1;\n" end
740     
741     commandString << "}"
742     
743     # That's it, print to screen now
744     puts commandString
745     #puts "*" * @columnWidth
746     puts  "\n"
747   end
748
749   def generateAPIList(hash) # Makes a list of the CLI options a built-in CLI preset uses, for wrappers to parse
750     commandString = ""
751     commandString << "    printf(\"\\n+ " << hash["PresetName"] << ": "
752         
753     #Video encoder
754     if hash["VideoEncoder"] != "FFmpeg"
755       commandString << " -e "
756       commandString << hash["VideoEncoder"].to_s.downcase
757     end
758
759     #VideoRateControl
760     case hash["VideoQualityType"].to_i
761     when 0
762       commandString << " -S " << hash["VideoTargetSize"]
763     when 1
764       commandString << " -b " << hash["VideoAvgBitrate"]
765     when 2
766       commandString << " -q " << hash["VideoQualitySlider"]
767     end
768
769     #FPS
770     if hash["VideoFramerate"] != "Same as source"
771       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
772         commandString << " -r " << "23.976"
773       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
774         commandString << " -r " << "29.97"
775       else
776         commandString << " -r " << hash["VideoFramerate"]
777       end
778     end
779     
780     # Only include samplerate and bitrate when not performing AC-3 passthru
781     if (hash["FileCodecs"].include? "AC-3") == false
782       #Audio bitrate
783       commandString << " -B " << hash["AudioBitRate"]
784       #Audio samplerate
785       commandString << " -R " << hash["AudioSampleRate"]
786     end
787     
788     #Audio encoder
789     commandString << " -E "
790     case hash["FileCodecs"]
791     when /AC3 Audio/
792       commandString << "aac+ac3"
793     when /AAC Audio/
794       commandString << "faac"
795     when /AC-3/
796       commandString << "ac3"
797     when /Vorbis/
798       commandString << "vorbis"
799     when /MP3/
800       commandString << "lame"
801     end
802     
803     #Container
804     commandString << " -f "
805     case hash["FileFormat"]
806     when /MP4/
807       commandString << "mp4"
808     when /AVI/
809       commandString << "avi"
810     when /OGM/
811       commandString << "ogm"
812     when /MKV/
813       commandString << "mkv"
814     end
815     
816     #iPod MP4 atom
817     if hash["Mp4iPodCompatible"].to_i == 1
818       commandString << " -I"
819     end
820     
821     # 64-bit files
822     if hash["Mp4LargeFile"].to_i == 1
823       commandString << " -4"
824     end
825     
826     #Cropping
827     if !hash["PictureAutoCrop"].to_i
828       commandString << " --crop "
829       commandString << hash["PictureTopCrop"]
830       commandString << ":"
831       commandString << hash["PictureBottomCrop"]
832       commandString << ":"
833       commandString << hash["PictureLeftCrop"]
834       commandString << ":"
835       commandString << hash["PictureRightCrop"]
836     end
837     
838     #Dimensions
839     if hash["PictureWidth"].to_i != 0
840       commandString << " -w "
841       commandString << hash["PictureWidth"]
842     end
843     if hash["PictureHeight"].to_i != 0
844       commandString << " -l "
845       commandString << hash["PictureHeight"]
846     end
847     
848     #Subtitles
849     if hash["Subtitles"] != "None"
850       commandString << " -s "
851       commandString << hash["Subtitles"]
852     end
853     
854     #Video Filters
855     if hash["UsesPictureFilters"].to_i == 1
856       
857       case hash["PictureDeinterlace"].to_i
858       when 1
859         commandString << " --deinterlace=\\\"fast\\\""
860       when 2
861         commandString << " --deinterlace=\\\slow\\\""
862       when 3
863         commandString << " --deinterlace=\\\"slower\\\""
864       when 4
865         commandString << " --deinterlace=\\\"slowest\\\""
866       end
867       
868       case hash["PictureDenoise"].to_i
869       when 1
870         commandString << " --denoise=\\\"weak\\\""
871       when 2
872         commandString << " --denoise=\\\"medium\\\""
873       when 3
874         commandString << " --denoise=\\\"strong\\\""
875       end
876       
877       if hash["PictureDetelecine"].to_i == 1 then commandString << " --detelecine" end
878       if hash["PictureDeblock"].to_i == 1 then commandString << " --deblock" end
879       if hash["VFR"].to_i == 1 then commandString << " --vfr" end
880     end
881     
882     #Booleans
883     if hash["ChapterMarkers"].to_i == 1 then commandString << " -m" end
884     if hash["PicturePAR"].to_i == 1 then commandString << " -p" end
885     if hash["VideoGrayScale"].to_i == 1 then commandString << " -g" end
886     if hash["VideoTwoPass"].to_i == 1 then commandString << " -2" end
887     if hash["VideoTurboTwoPass"].to_i == 1 then commandString << " -T" end
888     
889       #x264 Options
890       if hash["x264Option"] != ""
891         commandString << " -x "
892         commandString << hash["x264Option"]
893       end
894     
895     commandString << "\\n\");"
896     
897     # That's it, print to screen now
898     puts commandString
899     puts  "\n"
900   end
901   
902 end
903
904 # First grab the specified CLI options
905 options = readOptions
906
907 # Only run if one of the useful CLI flags have been passed
908 if options.cliraw == true || options.cliparse == true || options.api == true || options.apilist == true
909   # This line is the ignition -- generates hashes of
910   # presets and then displays them to the screen
911   # with the options the user selects on the CLI. 
912   Display.new( Presets.new.hashMasterList, options )
913 else
914   # Direct the user to the help
915   puts "\n\tUsage: manicure.rb [options]"
916   puts "\tSee help with -h or --help"
917 end