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'
89 # Parse the presets into hashes
90 @hashMasterList = Plist::parse_xml( inputFile )
96 # This class displays the presets to stdout in various formats.
99 def initialize(hashMasterList, options)
101 @hashMasterList = hashMasterList
104 # A width of 40 gives nice, compact output.
108 displayCommandStrings
112 def displayCommandStrings # prints everything to screen
114 # Iterate through the hashes.
115 @hashMasterList.each do |hash|
117 # Check to see whether we've got a preset or afolder
119 # It's a top-level preset
120 displayIndividualPreset(hash, 0)
123 displayFolder( hash, 0 )
124 hash["ChildrenArray"].each do |subhash|
125 # Drill down to see its contents
126 if !subhash["Folder"]
128 displayIndividualPreset(subhash, 1)
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)
138 displayFolderCloser( 1 )
141 displayFolderCloser( 0 )
146 def displayIndividualPreset(hash, depth)
147 if @options.header == true
148 # First throw up a header to make each preset distinct
152 if @options.cliraw == true
153 # Show the preset's full CLI string equivalent
154 generateCLIString(hash, depth)
157 if @options.cliparse == true
158 generateCLIParse(hash, depth)
161 if @options.api == true
162 # Show the preset as code for test/test.c, HandBrakeCLI
163 generateAPIcalls(hash)
166 if @options.apilist == true
167 # Show the preset as print statements, for CLI wrappers to parse.
168 generateAPIList(hash, depth)
172 def displayHeader(hash) # A distinct banner to separate each preset
174 # Print a line of asterisks
175 puts "*" * @columnWidth
177 # Print the name, centered
178 puts '* '+hash["PresetName"].to_s.center(@columnWidth-4)+' *'
180 # Print a line of dashes
181 puts '~' * @columnWidth
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+/)
186 # Print another line of dashes
187 puts '~' * @columnWidth
189 # Print the formats the preset uses
190 puts "#{hash["FileCodecs"]}".center(@columnWidth)
192 # Note if the preset isn't built-in
194 puts "Custom Preset".center(@columnWidth)
197 # Note if the preset is marked as default.
198 if hash["Default"] == 1
199 puts "This is your default preset.".center(@columnWidth)
202 # End with a line of tildes.
203 puts "~" * @columnWidth
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)
214 if @options.cliparse == true
215 # Show the folder in a format that matches the CLI wrapper equivalents
216 generateCLIFolderParse(hash, depth)
219 if @options.apilist == true
220 # Show the folder as print statements, for CLI wrappers to parse.
221 generateAPIFolderList(hash, depth)
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 )
232 if @options.cliparse == true
233 # Show the folder in a format that matches the CLI wrapper equivalents
234 generateCLIFolderCloserParse( depth )
237 if @options.apilist == true
238 # Show the folder as print statements, for CLI wrappers to parse.
239 generateAPIFolderCloserList( depth )
243 def generateCLIFolderString( hash, depth ) # Shows the folder for the CLI equivalents
251 commandString << " " << hash["PresetName"] << "\n\n"
255 def generateCLIFolderCloserString( depth )
263 commandString << "\n\n"
267 def generateCLIString(hash, depth) # Makes a full CLI equivalent of a preset
272 commandString << './HandBrakeCLI -i DVD -o ~/Movies/movie.'
275 case hash["FileFormat"]
277 commandString << "mp4 "
279 commandString << "mkv "
283 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
284 commandString << " -e "
285 case hash["VideoEncoder"]
287 commandString << "x264"
289 commandString << "theora"
294 case hash["VideoQualityType"]
296 commandString << " -S " << hash["VideoTargetSize"]
298 commandString << " -b " << hash["VideoAvgBitrate"]
300 commandString << " -q " << hash["VideoQualitySlider"].to_s
304 if hash["VideoFramerate"] != "Same as source"
305 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
306 commandString << " -r " << "23.976"
307 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
308 commandString << " -r " << "29.97"
309 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
310 commandString << " -r " << "25"
312 commandString << " -r " << hash["VideoFramerate"]
320 audioSamplerates = ""
323 audioCount = hash["AudioList"].size
325 hash["AudioList"].each do |audioTrack|
326 audioCount = audioCount - 1
329 audioBitrates << audioTrack["AudioBitrate"]
332 case audioTrack["AudioEncoder"]
334 audioEncoders << "ac3"
336 audioEncoders << "faac"
338 audioEncoders << "vorbis"
340 audioEncoders << "lame"
344 case audioTrack["AudioMixdown"]
346 audioMixdowns << "mono"
348 audioMixdowns << "stereo"
349 when /Dolby Surround/
350 audioMixdowns << "dpl1"
351 when /Dolby Pro Logic II/
352 audioMixdowns << "dpl2"
354 audioMixdowns << "6ch"
356 audioMixdowns << "auto"
360 audioSamplerates << audioTrack["AudioSamplerate"]
363 audioTracks << audioTrack["AudioTrack"].to_s
366 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
372 audioSamplerates << ","
374 audioTrackDRCs << ","
378 commandString << " -a " << audioTracks
379 commandString << " -E " << audioEncoders
380 commandString << " -B " << audioBitrates
381 commandString << " -6 " << audioMixdowns
382 commandString << " -R " << audioSamplerates
383 commandString << " -D " << audioTrackDRCs
386 commandString << " -f "
387 case hash["FileFormat"]
389 commandString << "mp4"
391 commandString << "mkv"
395 if hash["Mp4iPodCompatible"].to_i == 1
396 commandString << " -I"
400 if hash["Mp4LargeFile"] == 1
401 commandString << " -4"
405 if hash["PictureAutoCrop"] == 0
406 commandString << " --crop "
407 commandString << hash["PictureTopCrop"].to_s
409 commandString << hash["PictureBottomCrop"].to_s
411 commandString << hash["PictureLeftCrop"].to_s
413 commandString << hash["PictureRightCrop"].to_s
417 if hash["PictureWidth"] != 0
418 commandString << " -X "
419 commandString << hash["PictureWidth"].to_s
421 if hash["PictureHeight"] != 0
422 commandString << " -Y "
423 commandString << hash["PictureHeight"].to_s
427 if hash["Subtitles"] && hash["Subtitles"] != "None"
428 if hash["Subtitles"] == "Autoselect"
429 commandString << " --subtitle-scan"
431 commandString << " -s "
432 commandString << hash["Subtitles"]
437 if hash["UsesPictureFilters"] == 1
439 case hash["PictureDeinterlace"]
441 commandString << " --deinterlace=\"fast\""
443 commandString << " --deinterlace=\slow\""
445 commandString << " --deinterlace=\"slower\""
447 commandString << " --deinterlace=\"slowest\""
450 case hash["PictureDenoise"]
452 commandString << " --denoise=\"weak\""
454 commandString << " --denoise=\"medium\""
456 commandString << " --denoise=\"strong\""
459 if hash["PictureDetelecine"] == 2 then commandString << " --detelecine" end
460 if hash["PictureDeblock"] != 0 then commandString << " --deblock=" << hash["PictureDeblock"].to_s end
461 if hash["PictureDecomb"] == 2 then commandString << " --decomb" end
466 if hash["PicturePAR"] == 1
467 commandString << " --strict-anamorphic"
468 elsif hash["PicturePAR"] == 2
469 commandString << " --loose-anamorphic"
470 elsif hash["PicturePAR"] == 3
471 commandString << " --custom-anamorphic"
475 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
476 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
477 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
478 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
481 if hash["x264Option"] != ""
482 commandString << " -x "
483 commandString << hash["x264Option"]
486 # That's it, print to screen now
489 #puts "*" * @columnWidth
494 def generateCLIFolderParse( hash, depth ) # Shows the folder for wrappers to parse
502 commandString << " " << hash["PresetName"] << "\n\n"
506 def generateCLIFolderCloserParse( depth )
514 commandString << "\n\n"
518 def generateCLIParse(hash, depth) # Makes a CLI equivalent of all user presets, for wrappers to parse
523 commandString << '+ ' << hash["PresetName"] << ":"
526 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
527 commandString << " -e "
528 case hash["VideoEncoder"]
530 commandString << "x264"
532 commandString << "theora"
537 case hash["VideoQualityType"]
539 commandString << " -S " << hash["VideoTargetSize"]
541 commandString << " -b " << hash["VideoAvgBitrate"]
543 commandString << " -q " << hash["VideoQualitySlider"].to_s
547 if hash["VideoFramerate"] != "Same as source"
548 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
549 commandString << " -r " << "23.976"
550 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
551 commandString << " -r " << "29.97"
552 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
553 commandString << " -r " << "25"
555 commandString << " -r " << hash["VideoFramerate"]
563 audioSamplerates = ""
566 audioCount = hash["AudioList"].size
568 hash["AudioList"].each do |audioTrack|
569 audioCount = audioCount - 1
572 audioBitrates << audioTrack["AudioBitrate"]
575 case audioTrack["AudioEncoder"]
577 audioEncoders << "ac3"
579 audioEncoders << "faac"
581 audioEncoders << "vorbis"
583 audioEncoders << "lame"
587 case audioTrack["AudioMixdown"]
589 audioMixdowns << "mono"
591 audioMixdowns << "stereo"
592 when /Dolby Surround/
593 audioMixdowns << "dpl1"
594 when /Dolby Pro Logic II/
595 audioMixdowns << "dpl2"
597 audioMixdowns << "6ch"
599 audioMixdowns << "auto"
603 audioSamplerates << audioTrack["AudioSamplerate"]
606 audioTracks << audioTrack["AudioTrack"].to_s
609 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
615 audioSamplerates << ","
617 audioTrackDRCs << ","
621 commandString << " -a " << audioTracks
622 commandString << " -E " << audioEncoders
623 commandString << " -B " << audioBitrates
624 commandString << " -6 " << audioMixdowns
625 commandString << " -R " << audioSamplerates
626 commandString << " -D " << audioTrackDRCs
629 commandString << " -f "
630 case hash["FileFormat"]
632 commandString << "mp4"
634 commandString << "mkv"
638 if hash["Mp4iPodCompatible"].to_i == 1
639 commandString << " -I"
643 if hash["Mp4LargeFile"] == 1
644 commandString << " -4"
648 if hash["PictureAutoCrop"] == 0
649 commandString << " --crop "
650 commandString << hash["PictureTopCrop"].to_s
652 commandString << hash["PictureBottomCrop"].to_s
654 commandString << hash["PictureLeftCrop"].to_s
656 commandString << hash["PictureRightCrop"].to_s
660 if hash["PictureWidth"] != 0
661 commandString << " -X "
662 commandString << hash["PictureWidth"].to_s
664 if hash["PictureHeight"] != 0
665 commandString << " -Y "
666 commandString << hash["PictureHeight"].to_s
670 if hash["Subtitles"] && hash["Subtitles"] != "None"
671 if hash["Subtitles"] == "Autoselect"
672 commandString << " --subtitle-scan"
674 commandString << " -s "
675 commandString << hash["Subtitles"]
680 if hash["UsesPictureFilters"] == 1
682 case hash["PictureDeinterlace"]
684 commandString << " --deinterlace=\"fast\""
686 commandString << " --deinterlace=\slow\""
688 commandString << " --deinterlace=\"slower\""
690 commandString << " --deinterlace=\"slowest\""
693 case hash["PictureDenoise"]
695 commandString << " --denoise=\"weak\""
697 commandString << " --denoise=\"medium\""
699 commandString << " --denoise=\"strong\""
702 if hash["PictureDetelecine"] == 2 then commandString << " --detelecine" end
703 if hash["PictureDeblock"] != 0 then commandString << " --deblock=" << hash["PictureDeblock"].to_s end
704 if hash["PictureDecomb"] == 2 then commandString << " --decomb" end
708 if hash["PicturePAR"] == 1
709 commandString << " --strict-anamorphic"
710 elsif hash["PicturePAR"] == 2
711 commandString << " --loose-anamorphic"
712 elsif hash["PicturePAR"] == 3
713 commandString << " --custom-anamorphic"
717 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
718 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
719 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
720 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
723 if hash["x264Option"] != ""
724 commandString << " -x "
725 commandString << hash["x264Option"]
728 # That's it, print to screen now
731 #puts "*" * @columnWidth
736 def generateAPIcalls(hash) # Makes a C version of the preset ready for coding into the CLI
738 commandString = "if (!strcmp(preset_name, \"" << hash["PresetName"] << "\"))\n{\n "
741 commandString << "if( !mux )\n "
742 commandString << "{\n "
744 case hash["FileFormat"]
746 commandString << " mux = " << "HB_MUX_MP4;\n "
748 commandString << " mux = " << "HB_MUX_MKV;\n "
750 commandString << "}\n "
753 if hash["Mp4iPodCompatible"].to_i == 1
754 commandString << "job->ipod_atom = 1;\n "
758 if hash["Mp4LargeFile"] == 1
759 commandString << "job->largeFileSize = 1;\n "
763 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
764 commandString << "vcodec = "
765 case hash["VideoEncoder"]
767 commandString << "HB_VCODEC_X264;\n "
769 commandString << "HB_VCODEC_THEORA;\n "
774 case hash["VideoQualityType"]
776 commandString << "size = " << hash["VideoTargetSize"] << ";\n "
778 commandString << "job->vbitrate = " << hash["VideoAvgBitrate"] << ";\n "
780 commandString << "job->vquality = " << hash["VideoQualitySlider"].to_s << ";\n "
784 if hash["VideoFramerate"] != "Same as source"
785 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
786 commandString << "job->vrate_base = " << "1126125;\n "
787 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
788 commandString << "job->vrate_base = " << "900900;\n "
789 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
790 commandString << "job->vrate_base = " << "1080000\n "
791 # Gotta add the rest of the framerates for completion's sake.
793 commandString << "job->cfr = 1;\n "
800 audioSamplerates = ""
803 audioCount = hash["AudioList"].size
805 hash["AudioList"].each do |audioTrack|
806 audioCount = audioCount - 1
809 audioBitrates << audioTrack["AudioBitrate"]
812 case audioTrack["AudioEncoder"]
814 audioEncoders << "ac3"
816 audioEncoders << "faac"
818 audioEncoders << "vorbis"
820 audioEncoders << "lame"
824 case audioTrack["AudioMixdown"]
826 audioMixdowns << "mono"
828 audioMixdowns << "stereo"
829 when /Dolby Surround/
830 audioMixdowns << "dpl1"
831 when /Dolby Pro Logic II/
832 audioMixdowns << "dpl2"
834 audioMixdowns << "6ch"
836 audioMixdowns << "auto"
840 audioSamplerates << audioTrack["AudioSamplerate"]
843 audioTracks << audioTrack["AudioTrack"].to_s
846 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
852 audioSamplerates << ","
854 audioTrackDRCs << ","
858 commandString << "if( !atracks )\n "
859 commandString << "{\n "
860 commandString << " atracks = strdup(\"" << audioTracks
861 commandString << "\");\n "
862 commandString << "}\n "
864 commandString << "if( !acodecs )\n "
865 commandString << "{\n "
866 commandString << " acodecs = strdup(\"" << audioEncoders
867 commandString << "\");\n "
868 commandString << "}\n "
870 commandString << "if( !abitrates )\n "
871 commandString << "{\n "
872 commandString << " abitrates = strdup(\"" << audioBitrates
873 commandString << "\");\n "
874 commandString << "}\n "
876 commandString << "if( !mixdowns )\n "
877 commandString << "{\n "
878 commandString << " mixdowns = strdup(\"" << audioMixdowns
879 commandString << "\");\n "
880 commandString << "}\n "
882 commandString << "if( !arates )\n "
883 commandString << "{\n "
884 commandString << " arates = strdup(\"" << audioSamplerates
885 commandString << "\");\n "
886 commandString << "}\n "
888 commandString << "if( !dynamic_range_compression )\n "
889 commandString << "{\n "
890 commandString << " dynamic_range_compression = strdup(\"" << audioTrackDRCs
891 commandString << "\");\n "
892 commandString << "}\n "
895 if hash["PictureAutoCrop"] == 0
896 commandString << "job->crop[0] = " << hash["PictureTopCrop"].to_s << ";\n "
897 commandString << "job->crop[1] = " << hash["PictureBottomCrop"].to_s << ";\n "
898 commandString << "job->crop[2] = " << hash["PictureLeftCrop"].to_s << ";\n "
899 commandString << "job->crop[4] = " << hash["PictureRightCrop"].to_s << ";\n "
903 if hash["PictureWidth"] != 0
904 commandString << "maxWidth = "
905 commandString << hash["PictureWidth"].to_s << ";\n "
907 if hash["PictureHeight"] != 0
908 commandString << "maxHeight = "
909 commandString << hash["PictureHeight"].to_s << ";\n "
913 if hash["Subtitles"] != "None"
914 if hash["Subtitles"] == "Autoselect"
915 commandString << "subtitle_scan = 1;\n "
917 commandString << "job->subtitle = "
918 commandString << ( hash["Subtitles"].to_i - 1).to_s << ";\n "
923 if hash["x264Option"] != ""
924 commandString << "if( !x264opts )\n "
925 commandString << "{\n "
926 commandString << " x264opts = strdup(\""
927 commandString << hash["x264Option"] << "\");\n "
928 commandString << "}\n "
932 if hash["UsesPictureFilters"] == 1
934 case hash["PictureDeinterlace"]
936 commandString << "deinterlace = 1;\n "
937 commandString << "deinterlace_opt = \"-1\";\n "
939 commandString << "deinterlace = 1;\n "
940 commandString << "deinterlace_opt = \"2\";\n "
942 commandString << "deinterlace = 1;\n "
943 commandString << "deinterlace_opt = \"0\";\n "
945 commandString << "deinterlace = 1;\n "
946 commandString << "deinterlace_opt = \"1:-1:1\";\n "
949 case hash["PictureDenoise"]
951 commandString << "denoise = 1;\n "
952 commandString << "denoise_opt = \"2:1:2:3\";\n "
954 commandString << "denoise = 1;\n "
955 commandString << "denoise_opt = \"3:2:2:3\";\n "
957 commandString << "denoise = 1;\n "
958 commandString << "denoise_opt = \"7:7:5:5\";\n "
961 if hash["PictureDetelecine"] == 2 then commandString << "detelecine = 1;\n " end
962 if hash["PictureDeblock"] != 0
964 commandString << "deblock = 1;\n "
965 commandString << "deblock_opt = \"" << hash["PictureDeblock"].to_s << "\";\n "
967 if hash["PictureDecomb"] == 2 then commandString << "decomb = 1;\n " end
972 if hash["PicturePAR"] != 0
973 commandString << "if( !anamorphic_mode )\n "
974 commandString << "{\n "
975 if hash["PicturePAR"] == 1
976 commandString << " anamorphic_mode = 1;\n "
977 elsif hash["PicturePAR"] == 2
978 commandString << " anamorphic_mode = 2;\n "
979 elsif hash["PicturePAR"] == 3
980 commandString << " anamorphic_mode = 3;\n "
982 commandString << "}\n "
986 if hash["ChapterMarkers"] == 1 then commandString << "job->chapter_markers = 1;\n " end
987 if hash["VideoGrayScale"] == 1 then commandString << "job->grayscale = 1;\n " end
988 if hash["VideoTwoPass"] == 1 then commandString << "twoPass = 1;\n " end
989 if hash["VideoTurboTwoPass"] == 1 then commandString << "turbo_opts_enabled = 1;\n" end
990 commandString << "\n"
993 # That's it, print to screen now
995 #puts "*" * @columnWidth
999 def generateAPIFolderList( hash, depth )
1002 commandString << " printf(\"\\n"
1004 commandString << " "
1007 commandString << "<"
1009 commandString << " " << hash["PresetName"]
1010 commandString << "\\n\");\n\n"
1014 def generateAPIFolderCloserList( depth )
1017 commandString << " printf(\"\\n"
1019 commandString << " "
1022 commandString << ">"
1024 commandString << "\\n\");\n\n"
1028 def generateAPIList(hash, depth) # Makes a list of the CLI options a built-in CLI preset uses, for wrappers to parse
1030 commandString << " printf(\"\\n"
1032 commandString << " "
1035 commandString << "+ " << hash["PresetName"] << ": "
1038 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
1039 commandString << " -e "
1040 case hash["VideoEncoder"]
1042 commandString << "x264 "
1044 commandString << "theora "
1049 case hash["VideoQualityType"]
1051 commandString << " -S " << hash["VideoTargetSize"]
1053 commandString << " -b " << hash["VideoAvgBitrate"]
1055 commandString << " -q " << hash["VideoQualitySlider"].to_s
1059 if hash["VideoFramerate"] != "Same as source"
1060 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
1061 commandString << " -r " << "23.976"
1062 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
1063 commandString << " -r " << "29.97"
1064 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
1065 commandString << " -r " << "25"
1067 commandString << " -r " << hash["VideoFramerate"]
1075 audioSamplerates = ""
1078 audioCount = hash["AudioList"].size
1080 hash["AudioList"].each do |audioTrack|
1081 audioCount = audioCount - 1
1084 audioBitrates << audioTrack["AudioBitrate"]
1087 case audioTrack["AudioEncoder"]
1089 audioEncoders << "ac3"
1091 audioEncoders << "faac"
1093 audioEncoders << "vorbis"
1095 audioEncoders << "lame"
1099 case audioTrack["AudioMixdown"]
1101 audioMixdowns << "mono"
1103 audioMixdowns << "stereo"
1104 when /Dolby Surround/
1105 audioMixdowns << "dpl1"
1106 when /Dolby Pro Logic II/
1107 audioMixdowns << "dpl2"
1109 audioMixdowns << "6ch"
1111 audioMixdowns << "auto"
1115 audioSamplerates << audioTrack["AudioSamplerate"]
1118 audioTracks << audioTrack["AudioTrack"].to_s
1121 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
1124 audioBitrates << ","
1125 audioEncoders << ","
1126 audioMixdowns << ","
1127 audioSamplerates << ","
1129 audioTrackDRCs << ","
1133 commandString << " -a " << audioTracks
1134 commandString << " -E " << audioEncoders
1135 commandString << " -B " << audioBitrates
1136 commandString << " -6 " << audioMixdowns
1137 commandString << " -R " << audioSamplerates
1138 commandString << " -D " << audioTrackDRCs
1141 commandString << " -f "
1142 case hash["FileFormat"]
1144 commandString << "mp4"
1146 commandString << "mkv"
1150 if hash["Mp4iPodCompatible"].to_i == 1
1151 commandString << " -I"
1155 if hash["Mp4LargeFile"] == 1
1156 commandString << " -4"
1160 if hash["PictureAutoCrop"] == 0
1161 commandString << " --crop "
1162 commandString << hash["PictureTopCrop"].to_s
1163 commandString << ":"
1164 commandString << hash["PictureBottomCrop"].to_s
1165 commandString << ":"
1166 commandString << hash["PictureLeftCrop"].to_s
1167 commandString << ":"
1168 commandString << hash["PictureRightCrop"].to_s
1172 if hash["PictureWidth"] != 0
1173 commandString << " -X "
1174 commandString << hash["PictureWidth"].to_s
1176 if hash["PictureHeight"] != 0
1177 commandString << " -Y "
1178 commandString << hash["PictureHeight"].to_s
1182 if hash["Subtitles"] && hash["Subtitles"] != "None"
1183 if hash["Subtitles"] == "Autoselect"
1184 commandString << " --subtitle-scan"
1186 commandString << " -s "
1187 commandString << hash["Subtitles"]
1192 if hash["UsesPictureFilters"] == 1
1194 case hash["PictureDeinterlace"]
1196 commandString << " --deinterlace=\\\"fast\\\""
1198 commandString << " --deinterlace=\\\slow\\\""
1200 commandString << " --deinterlace=\\\"slower\\\""
1202 commandString << " --deinterlace=\\\"slowest\\\""
1205 case hash["PictureDenoise"]
1207 commandString << " --denoise=\\\"weak\\\""
1209 commandString << " --denoise=\\\"medium\\\""
1211 commandString << " --denoise=\\\"strong\\\""
1214 if hash["PictureDetelecine"] == 2 then commandString << " --detelecine" end
1215 if hash["PictureDeblock"] != 0 then commandString << " --deblock=" << hash["PictureDeblock"].to_s end
1216 if hash["PictureDecomb"] == 2 then commandString << " --decomb" end
1220 if hash["PicturePAR"] == 1
1221 commandString << " --strict-anamorphic"
1222 elsif hash["PicturePAR"] == 2
1223 commandString << " --loose-anamorphic"
1224 elsif hash["PicturePAR"] == 3
1225 commandString << " --custom-anamorphic"
1229 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
1230 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
1231 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
1232 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
1235 if hash["x264Option"] != ""
1236 commandString << " -x "
1237 commandString << hash["x264Option"]
1240 commandString << "\\n\");"
1242 # That's it, print to screen now
1249 # First grab the specified CLI options
1250 options = readOptions
1252 # Only run if one of the useful CLI flags have been passed
1253 if options.cliraw == true || options.cliparse == true || options.api == true || options.apilist == true
1254 # This line is the ignition -- generates hashes of
1255 # presets and then displays them to the screen
1256 # with the options the user selects on the CLI.
1257 Display.new( Presets.new.hashMasterList, options )
1259 # Direct the user to the help
1260 puts "\n\tUsage: manicure.rb [options]"
1261 puts "\tSee help with -h or --help"