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
17 # CLI options: (code based on http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/index.html )
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
29 options.apilist = false
30 options.header = false
32 opts = OptionParser.new do |opts|
33 opts.banner = "Usage: manicure.rb [options]"
36 opts.separator "Options:"
38 opts.on("-r", "--cli-raw", "Gives example strings for the HB wiki") do |raw|
43 opts.on("-p", "--cli-parse", "Gives presets as wrapper-parseable CLI", " option strings") do |par|
44 options.cliparse = par
47 opts.on("-a", "--api", "Gives preset code for test.c") do |api|
51 opts.on("-A", "--api-list", "Gives code for test.c's --preset-list", " options") do |alist|
52 options.apilist = alist
55 opts.on("-H", "--Header", "Display a banner before each preset") do |head|
59 opts.on_tail("-h", "--help", "Show this message") do
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.
73 # This class parses the user's presets .plist into an array of hashes
76 attr_reader :hashMasterList
78 # Running initialization runs everything.
79 # Calling it will also call the parser
83 # Grab the user's home path
84 homeLocation = `echo $HOME`.chomp
86 # Use that to build a path to the presets .plist
87 #inputFile = homeLocation+'/Library/Application Support/HandBrake/UserPresets.plist'
88 inputFile = homeLocation+'/UserPresets.plist'
90 # Parse the presets into hashes
91 @hashMasterList = Plist::parse_xml( inputFile )
97 # This class displays the presets to stdout in various formats.
100 def initialize(hashMasterList, options)
102 @hashMasterList = hashMasterList
105 # A width of 40 gives nice, compact output.
109 displayCommandStrings
113 def displayCommandStrings # prints everything to screen
115 # Iterate through the hashes.
116 @hashMasterList.each do |hash|
118 # Check to see whether we've got a preset or afolder
120 # It's a top-level preset
121 displayIndividualPreset(hash, 0)
124 displayFolder( hash, 0 )
125 hash["ChildrenArray"].each do |subhash|
126 # Drill down to see its contents
127 if !subhash["Folder"]
129 displayIndividualPreset(subhash, 1)
132 displayFolder( subhash, 1 )
133 subhash["ChildrenArray"].each do |subsubhash|
134 # At this point we're far enough down we won't try to drill further
135 if !subsubhash["Folder"]
136 displayIndividualPreset(subsubhash, 2)
139 displayFolderCloser( 1 )
142 displayFolderCloser( 0 )
147 def displayIndividualPreset(hash, depth)
148 if @options.header == true
149 # First throw up a header to make each preset distinct
153 if @options.cliraw == true
154 # Show the preset's full CLI string equivalent
155 generateCLIString(hash, depth)
158 if @options.cliparse == true
159 generateCLIParse(hash, depth)
162 if @options.api == true
163 # Show the preset as code for test/test.c, HandBrakeCLI
164 generateAPIcalls(hash)
167 if @options.apilist == true
168 # Show the preset as print statements, for CLI wrappers to parse.
169 generateAPIList(hash, depth)
173 def displayHeader(hash) # A distinct banner to separate each preset
175 # Print a line of asterisks
176 puts "*" * @columnWidth
178 # Print the name, centered
179 puts '* '+hash["PresetName"].to_s.center(@columnWidth-4)+' *'
181 # Print a line of dashes
182 puts '~' * @columnWidth
184 # Print the description, centered and word-wrapped
185 puts hash["PresetDescription"].to_s.center(@columnWidth).gsub(/\n/," ").scan(/\S.{0,#{@columnWidth-2}}\S(?=\s|$)|\S+/)
187 # Print another line of dashes
188 puts '~' * @columnWidth
190 # Print the formats the preset uses
191 puts "#{hash["FileCodecs"]}".center(@columnWidth)
193 # Note if the preset isn't built-in
195 puts "Custom Preset".center(@columnWidth)
198 # Note if the preset is marked as default.
199 if hash["Default"] == 1
200 puts "This is your default preset.".center(@columnWidth)
203 # End with a line of tildes.
204 puts "~" * @columnWidth
208 def displayFolder( hash, depth )
210 if @options.cliraw == true
211 # Show the folder's full in a format that matches the CLI equivalents
212 generateCLIFolderString(hash, depth)
215 if @options.cliparse == true
216 # Show the folder in a format that matches the CLI wrapper equivalents
217 generateCLIFolderParse(hash, depth)
220 if @options.apilist == true
221 # Show the folder as print statements, for CLI wrappers to parse.
222 generateAPIFolderList(hash, depth)
227 def displayFolderCloser( depth )
228 if @options.cliraw == true
229 # Show the folder's full in a format that matches the CLI equivalents
230 generateCLIFolderCloserString( depth )
233 if @options.cliparse == true
234 # Show the folder in a format that matches the CLI wrapper equivalents
235 generateCLIFolderCloserParse( depth )
238 if @options.apilist == true
239 # Show the folder as print statements, for CLI wrappers to parse.
240 generateAPIFolderCloserList( depth )
244 def generateCLIFolderString( hash, depth ) # Shows the folder for the CLI equivalents
252 commandString << " " << hash["PresetName"] << "\n\n"
256 def generateCLIFolderCloserString( depth )
264 commandString << "\n\n"
268 def generateCLIString(hash, depth) # Makes a full CLI equivalent of a preset
273 commandString << './HandBrakeCLI -i DVD -o ~/Movies/movie.'
276 case hash["FileFormat"]
278 commandString << "mp4 "
280 commandString << "mkv "
284 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
285 commandString << " -e "
286 case hash["VideoEncoder"]
288 commandString << "x264"
290 commandString << "theora"
295 case hash["VideoQualityType"]
297 commandString << " -S " << hash["VideoTargetSize"]
299 commandString << " -b " << hash["VideoAvgBitrate"]
301 commandString << " -q " << hash["VideoQualitySlider"].to_s
305 if hash["VideoFramerate"] != "Same as source"
306 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
307 commandString << " -r " << "23.976"
308 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
309 commandString << " -r " << "29.97"
310 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
311 commandString << " -r " << "25"
313 commandString << " -r " << hash["VideoFramerate"]
321 audioSamplerates = ""
324 audioCount = hash["AudioList"].size
326 hash["AudioList"].each do |audioTrack|
327 audioCount = audioCount - 1
330 audioBitrates << audioTrack["AudioBitrate"]
333 case audioTrack["AudioEncoder"]
335 audioEncoders << "ac3"
337 audioEncoders << "faac"
339 audioEncoders << "vorbis"
341 audioEncoders << "lame"
345 case audioTrack["AudioMixdown"]
347 audioMixdowns << "mono"
349 audioMixdowns << "stereo"
350 when /Dolby Surround/
351 audioMixdowns << "dpl1"
352 when /Dolby Pro Logic II/
353 audioMixdowns << "dpl2"
355 audioMixdowns << "6ch"
357 audioMixdowns << "auto"
361 audioSamplerates << audioTrack["AudioSamplerate"]
364 audioTracks << audioTrack["AudioTrack"].to_s
367 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
373 audioSamplerates << ","
375 audioTrackDRCs << ","
379 commandString << " -a " << audioTracks
380 commandString << " -E " << audioEncoders
381 commandString << " -B " << audioBitrates
382 commandString << " -6 " << audioMixdowns
383 commandString << " -R " << audioSamplerates
384 commandString << " -D " << audioTrackDRCs
387 commandString << " -f "
388 case hash["FileFormat"]
390 commandString << "mp4"
392 commandString << "mkv"
396 if hash["Mp4iPodCompatible"].to_i == 1
397 commandString << " -I"
401 if hash["Mp4LargeFile"] == 1
402 commandString << " -4"
406 if hash["PictureAutoCrop"] == 0
407 commandString << " --crop "
408 commandString << hash["PictureTopCrop"].to_s
410 commandString << hash["PictureBottomCrop"].to_s
412 commandString << hash["PictureLeftCrop"].to_s
414 commandString << hash["PictureRightCrop"].to_s
418 if hash["PictureWidth"] != 0
419 commandString << " -X "
420 commandString << hash["PictureWidth"].to_s
422 if hash["PictureHeight"] != 0
423 commandString << " -Y "
424 commandString << hash["PictureHeight"].to_s
428 if hash["Subtitles"] && hash["Subtitles"] != "None"
429 if hash["Subtitles"] == "Autoselect"
430 commandString << " --subtitle-scan"
432 commandString << " -s "
433 commandString << hash["Subtitles"]
438 if hash["UsesPictureFilters"] == 1
440 case hash["PictureDeinterlace"]
442 commandString << " --deinterlace=\"fast\""
444 commandString << " --deinterlace=\slow\""
446 commandString << " --deinterlace=\"slower\""
448 commandString << " --deinterlace=\"slowest\""
451 case hash["PictureDenoise"]
453 commandString << " --denoise=\"weak\""
455 commandString << " --denoise=\"medium\""
457 commandString << " --denoise=\"strong\""
460 if hash["PictureDetelecine"] == 2 then commandString << " --detelecine" end
461 if hash["PictureDeblock"] != 0 then commandString << " --deblock=" << hash["PictureDeblock"].to_s end
462 if hash["PictureDecomb"] == 2 then commandString << " --decomb" end
467 if hash["PicturePAR"] == 1
468 commandString << " --strict-anamorphic"
469 elsif hash["PicturePAR"] == 2
470 commandString << " --loose-anamorphic"
471 elsif hash["PicturePAR"] == 3
472 commandString << " --custom-anamorphic"
476 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
477 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
478 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
479 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
482 if hash["x264Option"] != ""
483 commandString << " -x "
484 commandString << hash["x264Option"]
487 # That's it, print to screen now
490 #puts "*" * @columnWidth
495 def generateCLIFolderParse( hash, depth ) # Shows the folder for wrappers to parse
503 commandString << " " << hash["PresetName"] << "\n\n"
507 def generateCLIFolderCloserParse( depth )
515 commandString << "\n\n"
519 def generateCLIParse(hash, depth) # Makes a CLI equivalent of all user presets, for wrappers to parse
524 commandString << '+ ' << hash["PresetName"] << ":"
527 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
528 commandString << " -e "
529 case hash["VideoEncoder"]
531 commandString << "x264"
533 commandString << "theora"
538 case hash["VideoQualityType"]
540 commandString << " -S " << hash["VideoTargetSize"]
542 commandString << " -b " << hash["VideoAvgBitrate"]
544 commandString << " -q " << hash["VideoQualitySlider"].to_s
548 if hash["VideoFramerate"] != "Same as source"
549 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
550 commandString << " -r " << "23.976"
551 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
552 commandString << " -r " << "29.97"
553 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
554 commandString << " -r " << "25"
556 commandString << " -r " << hash["VideoFramerate"]
564 audioSamplerates = ""
567 audioCount = hash["AudioList"].size
569 hash["AudioList"].each do |audioTrack|
570 audioCount = audioCount - 1
573 audioBitrates << audioTrack["AudioBitrate"]
576 case audioTrack["AudioEncoder"]
578 audioEncoders << "ac3"
580 audioEncoders << "faac"
582 audioEncoders << "vorbis"
584 audioEncoders << "lame"
588 case audioTrack["AudioMixdown"]
590 audioMixdowns << "mono"
592 audioMixdowns << "stereo"
593 when /Dolby Surround/
594 audioMixdowns << "dpl1"
595 when /Dolby Pro Logic II/
596 audioMixdowns << "dpl2"
598 audioMixdowns << "6ch"
600 audioMixdowns << "auto"
604 audioSamplerates << audioTrack["AudioSamplerate"]
607 audioTracks << audioTrack["AudioTrack"].to_s
610 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
616 audioSamplerates << ","
618 audioTrackDRCs << ","
622 commandString << " -a " << audioTracks
623 commandString << " -E " << audioEncoders
624 commandString << " -B " << audioBitrates
625 commandString << " -6 " << audioMixdowns
626 commandString << " -R " << audioSamplerates
627 commandString << " -D " << audioTrackDRCs
630 commandString << " -f "
631 case hash["FileFormat"]
633 commandString << "mp4"
635 commandString << "mkv"
639 if hash["Mp4iPodCompatible"].to_i == 1
640 commandString << " -I"
644 if hash["Mp4LargeFile"] == 1
645 commandString << " -4"
649 if hash["PictureAutoCrop"] == 0
650 commandString << " --crop "
651 commandString << hash["PictureTopCrop"].to_s
653 commandString << hash["PictureBottomCrop"].to_s
655 commandString << hash["PictureLeftCrop"].to_s
657 commandString << hash["PictureRightCrop"].to_s
661 if hash["PictureWidth"] != 0
662 commandString << " -X "
663 commandString << hash["PictureWidth"].to_s
665 if hash["PictureHeight"] != 0
666 commandString << " -Y "
667 commandString << hash["PictureHeight"].to_s
671 if hash["Subtitles"] && hash["Subtitles"] != "None"
672 if hash["Subtitles"] == "Autoselect"
673 commandString << " --subtitle-scan"
675 commandString << " -s "
676 commandString << hash["Subtitles"]
681 if hash["UsesPictureFilters"] == 1
683 case hash["PictureDeinterlace"]
685 commandString << " --deinterlace=\"fast\""
687 commandString << " --deinterlace=\slow\""
689 commandString << " --deinterlace=\"slower\""
691 commandString << " --deinterlace=\"slowest\""
694 case hash["PictureDenoise"]
696 commandString << " --denoise=\"weak\""
698 commandString << " --denoise=\"medium\""
700 commandString << " --denoise=\"strong\""
703 if hash["PictureDetelecine"] == 2 then commandString << " --detelecine" end
704 if hash["PictureDeblock"] != 0 then commandString << " --deblock=" << hash["PictureDeblock"].to_s end
705 if hash["PictureDecomb"] == 2 then commandString << " --decomb" end
709 if hash["PicturePAR"] == 1
710 commandString << " --strict-anamorphic"
711 elsif hash["PicturePAR"] == 2
712 commandString << " --loose-anamorphic"
713 elsif hash["PicturePAR"] == 3
714 commandString << " --custom-anamorphic"
718 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
719 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
720 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
721 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
724 if hash["x264Option"] != ""
725 commandString << " -x "
726 commandString << hash["x264Option"]
729 # That's it, print to screen now
732 #puts "*" * @columnWidth
737 def generateAPIcalls(hash) # Makes a C version of the preset ready for coding into the CLI
739 commandString = "if (!strcmp(preset_name, \"" << hash["PresetName"] << "\"))\n{\n "
742 commandString << "if( !mux )\n "
743 commandString << "{\n "
745 case hash["FileFormat"]
747 commandString << " mux = " << "HB_MUX_MP4;\n "
749 commandString << " mux = " << "HB_MUX_MKV;\n "
751 commandString << "}\n "
754 if hash["Mp4iPodCompatible"].to_i == 1
755 commandString << "job->ipod_atom = 1;\n "
759 if hash["Mp4LargeFile"] == 1
760 commandString << "job->largeFileSize = 1;\n "
764 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
765 commandString << "vcodec = "
766 case hash["VideoEncoder"]
768 commandString << "HB_VCODEC_X264;\n "
770 commandString << "HB_VCODEC_THEORA;\n "
775 case hash["VideoQualityType"]
777 commandString << "size = " << hash["VideoTargetSize"] << ";\n "
779 commandString << "job->vbitrate = " << hash["VideoAvgBitrate"] << ";\n "
781 commandString << "job->vquality = " << hash["VideoQualitySlider"].to_s << ";\n "
785 if hash["VideoFramerate"] != "Same as source"
786 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
787 commandString << "job->vrate_base = " << "1126125;\n "
788 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
789 commandString << "job->vrate_base = " << "900900;\n "
790 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
791 commandString << "job->vrate_base = " << "1080000\n "
792 # Gotta add the rest of the framerates for completion's sake.
794 commandString << "job->cfr = 1;\n "
801 audioSamplerates = ""
804 audioCount = hash["AudioList"].size
806 hash["AudioList"].each do |audioTrack|
807 audioCount = audioCount - 1
810 audioBitrates << audioTrack["AudioBitrate"]
813 case audioTrack["AudioEncoder"]
815 audioEncoders << "ac3"
817 audioEncoders << "faac"
819 audioEncoders << "vorbis"
821 audioEncoders << "lame"
825 case audioTrack["AudioMixdown"]
827 audioMixdowns << "mono"
829 audioMixdowns << "stereo"
830 when /Dolby Surround/
831 audioMixdowns << "dpl1"
832 when /Dolby Pro Logic II/
833 audioMixdowns << "dpl2"
835 audioMixdowns << "6ch"
837 audioMixdowns << "auto"
841 audioSamplerates << audioTrack["AudioSamplerate"]
844 audioTracks << audioTrack["AudioTrack"].to_s
847 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
853 audioSamplerates << ","
855 audioTrackDRCs << ","
859 commandString << "if( !atracks )\n "
860 commandString << "{\n "
861 commandString << " atracks = strdup(\"" << audioTracks
862 commandString << "\");\n "
863 commandString << "}\n "
865 commandString << "if( !acodecs )\n "
866 commandString << "{\n "
867 commandString << " acodecs = strdup(\"" << audioEncoders
868 commandString << "\");\n "
869 commandString << "}\n "
871 commandString << "if( !abitrates )\n "
872 commandString << "{\n "
873 commandString << " abitrates = strdup(\"" << audioBitrates
874 commandString << "\");\n "
875 commandString << "}\n "
877 commandString << "if( !mixdowns )\n "
878 commandString << "{\n "
879 commandString << " mixdowns = strdup(\"" << audioMixdowns
880 commandString << "\");\n "
881 commandString << "}\n "
883 commandString << "if( !arates )\n "
884 commandString << "{\n "
885 commandString << " arates = strdup(\"" << audioSamplerates
886 commandString << "\");\n "
887 commandString << "}\n "
889 commandString << "if( !dynamic_range_compression )\n "
890 commandString << "{\n "
891 commandString << " dynamic_range_compression = strdup(\"" << audioTrackDRCs
892 commandString << "\");\n "
893 commandString << "}\n "
896 if hash["PictureAutoCrop"] == 0
897 commandString << "job->crop[0] = " << hash["PictureTopCrop"].to_s << ";\n "
898 commandString << "job->crop[1] = " << hash["PictureBottomCrop"].to_s << ";\n "
899 commandString << "job->crop[2] = " << hash["PictureLeftCrop"].to_s << ";\n "
900 commandString << "job->crop[4] = " << hash["PictureRightCrop"].to_s << ";\n "
904 if hash["PictureWidth"] != 0
905 commandString << "maxWidth = "
906 commandString << hash["PictureWidth"].to_s << ";\n "
908 if hash["PictureHeight"] != 0
909 commandString << "maxHeight = "
910 commandString << hash["PictureHeight"].to_s << ";\n "
914 if hash["Subtitles"] != "None"
915 if hash["Subtitles"] == "Autoselect"
916 commandString << "subtitle_scan = 1;\n "
918 commandString << "job->subtitle = "
919 commandString << ( hash["Subtitles"].to_i - 1).to_s << ";\n "
924 if hash["x264Option"] != ""
925 commandString << "if( !x264opts )\n "
926 commandString << "{\n "
927 commandString << " x264opts = strdup(\""
928 commandString << hash["x264Option"] << "\");\n "
929 commandString << "}\n "
933 if hash["UsesPictureFilters"] == 1
935 case hash["PictureDeinterlace"]
937 commandString << "deinterlace = 1;\n "
938 commandString << "deinterlace_opt = \"-1\";\n "
940 commandString << "deinterlace = 1;\n "
941 commandString << "deinterlace_opt = \"2\";\n "
943 commandString << "deinterlace = 1;\n "
944 commandString << "deinterlace_opt = \"0\";\n "
946 commandString << "deinterlace = 1;\n "
947 commandString << "deinterlace_opt = \"1:-1:1\";\n "
950 case hash["PictureDenoise"]
952 commandString << "denoise = 1;\n "
953 commandString << "denoise_opt = \"2:1:2:3\";\n "
955 commandString << "denoise = 1;\n "
956 commandString << "denoise_opt = \"3:2:2:3\";\n "
958 commandString << "denoise = 1;\n "
959 commandString << "denoise_opt = \"7:7:5:5\";\n "
962 if hash["PictureDetelecine"] == 2 then commandString << "detelecine = 1;\n " end
963 if hash["PictureDeblock"] != 0
965 commandString << "deblock = 1;\n "
966 commandString << "deblock_opt = \"" << hash["PictureDeblock"].to_s << "\";\n "
968 if hash["PictureDecomb"] == 2 then commandString << "decomb = 1;\n " end
973 if hash["PicturePAR"] != 0
974 commandString << "if( !anamorphic_mode )\n "
975 commandString << "{\n "
976 if hash["PicturePAR"] == 1
977 commandString << " anamorphic_mode = 1;\n "
978 elsif hash["PicturePAR"] == 2
979 commandString << " anamorphic_mode = 2;\n "
980 elsif hash["PicturePAR"] == 3
981 commandString << " anamorphic_mode = 3;\n "
983 commandString << "}\n "
987 if hash["ChapterMarkers"] == 1 then commandString << "job->chapter_markers = 1;\n " end
988 if hash["VideoGrayScale"] == 1 then commandString << "job->grayscale = 1;\n " end
989 if hash["VideoTwoPass"] == 1 then commandString << "twoPass = 1;\n " end
990 if hash["VideoTurboTwoPass"] == 1 then commandString << "turbo_opts_enabled = 1;\n" end
991 commandString << "\n"
994 # That's it, print to screen now
996 #puts "*" * @columnWidth
1000 def generateAPIFolderList( hash, depth )
1003 commandString << " printf(\"\\n"
1005 commandString << " "
1008 commandString << "<"
1010 commandString << " " << hash["PresetName"]
1011 commandString << "\\n\");\n\n"
1015 def generateAPIFolderCloserList( depth )
1018 commandString << " printf(\"\\n"
1020 commandString << " "
1023 commandString << ">"
1025 commandString << "\\n\");\n\n"
1029 def generateAPIList(hash, depth) # Makes a list of the CLI options a built-in CLI preset uses, for wrappers to parse
1031 commandString << " printf(\"\\n"
1033 commandString << " "
1036 commandString << "+ " << hash["PresetName"] << ": "
1039 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
1040 commandString << " -e "
1041 case hash["VideoEncoder"]
1043 commandString << "x264 "
1045 commandString << "theora "
1050 case hash["VideoQualityType"]
1052 commandString << " -S " << hash["VideoTargetSize"]
1054 commandString << " -b " << hash["VideoAvgBitrate"]
1056 commandString << " -q " << hash["VideoQualitySlider"].to_s
1060 if hash["VideoFramerate"] != "Same as source"
1061 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
1062 commandString << " -r " << "23.976"
1063 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
1064 commandString << " -r " << "29.97"
1065 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
1066 commandString << " -r " << "25"
1068 commandString << " -r " << hash["VideoFramerate"]
1076 audioSamplerates = ""
1079 audioCount = hash["AudioList"].size
1081 hash["AudioList"].each do |audioTrack|
1082 audioCount = audioCount - 1
1085 audioBitrates << audioTrack["AudioBitrate"]
1088 case audioTrack["AudioEncoder"]
1090 audioEncoders << "ac3"
1092 audioEncoders << "faac"
1094 audioEncoders << "vorbis"
1096 audioEncoders << "lame"
1100 case audioTrack["AudioMixdown"]
1102 audioMixdowns << "mono"
1104 audioMixdowns << "stereo"
1105 when /Dolby Surround/
1106 audioMixdowns << "dpl1"
1107 when /Dolby Pro Logic II/
1108 audioMixdowns << "dpl2"
1110 audioMixdowns << "6ch"
1112 audioMixdowns << "auto"
1116 audioSamplerates << audioTrack["AudioSamplerate"]
1119 audioTracks << audioTrack["AudioTrack"].to_s
1122 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
1125 audioBitrates << ","
1126 audioEncoders << ","
1127 audioMixdowns << ","
1128 audioSamplerates << ","
1130 audioTrackDRCs << ","
1134 commandString << " -a " << audioTracks
1135 commandString << " -E " << audioEncoders
1136 commandString << " -B " << audioBitrates
1137 commandString << " -6 " << audioMixdowns
1138 commandString << " -R " << audioSamplerates
1139 commandString << " -D " << audioTrackDRCs
1142 commandString << " -f "
1143 case hash["FileFormat"]
1145 commandString << "mp4"
1147 commandString << "mkv"
1151 if hash["Mp4iPodCompatible"].to_i == 1
1152 commandString << " -I"
1156 if hash["Mp4LargeFile"] == 1
1157 commandString << " -4"
1161 if hash["PictureAutoCrop"] == 0
1162 commandString << " --crop "
1163 commandString << hash["PictureTopCrop"].to_s
1164 commandString << ":"
1165 commandString << hash["PictureBottomCrop"].to_s
1166 commandString << ":"
1167 commandString << hash["PictureLeftCrop"].to_s
1168 commandString << ":"
1169 commandString << hash["PictureRightCrop"].to_s
1173 if hash["PictureWidth"] != 0
1174 commandString << " -X "
1175 commandString << hash["PictureWidth"].to_s
1177 if hash["PictureHeight"] != 0
1178 commandString << " -Y "
1179 commandString << hash["PictureHeight"].to_s
1183 if hash["Subtitles"] && hash["Subtitles"] != "None"
1184 if hash["Subtitles"] == "Autoselect"
1185 commandString << " --subtitle-scan"
1187 commandString << " -s "
1188 commandString << hash["Subtitles"]
1193 if hash["UsesPictureFilters"] == 1
1195 case hash["PictureDeinterlace"]
1197 commandString << " --deinterlace=\\\"fast\\\""
1199 commandString << " --deinterlace=\\\slow\\\""
1201 commandString << " --deinterlace=\\\"slower\\\""
1203 commandString << " --deinterlace=\\\"slowest\\\""
1206 case hash["PictureDenoise"]
1208 commandString << " --denoise=\\\"weak\\\""
1210 commandString << " --denoise=\\\"medium\\\""
1212 commandString << " --denoise=\\\"strong\\\""
1215 if hash["PictureDetelecine"] == 2 then commandString << " --detelecine" end
1216 if hash["PictureDeblock"] != 0 then commandString << " --deblock=" << hash["PictureDeblock"].to_s end
1217 if hash["PictureDecomb"] == 2 then commandString << " --decomb" end
1221 if hash["PicturePAR"] == 1
1222 commandString << " --strict-anamorphic"
1223 elsif hash["PicturePAR"] == 2
1224 commandString << " --loose-anamorphic"
1225 elsif hash["PicturePAR"] == 3
1226 commandString << " --custom-anamorphic"
1230 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
1231 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
1232 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
1233 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
1236 if hash["x264Option"] != ""
1237 commandString << " -x "
1238 commandString << hash["x264Option"]
1241 commandString << "\\n\");"
1243 # That's it, print to screen now
1250 # First grab the specified CLI options
1251 options = readOptions
1253 # Only run if one of the useful CLI flags have been passed
1254 if options.cliraw == true || options.cliparse == true || options.api == true || options.apilist == true
1255 # This line is the ignition -- generates hashes of
1256 # presets and then displays them to the screen
1257 # with the options the user selects on the CLI.
1258 Display.new( Presets.new.hashMasterList, options )
1260 # Direct the user to the help
1261 puts "\n\tUsage: manicure.rb [options]"
1262 puts "\tSee help with -h or --help"