WinGui: Fix another instance of the Caliburn vs Json.net sillyness where objects...
[HandBrake.git] / scripts / manicure.rb
blob6764a3e1fe128076deb8510bed96a0894875ea11
1 #! /usr/bin/ruby
2 # manincure.rb version 0.66
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.
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.
11 # For handling command line arguments to the script
12 require 'optparse'
13 require 'ostruct'
14 require 'rubygems'
15 require 'plist'
17 # CLI options: (code based on http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/index.html )
18 def readOptions
19   
20   # --[no-]cli-raw, -r gives raw CLI for wiki
21   # --cli-parse, -p gives CLI strings for wrappers
22   # --api, -a gives preset code for test.c
23   # --api-list, -A gives CLI strings for --preset-list display
24   # --[no-]header, -h turns off banner display
25   options = OpenStruct.new
26   options.cliraw = false
27   options.cliparse = false
28   options.api = false
29   options.apilist = false
30   options.header = false
31   
32   opts = OptionParser.new do |opts|
33     opts.banner = "Usage: manicure.rb [options]"
34     
35     opts.separator ""
36     opts.separator "Options:"
37     
38     opts.on("-r", "--cli-raw", "Gives example strings for the HB wiki") do |raw|
39       options.cliraw = raw
40       option_set = true
41     end
42     
43     opts.on("-p", "--cli-parse", "Gives presets as wrapper-parseable CLI", " option strings") do |par|
44       options.cliparse = par
45     end
46     
47     opts.on("-a", "--api", "Gives preset code for test.c") do |api|
48       options.api = api
49     end
50     
51     opts.on("-A", "--api-list", "Gives code for test.c's --preset-list", " options") do |alist|
52       options.apilist = alist
53     end
54     
55     opts.on("-H", "--Header", "Display a banner before each preset") do |head|
56       options.header = head
57     end
58     
59     opts.on_tail("-h", "--help", "Show this message") do
60         puts opts
61         exit
62     end
63   end.parse!
64   
65   return options
66   
67 end
69 # These arrays contain all the other presets and hashes that are going to be used.
70 # Yeah, they're global variables. In an object-oriented scripting language.
71 # Real smooth, huh?
73 # This class parses the user's presets .plist into an array of hashes
74 class Presets
75   
76   attr_reader :hashMasterList
77   
78   # Running initialization runs everything.
79   # Calling it will also call the parser
80   # and display output.
81   def initialize
82     
83    # Grab the user's home path
84    homeLocation = `echo $HOME`.chomp
85    
86    # Use that to build a path to the presets .plist
87    inputFile = homeLocation+'/Library/Application Support/HandBrake/UserPresets.plist'
88    
89     # Parse the presets into hashes
90     @hashMasterList = Plist::parse_xml( inputFile )
91     
92   end
94 end
96 # This class displays the presets to stdout in various formats.
97 class Display
98   
99   def initialize(hashMasterList, options)
100   
101     @hashMasterList = hashMasterList
102     @options = options
104     # A width of 40 gives nice, compact output.
105     @columnWidth=40
106     
107     # Print to screen.
108     displayCommandStrings
109     
110   end
111   
112   def displayCommandStrings # prints everything to screen
113     
114     # Iterate through the hashes.    
115     @hashMasterList.each do |hash|
116     
117       # Check to see whether we've got a preset or afolder
118       if !hash["Folder"]
119         # It's a top-level preset
120        displayIndividualPreset(hash, 0) 
121       else
122         # It's a folder, yay
123         displayFolder( hash, 0 )
124         hash["ChildrenArray"].each do |subhash|
125           # Drill down to see its contents
126           if !subhash["Folder"]
127             # It's a preset
128             displayIndividualPreset(subhash, 1)
129           else
130             # It's a folder
131             displayFolder( subhash, 1 )
132             subhash["ChildrenArray"].each do |subsubhash|
133               # At this point we're far enough down we won't try to drill further
134               if !subsubhash["Folder"]
135                 displayIndividualPreset(subsubhash, 2)
136               end
137             end
138             displayFolderCloser( 1 )
139           end
140         end
141         displayFolderCloser( 0 )
142       end
143     end
144   end
145   
146   def displayIndividualPreset(hash, depth)
147     if @options.header == true
148       # First throw up a header to make each preset distinct
149       displayHeader(hash)
150     end
151     
152     if @options.cliraw == true
153       # Show the preset's full CLI string equivalent
154       generateCLIString(hash, depth)
155     end
156     
157     if @options.cliparse == true
158       generateCLIParse(hash, depth)
159     end
160     
161     if @options.api == true
162       # Show the preset as code for test/test.c, HandBrakeCLI
163       generateAPIcalls(hash)
164     end
165     
166     if @options.apilist == true
167       # Show the preset as print statements, for CLI wrappers to parse.
168       generateAPIList(hash, depth) 
169     end
170   end
171   
172   def displayHeader(hash) # A distinct banner to separate each preset
173     
174     # Print a line of asterisks
175     puts "*" * @columnWidth
176     
177     # Print the name, centered
178     puts '* '+hash["PresetName"].to_s.center(@columnWidth-4)+' *'
179     
180     # Print a line of dashes
181     puts '~' * @columnWidth
182     
183     # Print the description, centered and word-wrapped
184     puts hash["PresetDescription"].to_s.center(@columnWidth).gsub(/\n/," ").scan(/\S.{0,#{@columnWidth-2}}\S(?=\s|$)|\S+/)
185     
186     # Print another line of dashes
187     puts '~' * @columnWidth
188     
189     # Print the formats the preset uses
190     puts "#{hash["FileCodecs"]}".center(@columnWidth)
191     
192     # Note if the preset isn't built-in
193     if hash["Type"] == 1
194       puts "Custom Preset".center(@columnWidth)
195     end
197     # Note if the preset is marked as default.
198     if hash["Default"] == 1
199       puts "This is your default preset.".center(@columnWidth)
200     end
201     
202     # End with a line of tildes.  
203     puts "~" * @columnWidth
204     
205   end
206   
207   def displayFolder( hash, depth )
209     if @options.cliraw == true
210       # Show the folder's full in a format that matches the CLI equivalents
211       generateCLIFolderString(hash, depth)
212     end
213     
214     if @options.cliparse == true
215       # Show the folder in a format that matches the CLI wrapper equivalents
216       generateCLIFolderParse(hash, depth)
217     end
218     
219     if @options.apilist == true
220       # Show the folder as print statements, for CLI wrappers to parse.
221       generateAPIFolderList(hash, depth) 
222     end
223     
224   end
225   
226   def displayFolderCloser( depth )
227     if @options.cliraw == true
228       # Show the folder's full in a format that matches the CLI equivalents
229       generateCLIFolderCloserString( depth )
230     end
231     
232     if @options.cliparse == true
233       # Show the folder in a format that matches the CLI wrapper equivalents
234       generateCLIFolderCloserParse( depth )
235     end
236     
237     if @options.apilist == true
238       # Show the folder as print statements, for CLI wrappers to parse.
239       generateAPIFolderCloserList( depth ) 
240     end
241   end
242   
243   def generateCLIFolderString( hash, depth ) # Shows the folder for the CLI equivalents
244     commandString = ""
245     depth.times do
246       commandString << "   "
247     end
248     (depth+1).times do
249       commandString << "<"
250     end
251     commandString << " " << hash["PresetName"] << "\n"
252     puts commandString
253   end
254   
255   def generateCLIFolderCloserString( depth )
256     commandString = ""
257     depth.times do
258       commandString << "   "
259     end
260     (depth+1).times do
261       commandString << ">"
262     end
263     commandString << "\n"
264     puts commandString
265   end
266   
267   def generateCLIString(hash, depth) # Makes a full CLI equivalent of a preset
268     commandString = ""
269     depth.times do
270       commandString << "   "
271     end
272     commandString << './HandBrakeCLI -i DVD -o ~/Movies/movie.'
273     
274     #Filename suffix
275     case hash["FileFormat"]
276     when /MPEG-4/, /MP4/
277       commandString << "mp4 "
278     when /Matroska/, /MKV/
279       commandString << "mkv "
280     end
281     
282     #Video encoder
283     commandString << " -e "
284     case hash["VideoEncoder"]
285     when /x264/
286       commandString << "x264"
287     when /Theora/
288       commandString << "theora"
289     when /MPEG-4/
290       commandString << "ffmpeg4"
291     when /MPEG-2/
292       commandString << "ffmpeg2"
293     end
295     #VideoRateControl
296     case hash["VideoQualityType"]
297     when 0
298       commandString << " -S " << hash["VideoTargetSize"]
299     when 1
300       commandString << " -b " << hash["VideoAvgBitrate"]
301     when 2
302       commandString << " -q " << hash["VideoQualitySlider"].to_s
303     end
305     #FPS
306     if hash["VideoFramerate"] != "Same as source"
307       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
308         commandString << " -r " << "23.976"
309       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
310         commandString << " -r " << "29.97"
311       elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
312         commandString << " -r " << "25"
313       else
314         commandString << " -r " << hash["VideoFramerate"]
315       end
316       # not same as source: pfr, else default (cfr)
317       if hash["VideoFramerateMode"] == "pfr"
318         commandString << " --pfr "
319       end
320     # same as source: cfr, else default (vfr)
321     elsif hash["VideoFramerateMode"] == "cfr"
322       commandString << " --cfr "
323     end
324     
325     #Audio tracks
326     audioBitrates = ""
327     audioEncoders = ""
328     audioMixdowns = ""
329     audioSamplerates = ""
330     audioTracks = ""
331     audioTrackDRCs = ""
332     audioCount = hash["AudioList"].size
333     
334     hash["AudioList"].each do |audioTrack|
335       audioCount = audioCount - 1
337       #Bitrates
338       audioBitrates << audioTrack["AudioBitrate"]
339       
340       #Encoders
341       case audioTrack["AudioEncoder"]
342         when /AC3 Pass/
343           audioEncoders << "copy:ac3"
344         when /AC3/
345           audioEncoders << "ac3"
346         when /DTS Pass/
347           audioEncoders << "copy:dts"
348         when /DTS-HD Pass/
349           audioEncoders << "copy:dtshd"
350         when /AAC Pass/
351           audioEncoders << "copy:aac"
352         when "AAC (ffmpeg)", "AAC (avcodec)", "AAC (faac)"
353           audioEncoders << "av_aac"
354         when "AAC (FDK)"
355           audioEncoders << "fdk_aac"
356         when "HE-AAC (FDK)"
357           audioEncoders << "fdk_haac"
358         when "AAC (CoreAudio)"
359           audioEncoders << "ca_aac"
360         when "HE-AAC (CoreAudio)"
361           audioEncoders << "ca_haac"
362         when /Vorbis/
363           audioEncoders << "vorbis"
364         when /MP3 Pass/
365           audioEncoders << "copy:mp3"
366         when /MP3/
367           audioEncoders << "mp3"
368         when "FLAC (ffmpeg)", "FLAC 16-bit"
369           audioEncoders << "flac16"
370         when "FLAC (24-bit)", "FLAC 24-bit"
371           audioEncoders << "flac24"
372         when /Auto Pass/
373           audioEncoders << "copy"
374       end
375       
376       #Mixdowns
377       case audioTrack["AudioMixdown"]
378         when "Mono (Left Only)"
379           audioMixdowns << "left_only"
380         when "Mono (Right Only)"
381           audioMixdowns << "right_only"
382         when /Mono/
383           audioMixdowns << "mono"
384         when /Stereo/
385           audioMixdowns << "stereo"
386         when /Dolby Surround/
387           audioMixdowns << "dpl1"
388         when /Dolby Pro Logic II/
389           audioMixdowns << "dpl2"
390         when /5.1/, /discrete/
391           audioMixdowns << "5point1"
392         when /6.1/
393           audioMixdowns << "6point1"
394         when "7.1 (5F/2R/LFE)"
395           audioMixdowns << "5_2_lfe"
396         when /7.1/
397           audioMixdowns << "7point1"
398         when /None/
399           audioMixdowns << "none"
400       end
401       
402       #Samplerates
403       audioSamplerates << audioTrack["AudioSamplerate"]
404       
405       #Tracks
406       audioTracks << audioTrack["AudioTrack"].to_s
407       
408       #DRC
409       audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
410       
411       if audioCount > 0
412         audioBitrates << ","
413         audioEncoders << ","
414         audioMixdowns << ","
415         audioSamplerates << ","
416         audioTracks << ","
417         audioTrackDRCs << ","
418       end
419       
420     end
421     commandString << " -a " << audioTracks
422     commandString << " -E " << audioEncoders
423     commandString << " -B " << audioBitrates
424     commandString << " -6 " << audioMixdowns
425     commandString << " -R " << audioSamplerates
426     commandString << " -D " << audioTrackDRCs
427     
428     #Auto Passthru Mask
429     audioCopyMask = ""
430     
431     if hash["AudioAllowAACPass"].to_i == 1
432       audioCopyMask << "aac"
433     end
434     if hash["AudioAllowAC3Pass"].to_i == 1
435       if audioCopyMask.size > 0
436         audioCopyMask << ","
437       end
438       audioCopyMask << "ac3"
439     end
440     if hash["AudioAllowDTSHDPass"].to_i == 1
441       if audioCopyMask.size > 0
442         audioCopyMask << ","
443       end
444       audioCopyMask << "dtshd"
445     end
446     if hash["AudioAllowDTSPass"].to_i == 1
447       if audioCopyMask.size > 0
448         audioCopyMask << ","
449       end
450       audioCopyMask << "dts"
451     end
452     if hash["AudioAllowMP3Pass"].to_i == 1
453       if audioCopyMask.size > 0
454         audioCopyMask << ","
455       end
456       audioCopyMask << "mp3"
457     end
458     
459     if audioCopyMask.size > 0
460       commandString << " --audio-copy-mask " << audioCopyMask
461     end
462     
463     #Auto Passthru Fallback
464     audioEncoderFallback = ""
465     
466     case hash["AudioEncoderFallback"]
467       when /AC3/
468         audioEncoderFallback << "ac3"
469       when "AAC (ffmpeg)", "AAC (avcodec)", "AAC (faac)"
470         audioEncoderFallback << "av_aac"
471       when "AAC (FDK)"
472         audioEncoderFallback << "fdk_aac"
473       when "HE-AAC (FDK)"
474         audioEncoderFallback << "fdk_haac"
475       when "AAC (CoreAudio)"
476         audioEncoderFallback << "ca_aac"
477       when "HE-AAC (CoreAudio)"
478         audioEncoderFallback << "ca_haac"
479       when /Vorbis/
480         audioEncoderFallback << "vorbis"
481       when /MP3/
482         audioEncoderFallback << "mp3"
483       when "FLAC (ffmpeg)", "FLAC 16-bit"
484         audioEncoderFallback << "flac16"
485       when "FLAC (24-bit)", "FLAC 24-bit"
486         audioEncoderFallback << "flac24"
487     end
488     
489     if audioEncoderFallback.size > 0
490       commandString << " --audio-fallback " << audioEncoderFallback
491     end
492         
493     #Container
494     commandString << " -f "
495     case hash["FileFormat"]
496     when "MPEG-4 (mp4v2)"
497       commandString << "mp4v2"
498     when /MP4/
499       commandString << "mp4"
500     when "Matroska (libmkv)"
501       commandString << "libmkv"
502     when /MKV/
503       commandString << "mkv"
504     end
505     
506     #iPod MP4 atom
507     if hash["Mp4iPodCompatible"].to_i == 1
508       commandString << " -I"
509     end
510     
511     #MP4 Optimize for HTTP Streaming
512     if hash["Mp4HttpOptimize"].to_i == 1
513       commandString << " -O"
514     end
515     
516     #Cropping
517     if hash["PictureAutoCrop"] == 0
518       commandString << " --crop "
519       commandString << hash["PictureTopCrop"].to_s
520       commandString << ":"
521       commandString << hash["PictureBottomCrop"].to_s
522       commandString << ":"
523       commandString << hash["PictureLeftCrop"].to_s
524       commandString << ":"
525       commandString << hash["PictureRightCrop"].to_s
526     end
527     
528     #Dimensions
529     if hash["PictureWidth"] != 0
530       commandString << " -X "
531       commandString << hash["PictureWidth"].to_s
532     end
533     if hash["PictureHeight"] != 0
534       commandString << " -Y "
535       commandString << hash["PictureHeight"].to_s
536     end
537     
538     #Subtitles
539     if hash["Subtitles"] && hash["Subtitles"] != "None"
540       if hash["Subtitles"] == "Autoselect"
541         commandString << " --subtitle-scan"
542       else
543         commandString << " -s "
544         commandString << hash["Subtitles"]
545       end
546     end
548     #Video Filters
549     if hash["UsesPictureFilters"] == 1
550       
551       case hash["PictureDeinterlace"]
552       when 1
553         commandString << " --deinterlace=" << hash["PictureDeinterlaceCustom"].to_s
554       when 2
555         commandString << " --deinterlace=fast"
556       when 3
557         commandString << " --deinterlace=slow"
558       when 4
559         commandString << " --deinterlace=slower"
560       when 5
561         commandString << " --deinterlace=bob"
562       end
563       
564       case hash["PictureDenoise"]
565       when 1
566         commandString << " --denoise=" << hash["PictureDenoiseCustom"].to_s
567       when 2
568         commandString << " --denoise=weak"
569       when 3
570         commandString << " --denoise=medium"
571       when 4
572         commandString << " --denoise=strong"
573       end
574       
575       case hash["PictureDecomb"]
576       when 1
577         commandString << " --decomb=" << hash["PictureDecombCustom"].to_s
578       when 2
579         commandString << " --decomb"
580       when 3
581         commandString << " --decomb=fast"
582       when 4
583         commandString << " --decomb=bob"
584       end
586       case hash["PictureDetelecine"]
587         when 1
588           commandString << " --detelecine=" << hash["PictureDetelecineCustom"].to_s
589         when 2
590           commandString << " --detelecine"
591       end
593       if hash["PictureDeblock"] != 0
594         commandString << " --deblock=" << hash["PictureDeblock"].to_s
595       end
596       
597     end
598     
599     #Anamorphic
600     if hash["PicturePAR"] == 1
601       commandString << " --strict-anamorphic"
602     elsif hash["PicturePAR"] == 2
603       commandString << " --loose-anamorphic"
604     elsif hash["PicturePAR"] == 3
605       commandString << " --custom-anamorphic"
606     end
608     #Modulus
609     if hash["PictureModulus"]
610       commandString << " --modulus " << hash["PictureModulus"].to_s
611     end
613     #Booleans
614     if hash["ChapterMarkers"] == 1 then commandString << " -m" end
615     if hash["VideoGrayScale"] == 1 then commandString << " -g" end
616     if hash["VideoTwoPass"] == 1 then commandString << " -2" end
617     if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
619     #Advanced Options
620     if hash["x264UseAdvancedOptions"] != 1
621       if hash["x264Preset"] != ""
622         commandString << " --x264-preset "
623         commandString << hash["x264Preset"]
624       end
625       if hash["x264Tune"] != "" && hash["x264Tune"] != "none"
626         commandString << " --x264-tune "
627         commandString << hash["x264Tune"]
628       end
629       if hash["h264Profile"] != "" && hash["h264Profile"] != "auto"
630         commandString << " --h264-profile "
631         commandString << hash["h264Profile"]
632       end
633       if hash["h264Level"] != "" && hash["h264Level"] != "auto"
634         commandString << " --h264-level "
635         commandString << hash["h264Level"]
636       end
637       if hash["x264OptionExtra"] != ""
638         commandString << " -x "
639         commandString << hash["x264OptionExtra"]
640       end
641     elsif hash["x264Option"] != ""
642       commandString << " -x "
643       commandString << hash["x264Option"]
644     end
645     
646     # That's it, print to screen now
647     puts commandString
648   end
649   
650   def generateCLIFolderParse( hash, depth ) # Shows the folder for wrappers to parse
651     commandString = ""
652     depth.times do
653       commandString << "   "
654     end
655     (depth+1).times do
656       commandString << "<"
657     end
658     commandString << " " << hash["PresetName"] << "\n"
659     puts commandString
660   end
661   
662   def generateCLIFolderCloserParse( depth )
663     commandString = ""
664     depth.times do
665       commandString << "   "
666     end
667     (depth+1).times do
668       commandString << ">"
669     end
670     commandString << "\n"
671     puts commandString
672   end
673   
674   def generateCLIParse(hash, depth) # Makes a CLI equivalent of all user presets, for wrappers to parse
675     commandString = ""
676     depth.times do
677       commandString << "   "
678     end
679     commandString << '+ ' << hash["PresetName"] << ":"
680         
681     #Video encoder
682     commandString << " -e "
683     case hash["VideoEncoder"]
684     when /x264/
685       commandString << "x264"
686     when /Theora/
687       commandString << "theora"
688     when /MPEG-4/
689       commandString << "ffmpeg4"
690     when /MPEG-2/
691       commandString << "ffmpeg2"
692     end
694     #VideoRateControl
695     case hash["VideoQualityType"]
696     when 0
697       commandString << " -S " << hash["VideoTargetSize"]
698     when 1
699       commandString << " -b " << hash["VideoAvgBitrate"]
700     when 2
701       commandString << " -q " << hash["VideoQualitySlider"].to_s
702     end
704     #FPS
705     if hash["VideoFramerate"] != "Same as source"
706       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
707         commandString << " -r " << "23.976"
708       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
709         commandString << " -r " << "29.97"
710       elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
711         commandString << " -r " << "25"
712       else
713         commandString << " -r " << hash["VideoFramerate"]
714       end
715       # not same as source: pfr, else default (cfr)
716       if hash["VideoFramerateMode"] == "pfr"
717         commandString << " --pfr "
718       end
719     # same as source: cfr, else default (vfr)
720     elsif hash["VideoFramerateMode"] == "cfr"
721       commandString << " --cfr "
722     end
723     
724     #Audio tracks
725     audioBitrates = ""
726     audioEncoders = ""
727     audioMixdowns = ""
728     audioSamplerates = ""
729     audioTracks = ""
730     audioTrackDRCs = ""
731     audioCount = hash["AudioList"].size
732     
733     hash["AudioList"].each do |audioTrack|
734       audioCount = audioCount - 1
736       #Bitrates
737       audioBitrates << audioTrack["AudioBitrate"]
738       
739       #Encoders
740       case audioTrack["AudioEncoder"]
741         when /AC3 Pass/
742           audioEncoders << "copy:ac3"
743         when /AC3/
744           audioEncoders << "ac3"
745         when /DTS Pass/
746           audioEncoders << "copy:dts"
747         when /DTS-HD Pass/
748           audioEncoders << "copy:dtshd"
749         when /AAC Pass/
750           audioEncoders << "copy:aac"
751         when "AAC (ffmpeg)", "AAC (avcodec)", "AAC (faac)"
752           audioEncoders << "av_aac"
753         when "AAC (FDK)"
754           audioEncoders << "fdk_aac"
755         when "HE-AAC (FDK)"
756           audioEncoders << "fdk_haac"
757         when "AAC (CoreAudio)"
758           audioEncoders << "ca_aac"
759         when "HE-AAC (CoreAudio)"
760           audioEncoders << "ca_haac"
761         when /Vorbis/
762           audioEncoders << "vorbis"
763         when /MP3 Pass/
764           audioEncoders << "copy:mp3"
765         when /MP3/
766           audioEncoders << "mp3"
767         when "FLAC (ffmpeg)", "FLAC 16-bit"
768           audioEncoders << "flac16"
769         when "FLAC (24-bit)", "FLAC 24-bit"
770           audioEncoders << "flac24"
771         when /Auto Pass/
772           audioEncoders << "copy"
773       end
774       
775       #Mixdowns
776       case audioTrack["AudioMixdown"]
777         when "Mono (Left Only)"
778           audioMixdowns << "left_only"
779         when "Mono (Right Only)"
780           audioMixdowns << "right_only"
781         when /Mono/
782           audioMixdowns << "mono"
783         when /Stereo/
784           audioMixdowns << "stereo"
785         when /Dolby Surround/
786           audioMixdowns << "dpl1"
787         when /Dolby Pro Logic II/
788           audioMixdowns << "dpl2"
789         when /5.1/, /discrete/
790           audioMixdowns << "5point1"
791         when /6.1/
792           audioMixdowns << "6point1"
793         when "7.1 (5F/2R/LFE)"
794           audioMixdowns << "5_2_lfe"
795         when /7.1/
796           audioMixdowns << "7point1"
797         when /None/
798           audioMixdowns << "none"
799       end
800       
801       #Samplerates
802       audioSamplerates << audioTrack["AudioSamplerate"]
803       
804       #Tracks
805       audioTracks << audioTrack["AudioTrack"].to_s
806       
807       #DRC
808       audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
809       
810       if audioCount > 0
811         audioBitrates << ","
812         audioEncoders << ","
813         audioMixdowns << ","
814         audioSamplerates << ","
815         audioTracks << ","
816         audioTrackDRCs << ","
817       end
818       
819     end
820     commandString << " -a " << audioTracks
821     commandString << " -E " << audioEncoders
822     commandString << " -B " << audioBitrates
823     commandString << " -6 " << audioMixdowns
824     commandString << " -R " << audioSamplerates
825     commandString << " -D " << audioTrackDRCs
826     
827     #Auto Passthru Mask
828     audioCopyMask = ""
829     
830     if hash["AudioAllowAACPass"].to_i == 1
831       audioCopyMask << "aac"
832     end
833     if hash["AudioAllowAC3Pass"].to_i == 1
834       if audioCopyMask.size > 0
835         audioCopyMask << ","
836       end
837       audioCopyMask << "ac3"
838     end
839     if hash["AudioAllowDTSHDPass"].to_i == 1
840       if audioCopyMask.size > 0
841         audioCopyMask << ","
842       end
843       audioCopyMask << "dtshd"
844     end
845     if hash["AudioAllowDTSPass"].to_i == 1
846       if audioCopyMask.size > 0
847         audioCopyMask << ","
848       end
849       audioCopyMask << "dts"
850     end
851     if hash["AudioAllowMP3Pass"].to_i == 1
852       if audioCopyMask.size > 0
853         audioCopyMask << ","
854       end
855       audioCopyMask << "mp3"
856     end
857     
858     if audioCopyMask.size > 0
859       commandString << " --audio-copy-mask " << audioCopyMask
860     end
861     
862     #Auto Passthru Fallback
863     audioEncoderFallback = ""
864     
865     case hash["AudioEncoderFallback"]
866       when /AC3/
867         audioEncoderFallback << "ac3"
868       when "AAC (ffmpeg)", "AAC (avcodec)", "AAC (faac)"
869         audioEncoderFallback << "av_aac"
870       when "AAC (FDK)"
871         audioEncoderFallback << "fdk_aac"
872       when "HE-AAC (FDK)"
873         audioEncoderFallback << "fdk_haac"
874       when "AAC (CoreAudio)"
875         audioEncoderFallback << "ca_aac"
876       when "HE-AAC (CoreAudio)"
877         audioEncoderFallback << "ca_haac"
878       when /Vorbis/
879         audioEncoderFallback << "vorbis"
880       when /MP3/
881         audioEncoderFallback << "mp3"
882       when "FLAC (ffmpeg)", "FLAC 16-bit"
883         audioEncoderFallback << "flac16"
884       when "FLAC (24-bit)", "FLAC 24-bit"
885         audioEncoderFallback << "flac24"
886     end
887     
888     if audioEncoderFallback.size > 0
889       commandString << " --audio-fallback " << audioEncoderFallback
890     end
891     
892     #Container
893     commandString << " -f "
894     case hash["FileFormat"]
895     when "MPEG-4 (mp4v2)"
896       commandString << "mp4v2"
897     when /MP4/
898       commandString << "mp4"
899     when "Matroska (libmkv)"
900       commandString << "libmkv"
901     when /MKV/
902       commandString << "mkv"
903     end
904     
905     #iPod MP4 atom
906     if hash["Mp4iPodCompatible"].to_i == 1
907       commandString << " -I"
908     end
909     
910     #MP4 Optimize for HTTP Streaming
911     if hash["Mp4HttpOptimize"].to_i == 1
912       commandString << " -O"
913     end
914     
915     #Cropping
916     if hash["PictureAutoCrop"] == 0
917       commandString << " --crop "
918       commandString << hash["PictureTopCrop"].to_s
919       commandString << ":"
920       commandString << hash["PictureBottomCrop"].to_s
921       commandString << ":"
922       commandString << hash["PictureLeftCrop"].to_s
923       commandString << ":"
924       commandString << hash["PictureRightCrop"].to_s
925     end
926     
927     #Dimensions
928     if hash["PictureWidth"] != 0
929       commandString << " -X "
930       commandString << hash["PictureWidth"].to_s
931     end
932     if hash["PictureHeight"] != 0
933       commandString << " -Y "
934       commandString << hash["PictureHeight"].to_s
935     end
936     
937     #Subtitles
938     if hash["Subtitles"] && hash["Subtitles"] != "None"
939       if hash["Subtitles"] == "Autoselect"
940         commandString << " --subtitle-scan"
941       else
942         commandString << " -s "
943         commandString << hash["Subtitles"]
944       end
945     end
946     
947     #Video Filters
948     if hash["UsesPictureFilters"] == 1
949       
950       case hash["PictureDeinterlace"]
951       when 1
952         commandString << " --deinterlace=" << hash["PictureDeinterlaceCustom"].to_s
953       when 2
954         commandString << " --deinterlace=fast"
955       when 3
956         commandString << " --deinterlace=slow"
957       when 4
958         commandString << " --deinterlace=slower"
959       when 5
960         commandString << " --deinterlace=bob"
961       end
962       
963       case hash["PictureDenoise"]
964       when 1
965         commandString << " --denoise=" << hash["PictureDenoiseCustom"].to_s
966       when 2
967         commandString << " --denoise=weak"
968       when 3
969         commandString << " --denoise=medium"
970       when 4
971         commandString << " --denoise=strong"
972       end
973       
974       case hash["PictureDecomb"]
975       when 1
976         commandString << " --decomb=" << hash["PictureDecombCustom"].to_s
977       when 2
978         commandString << " --decomb"
979       when 3
980         commandString << " --decomb=fast"
981       when 4
982         commandString << " --decomb=bob"
983       end
985       case hash["PictureDetelecine"]
986         when 1
987           commandString << " --detelecine=" << hash["PictureDetelecineCustom"].to_s
988         when 2
989           commandString << " --detelecine"
990       end
992       if hash["PictureDeblock"] != 0
993         commandString << " --deblock=" << hash["PictureDeblock"].to_s
994       end
996     end
998     #Anamorphic
999     if hash["PicturePAR"] == 1
1000       commandString << " --strict-anamorphic"
1001     elsif hash["PicturePAR"] == 2
1002       commandString << " --loose-anamorphic"
1003     elsif hash["PicturePAR"] == 3
1004       commandString << " --custom-anamorphic"
1005     end
1006     
1007     #Modulus
1008     if hash["PictureModulus"]
1009       commandString << " --modulus " << hash["PictureModulus"].to_s
1010     end
1012     #Booleans
1013     if hash["ChapterMarkers"] == 1 then commandString << " -m" end
1014     if hash["VideoGrayScale"] == 1 then commandString << " -g" end
1015     if hash["VideoTwoPass"] == 1 then commandString << " -2" end
1016     if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
1018     #Advanced Options
1019     if hash["x264UseAdvancedOptions"] != 1
1020       if hash["x264Preset"] != ""
1021         commandString << " --x264-preset "
1022         commandString << hash["x264Preset"]
1023       end
1024       if hash["x264Tune"] != "" && hash["x264Tune"] != "none"
1025         commandString << " --x264-tune "
1026         commandString << hash["x264Tune"]
1027       end
1028       if hash["h264Profile"] != "" && hash["h264Profile"] != "auto"
1029         commandString << " --h264-profile "
1030         commandString << hash["h264Profile"]
1031       end
1032       if hash["h264Level"] != "" && hash["h264Level"] != "auto"
1033         commandString << " --h264-level "
1034         commandString << hash["h264Level"]
1035       end
1036       if hash["x264OptionExtra"] != ""
1037         commandString << " -x "
1038         commandString << hash["x264OptionExtra"]
1039       end
1040     elsif hash["x264Option"] != ""
1041       commandString << " -x "
1042       commandString << hash["x264Option"]
1043     end
1044     
1045     # That's it, print to screen now
1046     puts commandString
1047   end
1049   def generateAPIcalls(hash) # Makes a C version of the preset ready for coding into the CLI
1050     
1051     commandString = "if (!strcasecmp(preset_name, \"" << hash["PresetName"] << "\"))\n{\n    "
1052     
1053     #Container
1054     commandString << "if( !mux )\n    "
1055     commandString << "{\n    "
1057     case hash["FileFormat"]
1058     when "MPEG-4 (mp4v2)"
1059       commandString << "    mux = " << "HB_MUX_MP4V2;\n    "
1060     when /MP4/
1061       commandString << "    mux = " << "HB_MUX_MP4;\n    "
1062     when "Matroska (libmkv)"
1063       commandString << "    mux = " << "HB_MUX_LIBMKV;\n    "
1064     when /MKV/
1065       commandString << "    mux = " << "HB_MUX_MKV;\n    "
1066     end
1067     commandString << "}\n    "
1068     
1069     #iPod MP4 atom
1070     if hash["Mp4iPodCompatible"].to_i == 1
1071       commandString << "job->ipod_atom = 1;\n    "
1072     end
1073     
1074     #MP4 Optimize for HTTP Streaming
1075     if hash["Mp4HttpOptimize"].to_i == 1
1076       commandString << "job->mp4_optimize = 1;\n    "
1077     end
1078     
1079     #Video encoder
1080     commandString << "vcodec = "
1081     case hash["VideoEncoder"]
1082     when /x264/
1083       commandString << "HB_VCODEC_X264;\n    "
1084     when /Theora/
1085       commandString << "HB_VCODEC_THEORA;\n    "
1086     when /MPEG-4/
1087       commandString << "HB_VCODEC_FFMPEG_MPEG4;\n    "
1088     when /MPEG-2/
1089       commandString << "HB_VCODEC_FFMPEG_MPEG2;\n    "
1090     end
1092     #VideoRateControl
1093     case hash["VideoQualityType"]
1094     when 0
1095       commandString << "size = " << hash["VideoTargetSize"] << ";\n    "
1096     when 1
1097       commandString << "job->vbitrate = " << hash["VideoAvgBitrate"] << ";\n    "
1098     when 2
1099       commandString << "job->vquality = " << hash["VideoQualitySlider"].to_s << ";\n    "
1100     end
1102     #FPS
1103     if hash["VideoFramerate"] != "Same as source"
1104       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
1105         commandString << "filter_vrate_base = " << "1126125;\n    "
1106       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
1107         commandString << "filter_vrate_base = " << "900900;\n    "
1108       elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
1109         commandString << "filter_vrate_base = " << "1080000;\n    "
1110       else
1111         commandString << "filter_vrate_base = " << (27000000 / hash["VideoFramerate"].to_i).to_s << ";\n    "
1112       end
1113       # not same as source: pfr, else default (cfr)
1114       if hash["VideoFramerateMode"] == "pfr"
1115         commandString << "filter_cfr = 2;\n    "
1116       else
1117         commandString << "filter_cfr = 1;\n    "
1118       end
1119     # same as source: cfr, else default (vfr)
1120     elsif hash["VideoFramerateMode"] == "cfr"
1121       commandString << "filter_cfr = 1;\n    "
1122     end
1123     
1124     #Audio tracks
1125     audioBitrates = ""
1126     audioEncoders = ""
1127     audioMixdowns = ""
1128     audioSamplerates = ""
1129     audioTracks = ""
1130     audioTrackDRCs = ""
1131     audioCount = hash["AudioList"].size
1133     hash["AudioList"].each do |audioTrack|
1134       audioCount = audioCount - 1
1136       #Bitrates
1137       audioBitrates << audioTrack["AudioBitrate"]
1139       #Encoders
1140       case audioTrack["AudioEncoder"]
1141         when /AC3 Pass/
1142           audioEncoders << "copy:ac3"
1143         when /AC3/
1144           audioEncoders << "ac3"
1145         when /DTS Pass/
1146           audioEncoders << "copy:dts"
1147         when /DTS-HD Pass/
1148           audioEncoders << "copy:dtshd"
1149         when /AAC Pass/
1150           audioEncoders << "copy:aac"
1151         when "AAC (ffmpeg)", "AAC (avcodec)", "AAC (faac)"
1152           audioEncoders << "av_aac"
1153         when "AAC (FDK)"
1154           audioEncoders << "fdk_aac"
1155         when "HE-AAC (FDK)"
1156           audioEncoders << "fdk_haac"
1157         when "AAC (CoreAudio)"
1158           audioEncoders << "ca_aac"
1159         when "HE-AAC (CoreAudio)"
1160           audioEncoders << "ca_haac"
1161         when /Vorbis/
1162           audioEncoders << "vorbis"
1163         when /MP3 Pass/
1164           audioEncoders << "copy:mp3"
1165         when /MP3/
1166           audioEncoders << "mp3"
1167         when "FLAC (ffmpeg)", "FLAC 16-bit"
1168           audioEncoders << "flac16"
1169         when "FLAC (24-bit)", "FLAC 24-bit"
1170           audioEncoders << "flac24"
1171         when /Auto Pass/
1172           audioEncoders << "copy"
1173       end
1175       #Mixdowns
1176       case audioTrack["AudioMixdown"]
1177         when "Mono (Left Only)"
1178           audioMixdowns << "left_only"
1179         when "Mono (Right Only)"
1180           audioMixdowns << "right_only"
1181         when /Mono/
1182           audioMixdowns << "mono"
1183         when /Stereo/
1184           audioMixdowns << "stereo"
1185         when /Dolby Surround/
1186           audioMixdowns << "dpl1"
1187         when /Dolby Pro Logic II/
1188           audioMixdowns << "dpl2"
1189         when /5.1/, /discrete/
1190           audioMixdowns << "5point1"
1191         when /6.1/
1192           audioMixdowns << "6point1"
1193         when "7.1 (5F/2R/LFE)"
1194           audioMixdowns << "5_2_lfe"
1195         when /7.1/
1196           audioMixdowns << "7point1"
1197         when /None/
1198           audioMixdowns << "none"
1199       end
1201       #Samplerates
1202       audioSamplerates << audioTrack["AudioSamplerate"]
1204       #Tracks
1205       audioTracks << audioTrack["AudioTrack"].to_s
1207       #DRC
1208       audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
1210       if audioCount > 0
1211         audioBitrates << ","
1212         audioEncoders << ","
1213         audioMixdowns << ","
1214         audioSamplerates << ","
1215         audioTracks << ","
1216         audioTrackDRCs << ","
1217       end
1219     end
1220     commandString << "if( !atracks )\n    "
1221     commandString << "{\n    "
1222     commandString << "    atracks = strdup(\"" << audioTracks
1223     commandString << "\");\n    "
1224     commandString << "}\n    "
1226     commandString << "if( !acodecs )\n    "
1227     commandString << "{\n    "
1228     commandString << "    acodecs = strdup(\"" << audioEncoders
1229     commandString << "\");\n    "
1230     commandString << "}\n    "
1232     commandString << "if( !abitrates )\n    "
1233     commandString << "{\n    "
1234     commandString << "    abitrates = str_split(\"" << audioBitrates
1235     commandString << "\", ',');\n    "
1236     commandString << "}\n    "
1238     commandString << "if( !mixdowns )\n    "
1239     commandString << "{\n    "
1240     commandString << "    mixdowns = strdup(\"" << audioMixdowns
1241     commandString << "\");\n    "
1242     commandString << "}\n    "
1244     commandString << "if( !arates )\n    "
1245     commandString << "{\n    "
1246     commandString << "    arates = strdup(\"" << audioSamplerates
1247     commandString << "\");\n    "
1248     commandString << "}\n    "
1250     commandString << "if( !dynamic_range_compression )\n    "
1251     commandString << "{\n    "
1252     commandString << "    dynamic_range_compression = strdup(\"" << audioTrackDRCs
1253     commandString << "\");\n    "
1254     commandString << "}\n    "
1255     
1256     #Auto Passthru Mask
1257     if hash["AudioAllowAACPass"]
1258       commandString << "if( allowed_audio_copy == -1 )\n    "
1259       commandString << "{\n    "
1260       commandString << "    allowed_audio_copy = 0;\n    "
1261       if hash["AudioAllowAACPass"].to_i == 1
1262         commandString << "    allowed_audio_copy |= HB_ACODEC_AAC_PASS;\n    "
1263       end
1264       if hash["AudioAllowAC3Pass"].to_i == 1
1265         commandString << "    allowed_audio_copy |= HB_ACODEC_AC3_PASS;\n    "
1266       end
1267       if hash["AudioAllowDTSHDPass"].to_i == 1
1268         commandString << "    allowed_audio_copy |= HB_ACODEC_DCA_HD_PASS;\n    "
1269       end
1270       if hash["AudioAllowDTSPass"].to_i == 1
1271         commandString << "    allowed_audio_copy |= HB_ACODEC_DCA_PASS;\n    "
1272       end
1273       if hash["AudioAllowMP3Pass"].to_i == 1
1274         commandString << "    allowed_audio_copy |= HB_ACODEC_MP3_PASS;\n    "
1275       end
1276       commandString << "    allowed_audio_copy &= HB_ACODEC_PASS_MASK;\n    "
1277       commandString << "}\n    "
1278     end
1279     
1280     #Auto Passthru Fallback
1281     audioEncoderFallback = ""
1282     
1283     case hash["AudioEncoderFallback"]
1284       when /AC3/
1285         audioEncoderFallback << "ac3"
1286       when "AAC (ffmpeg)", "AAC (avcodec)", "AAC (faac)"
1287         audioEncoderFallback << "av_aac"
1288       when "AAC (FDK)"
1289         audioEncoderFallback << "fdk_aac"
1290       when "HE-AAC (FDK)"
1291         audioEncoderFallback << "fdk_haac"
1292       when "AAC (CoreAudio)"
1293         audioEncoderFallback << "ca_aac"
1294       when "HE-AAC (CoreAudio)"
1295         audioEncoderFallback << "ca_haac"
1296       when /Vorbis/
1297         audioEncoderFallback << "vorbis"
1298       when /MP3/
1299         audioEncoderFallback << "mp3"
1300       when "FLAC (ffmpeg)", "FLAC 16-bit"
1301         audioEncoderFallback << "flac16"
1302       when "FLAC (24-bit)", "FLAC 24-bit"
1303         audioEncoderFallback << "flac24"
1304     end
1305     
1306     if audioEncoderFallback.size > 0
1307       commandString << "if( acodec_fallback == NULL )\n    "
1308       commandString << "{\n    "
1309       commandString << "    acodec_fallback = \"" << audioEncoderFallback << "\";\n    "
1310       commandString << "}\n    "
1311     end
1312     
1313     #Cropping
1314     if hash["PictureAutoCrop"] == 0
1315       commandString << "job->crop[0] = " << hash["PictureTopCrop"].to_s << ";\n    "
1316       commandString << "job->crop[1] = " << hash["PictureBottomCrop"].to_s << ";\n    "
1317       commandString << "job->crop[2] = " << hash["PictureLeftCrop"].to_s << ";\n    "
1318       commandString << "job->crop[4] = " << hash["PictureRightCrop"].to_s << ";\n    "
1319     end
1320     
1321     #Dimensions
1322     if hash["PictureWidth"] != 0
1323       commandString << "maxWidth = "
1324       commandString << hash["PictureWidth"].to_s << ";\n    "
1325     end
1326     if hash["PictureHeight"] != 0
1327       commandString << "maxHeight = "
1328       commandString << hash["PictureHeight"].to_s << ";\n    "
1329     end
1330     
1331     #Subtitles
1332     if hash["Subtitles"] != "None"
1333       if hash["Subtitles"] == "Autoselect"
1334         commandString << "subtitle_scan = 1;\n    "
1335       else
1336         commandString << "job->subtitle = "
1337         commandString << ( hash["Subtitles"].to_i - 1).to_s << ";\n    "
1338       end
1339     end
1340     
1341     #Advanced Options
1342     if hash["x264UseAdvancedOptions"] != 1
1343       if hash["x264Preset"] != ""
1344         commandString << "if (x264_preset == NULL)\n    "
1345         commandString << "{\n    "
1346         commandString << "    x264_preset = strdup(\""
1347         commandString << hash["x264Preset"] << "\");\n    "
1348         commandString << "}\n    "
1349       end
1350       if hash["x264Tune"] != "" && hash["x264Tune"] != "none"
1351         commandString << "if (x264_tune == NULL)\n    "
1352         commandString << "{\n    "
1353         commandString << "    x264_tune = strdup(\""
1354         commandString << hash["x264Tune"]
1355         commandString << "\");\n    "
1356         commandString << "}\n    "
1357       end
1358       if hash["h264Profile"] != "" && hash["h264Profile"] != "auto"
1359         commandString << "if (h264_profile == NULL)\n    "
1360         commandString << "{\n    "
1361         commandString << "    h264_profile = strdup(\""
1362         commandString << hash["h264Profile"] << "\");\n    "
1363         commandString << "}\n    "
1364       end
1365       if hash["h264Level"] != "" && hash["h264Level"] != "auto"
1366         commandString << "if (h264_level == NULL)\n    "
1367         commandString << "{\n    "
1368         commandString << "    h264_level = strdup(\""
1369         commandString << hash["h264Level"] << "\");\n    "
1370         commandString << "}\n    "
1371       end
1372       if hash["x264OptionExtra"] != ""
1373         commandString << "if (advanced_opts == NULL)\n    "
1374         commandString << "{\n    "
1375         commandString << "    advanced_opts = strdup(\""
1376         commandString << hash["x264OptionExtra"] << "\");\n    "
1377         commandString << "}\n    "
1378       end
1379     elsif hash["x264Option"] != ""
1380       commandString << "if (advanced_opts == NULL)\n    "
1381       commandString << "{\n    "
1382       commandString << "    advanced_opts = strdup(\""
1383       commandString << hash["x264Option"] << "\");\n    "
1384       commandString << "}\n    "
1385     end
1386     
1387     #Video Filters
1388     if hash["UsesPictureFilters"] == 1
1389       
1390       if hash["PictureDeinterlace"].to_i != 0
1391         commandString << "deinterlace = 1;\n    "
1392       end
1394       case hash["PictureDeinterlace"]
1395       when 1
1396         commandString << "deinterlace_opt = \"" << hash["PictureDeinterlaceCustom"].to_s << "\";\n    "
1397       when 2
1398         commandString << "deinterlace_opt = \"0\";\n    "
1399       when 3
1400         commandString << "deinterlace_opt = \"1\";\n    "
1401       when 4
1402         commandString << "deinterlace_opt = \"3\";\n    "
1403       when 5
1404         commandString << "deinterlace_opt = \"15\";\n    "
1405       end
1406       
1407       if hash["PictureDenoise"].to_i != 0
1408         commandString << "denoise = 1;\n    "
1409       end
1411       case hash["PictureDenoise"]
1412       when 1
1413         commandString << "denoise_opt = \"" << hash["PictureDenoiseCustom"].to_s << "\";\n    "
1414       when 2
1415         commandString << "denoise_opt = \"2:1:1:2:3:3\";\n    "
1416       when 3
1417         commandString << "denoise_opt = \"3:2:2:2:3:3\";\n    "
1418       when 4
1419         commandString << "denoise_opt = \"7:7:7:5:5:5\";\n    "
1420       end
1421       
1422       if hash["PictureDecomb"].to_i != 0
1423         commandString << "decomb = 1;\n    "
1424       end
1426       case hash["PictureDecomb"]
1427       when 1
1428         commandString << "decomb_opt = \"" << hash["PictureDecombCustom"].to_s << "\";\n    "
1429       when 3
1430         commandString << "decomb_opt = \"7:2:6:9:1:80\";\n    "
1431       when 4
1432         commandString << "decomb_opt = \"455\";\n    "
1433       end
1435       if hash["PictureDetelecine"].to_i != 0
1436         commandString << "detelecine = 1;\n    "
1437       end
1439       case hash["PictureDetelecine"]
1440         when 1
1441           commandString << "detelecine_opt = \"" << hash["PictureDetelecineCustom"].to_s << "\";\n    "
1442       end
1444       if hash["PictureDeblock"] != 0
1445         commandString << "deblock = 1;\n    "
1446         commandString << "deblock_opt = \"" << hash["PictureDeblock"].to_s << "\";\n    "
1447       end
1448       
1449     end
1450     
1451     #Anamorphic
1452     if hash["PicturePAR"] != 0
1453       commandString << "if( !anamorphic_mode )\n    "
1454       commandString << "{\n    "
1455       if hash["PicturePAR"] == 1
1456         commandString << "    anamorphic_mode = 1;\n    "
1457       elsif hash["PicturePAR"] == 2
1458         commandString << "    anamorphic_mode = 2;\n    "
1459       elsif hash["PicturePAR"] == 3
1460         commandString << "    anamorphic_mode = 3;\n    "
1461       end
1462       commandString << "}\n    "
1463     end
1464     
1465     #Modulus
1466     if hash["PictureModulus"]
1467       commandString << "modulus = " << hash["PictureModulus"].to_s << ";\n    "
1468     end
1470     #Booleans
1471     if hash["ChapterMarkers"] == 1
1472       commandString << "job->chapter_markers = 1;\n    "
1473     end
1475     if hash["VideoGrayScale"] == 1
1476       commandString << "job->grayscale = 1;\n    "
1477     end
1479     if hash["VideoTwoPass"] == 1
1480       commandString << "twoPass = 1;\n    "
1481     end
1483     if hash["VideoTurboTwoPass"] == 1
1484       commandString << "turbo_opts_enabled = 1;\n    "
1485     end
1487     #Finish
1488     commandString = commandString.rstrip
1489     commandString << "\n}"
1491     # That's it, print to screen now
1492     puts commandString
1493   end
1494   
1495   def generateAPIFolderList( hash, depth )
1496     commandString = ""
1497     
1498     commandString << "    printf(\"\\n"
1499     depth.times do
1500       commandString << "   "
1501     end
1502     (depth+1).times do
1503       commandString << "<"
1504     end
1505     commandString << " " << hash["PresetName"]
1506     commandString << "\\n\");\n"    
1507     puts commandString
1508   end
1509   
1510   def generateAPIFolderCloserList( depth )
1511     commandString = ""
1512     
1513     commandString << "    printf(\"\\n"
1514     depth.times do
1515       commandString << "   "
1516     end
1517     (depth+1).times do
1518       commandString << ">"
1519     end
1520     commandString << "\\n\");\n"
1521     puts commandString
1522   end
1523   
1524   def generateAPIList(hash, depth) # Makes a list of the CLI options a built-in CLI preset uses, for wrappers to parse
1525     commandString = ""
1526     commandString << "    printf(\"\\n"
1527     depth.times do
1528       commandString << "   "
1529     end
1530            
1531     commandString << "+ " << hash["PresetName"] << ": "
1532         
1533     #Video encoder
1534     commandString << " -e "
1535     case hash["VideoEncoder"]
1536     when /x264/
1537       commandString << "x264 "
1538     when /Theora/
1539       commandString << "theora "
1540     when /MPEG-4/
1541       commandString << "ffmpeg4 "
1542     when /MPEG-2/
1543       commandString << "ffmpeg2 "
1544     end
1546     #VideoRateControl
1547     case hash["VideoQualityType"]
1548     when 0
1549       commandString << " -S " << hash["VideoTargetSize"]
1550     when 1
1551       commandString << " -b " << hash["VideoAvgBitrate"]
1552     when 2
1553       commandString << " -q " << hash["VideoQualitySlider"].to_s
1554     end
1556     #FPS
1557     if hash["VideoFramerate"] != "Same as source"
1558       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
1559         commandString << " -r " << "23.976"
1560       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
1561         commandString << " -r " << "29.97"
1562       elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
1563         commandString << " -r " << "25"
1564       else
1565         commandString << " -r " << hash["VideoFramerate"]
1566       end
1567       # not same as source: pfr, else default (cfr)
1568       if hash["VideoFramerateMode"] == "pfr"
1569         commandString << " --pfr "
1570       end
1571     # same as source: cfr, else default (vfr)
1572     elsif hash["VideoFramerateMode"] == "cfr"
1573       commandString << " --cfr "
1574     end
1575     
1576     #Audio tracks
1577     audioBitrates = ""
1578     audioEncoders = ""
1579     audioMixdowns = ""
1580     audioSamplerates = ""
1581     audioTracks = ""
1582     audioTrackDRCs = ""
1583     audioCount = hash["AudioList"].size
1584     
1585     hash["AudioList"].each do |audioTrack|
1586       audioCount = audioCount - 1
1588       #Bitrates
1589       audioBitrates << audioTrack["AudioBitrate"]
1590       
1591       #Encoders
1592       case audioTrack["AudioEncoder"]
1593         when /AC3 Pass/
1594           audioEncoders << "copy:ac3"
1595         when /AC3/
1596           audioEncoders << "ac3"
1597         when /DTS Pass/
1598           audioEncoders << "copy:dts"
1599         when /DTS-HD Pass/
1600           audioEncoders << "copy:dtshd"
1601         when /AAC Pass/
1602           audioEncoders << "copy:aac"
1603         when "AAC (ffmpeg)", "AAC (avcodec)", "AAC (faac)"
1604           audioEncoders << "av_aac"
1605         when "AAC (FDK)"
1606           audioEncoders << "fdk_aac"
1607         when "HE-AAC (FDK)"
1608           audioEncoders << "fdk_haac"
1609         when "AAC (CoreAudio)"
1610           audioEncoders << "ca_aac"
1611         when "HE-AAC (CoreAudio)"
1612           audioEncoders << "ca_haac"
1613         when /Vorbis/
1614           audioEncoders << "vorbis"
1615         when /MP3 Pass/
1616           audioEncoders << "copy:mp3"
1617         when /MP3/
1618           audioEncoders << "mp3"
1619         when "FLAC (ffmpeg)", "FLAC 16-bit"
1620           audioEncoders << "flac16"
1621         when "FLAC (24-bit)", "FLAC 24-bit"
1622           audioEncoders << "flac24"
1623         when /Auto Pass/
1624           audioEncoders << "copy"
1625       end
1626       
1627       #Mixdowns
1628       case audioTrack["AudioMixdown"]
1629         when "Mono (Left Only)"
1630           audioMixdowns << "left_only"
1631         when "Mono (Right Only)"
1632           audioMixdowns << "right_only"
1633         when /Mono/
1634           audioMixdowns << "mono"
1635         when /Stereo/
1636           audioMixdowns << "stereo"
1637         when /Dolby Surround/
1638           audioMixdowns << "dpl1"
1639         when /Dolby Pro Logic II/
1640           audioMixdowns << "dpl2"
1641         when /5.1/, /discrete/
1642           audioMixdowns << "5point1"
1643         when /6.1/
1644           audioMixdowns << "6point1"
1645         when "7.1 (5F/2R/LFE)"
1646           audioMixdowns << "5_2_lfe"
1647         when /7.1/
1648           audioMixdowns << "7point1"
1649         when /None/
1650           audioMixdowns << "none"
1651       end
1652       
1653       #Samplerates
1654       audioSamplerates << audioTrack["AudioSamplerate"]
1655       
1656       #Tracks
1657       audioTracks << audioTrack["AudioTrack"].to_s
1658       
1659       #DRC
1660       audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
1661       
1662       if audioCount > 0
1663         audioBitrates << ","
1664         audioEncoders << ","
1665         audioMixdowns << ","
1666         audioSamplerates << ","
1667         audioTracks << ","
1668         audioTrackDRCs << ","
1669       end
1670       
1671     end
1672     commandString << " -a " << audioTracks
1673     commandString << " -E " << audioEncoders
1674     commandString << " -B " << audioBitrates
1675     commandString << " -6 " << audioMixdowns
1676     commandString << " -R " << audioSamplerates
1677     commandString << " -D " << audioTrackDRCs
1678     
1679     #Auto Passthru Mask
1680     audioCopyMask = ""
1681     
1682     if hash["AudioAllowAACPass"].to_i == 1
1683       audioCopyMask << "aac"
1684     end
1685     if hash["AudioAllowAC3Pass"].to_i == 1
1686       if audioCopyMask.size > 0
1687         audioCopyMask << ","
1688       end
1689       audioCopyMask << "ac3"
1690     end
1691     if hash["AudioAllowDTSHDPass"].to_i == 1
1692       if audioCopyMask.size > 0
1693         audioCopyMask << ","
1694       end
1695       audioCopyMask << "dtshd"
1696     end
1697     if hash["AudioAllowDTSPass"].to_i == 1
1698       if audioCopyMask.size > 0
1699         audioCopyMask << ","
1700       end
1701       audioCopyMask << "dts"
1702     end
1703     if hash["AudioAllowMP3Pass"].to_i == 1
1704       if audioCopyMask.size > 0
1705         audioCopyMask << ","
1706       end
1707       audioCopyMask << "mp3"
1708     end
1709     
1710     if audioCopyMask.size > 0
1711       commandString << " --audio-copy-mask " << audioCopyMask
1712     end
1713     
1714     #Auto Passthru Fallback
1715     audioEncoderFallback = ""
1716     
1717     case hash["AudioEncoderFallback"]
1718       when /AC3/
1719         audioEncoderFallback << "ac3"
1720       when "AAC (ffmpeg)", "AAC (avcodec)", "AAC (faac)"
1721         audioEncoderFallback << "av_aac"
1722       when "AAC (FDK)"
1723         audioEncoderFallback << "fdk_aac"
1724       when "HE-AAC (FDK)"
1725         audioEncoderFallback << "fdk_haac"
1726       when "AAC (CoreAudio)"
1727         audioEncoderFallback << "ca_aac"
1728       when "HE-AAC (CoreAudio)"
1729         audioEncoderFallback << "ca_haac"
1730       when /Vorbis/
1731         audioEncoderFallback << "vorbis"
1732       when /MP3/
1733         audioEncoderFallback << "mp3"
1734       when "FLAC (ffmpeg)", "FLAC 16-bit"
1735         audioEncoderFallback << "flac16"
1736       when "FLAC (24-bit)", "FLAC 24-bit"
1737         audioEncoderFallback << "flac24"
1738     end
1739     
1740     if audioEncoderFallback.size > 0
1741       commandString << " --audio-fallback " << audioEncoderFallback
1742     end
1743     
1744     #Container
1745     commandString << " -f "
1746     case hash["FileFormat"]
1747     when "MPEG-4 (mp4v2)"
1748       commandString << "mp4v2"
1749     when /MP4/
1750       commandString << "mp4"
1751     when "Matroska (libmkv)"
1752       commandString << "libmkv"
1753     when /MKV/
1754       commandString << "mkv"
1755     end
1756     
1757     #iPod MP4 atom
1758     if hash["Mp4iPodCompatible"].to_i == 1
1759       commandString << " -I"
1760     end
1761     
1762     #MP4 Optimize for HTTP Streaming
1763     if hash["Mp4HttpOptimize"].to_i == 1
1764       commandString << " -O"
1765     end
1766     
1767     #Cropping
1768     if hash["PictureAutoCrop"] == 0
1769       commandString << " --crop "
1770       commandString << hash["PictureTopCrop"].to_s
1771       commandString << ":"
1772       commandString << hash["PictureBottomCrop"].to_s
1773       commandString << ":"
1774       commandString << hash["PictureLeftCrop"].to_s
1775       commandString << ":"
1776       commandString << hash["PictureRightCrop"].to_s
1777     end
1778     
1779     #Dimensions
1780     if hash["PictureWidth"] != 0
1781       commandString << " -X "
1782       commandString << hash["PictureWidth"].to_s
1783     end
1784     if hash["PictureHeight"] != 0
1785       commandString << " -Y "
1786       commandString << hash["PictureHeight"].to_s
1787     end
1788     
1789     #Subtitles
1790     if hash["Subtitles"] && hash["Subtitles"] != "None"
1791       if hash["Subtitles"] == "Autoselect"
1792         commandString << " --subtitle-scan"
1793       else
1794         commandString << " -s "
1795         commandString << hash["Subtitles"]
1796       end
1797     end
1798     
1799     #Video Filters
1800     if hash["UsesPictureFilters"] == 1
1801       
1802       case hash["PictureDeinterlace"]
1803       when 1
1804         commandString << " --deinterlace=" << hash["PictureDeinterlaceCustom"].to_s
1805       when 2
1806         commandString << " --deinterlace=fast"
1807       when 3
1808         commandString << " --deinterlace=slow"
1809       when 4
1810         commandString << " --deinterlace=slower"
1811       when 5
1812         commandString << " --deinterlace=bob"
1813       end
1814       
1815       case hash["PictureDenoise"]
1816       when 1
1817         commandString << " --denoise=" << hash["PictureDenoiseCustom"].to_s
1818       when 2
1819         commandString << " --denoise=weak"
1820       when 3
1821         commandString << " --denoise=medium"
1822       when 4
1823         commandString << " --denoise=strong"
1824       end
1825       
1826       case hash["PictureDecomb"]
1827       when 1
1828         commandString << " --decomb=" << hash["PictureDecombCustom"].to_s
1829       when 2
1830         commandString << " --decomb"
1831       when 3
1832         commandString << " --decomb=fast"
1833       when 4
1834         commandString << " --decomb=bob"
1835       end
1837       case hash["PictureDetelecine"]
1838         when 1
1839           commandString << " --detelecine=" << hash["PictureDetelecineCustom"].to_s
1840         when 2
1841           commandString << " --detelecine"
1842       end
1844       if hash["PictureDeblock"] != 0
1845         commandString << " --deblock=" << hash["PictureDeblock"].to_s
1846       end
1848     end
1849     
1850     #Anamorphic
1851     if hash["PicturePAR"] == 1
1852       commandString << " --strict-anamorphic"
1853     elsif hash["PicturePAR"] == 2
1854       commandString << " --loose-anamorphic"
1855     elsif hash["PicturePAR"] == 3
1856       commandString << " --custom-anamorphic"
1857     end
1858     
1859     #Modulus
1860     if hash["PictureModulus"]
1861       commandString << " --modulus " << hash["PictureModulus"].to_s
1862     end
1864     #Booleans
1865     if hash["ChapterMarkers"] == 1 then commandString << " -m" end
1866     if hash["VideoGrayScale"] == 1 then commandString << " -g" end
1867     if hash["VideoTwoPass"] == 1 then commandString << " -2" end
1868     if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
1869     
1870     #Advanced Options
1871     if hash["x264UseAdvancedOptions"] != 1
1872       if hash["x264Preset"] != ""
1873         commandString << " --x264-preset "
1874         commandString << hash["x264Preset"]
1875       end
1876       if hash["x264Tune"] != "" && hash["x264Tune"] != "none"
1877         commandString << " --x264-tune "
1878         commandString << hash["x264Tune"]
1879       end
1880       if hash["h264Profile"] != "" && hash["h264Profile"] != "auto"
1881         commandString << " --h264-profile "
1882         commandString << hash["h264Profile"]
1883       end
1884       if hash["h264Level"] != "" && hash["h264Level"] != "auto"
1885         commandString << " --h264-level "
1886         commandString << hash["h264Level"]
1887       end
1888       if hash["x264OptionExtra"] != ""
1889         commandString << " -x "
1890         commandString << hash["x264OptionExtra"]
1891       end
1892     elsif hash["x264Option"] != ""
1893       commandString << " -x "
1894       commandString << hash["x264Option"]
1895     end
1896     
1897     commandString << "\\n\");"
1898     
1899     # That's it, print to screen now
1900     puts commandString
1901   end
1902   
1905 # CLI invocation only
1906 if __FILE__ == $0
1908   # First grab the specified CLI options
1909   options = readOptions
1911   # Only run if one of the useful CLI flags have been passed
1912   if options.cliraw == true || options.cliparse == true || options.api == true || options.apilist == true
1913     # This line is the ignition -- generates hashes of
1914     # presets and then displays them to the screen
1915     # with the options the user selects on the CLI. 
1916     Display.new( Presets.new.hashMasterList, options )
1917   else
1918     # Direct the user to the help
1919     puts "\n\tUsage: manicure.rb [options]"
1920     puts "\tSee help with -h or --help"
1921   end