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 << "avi "
281 commandString << "ogm "
283 commandString << "mkv "
287 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
288 commandString << " -e "
289 case hash["VideoEncoder"]
291 commandString << "x264"
293 commandString << "xvid"
298 case hash["VideoQualityType"]
300 commandString << " -S " << hash["VideoTargetSize"]
302 commandString << " -b " << hash["VideoAvgBitrate"]
304 commandString << " -q " << hash["VideoQualitySlider"].to_s
308 if hash["VideoFramerate"] != "Same as source"
309 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
310 commandString << " -r " << "23.976"
311 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
312 commandString << " -r " << "29.97"
313 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
314 commandString << " -r " << "25"
316 commandString << " -r " << hash["VideoFramerate"]
321 commandString << " -a "
322 commandString << hash["Audio1Track"].to_s
323 if hash["Audio2Track"]
324 commandString << "," << hash["Audio2Track"].to_s
326 if hash["Audio3Track"]
327 commandString << "," << hash["Audio3Track"].to_s
329 if hash["Audio4Track"]
330 commandString << "," << hash["Audio4Track"].to_s
334 commandString << " -E "
335 case hash["Audio1Encoder"]
337 commandString << "ac3"
339 commandString << "faac"
341 commandString << "vorbis"
343 commandString << "lame"
345 case hash["Audio2Encoder"]
347 commandString << ",ac3"
349 commandString << ",faac"
351 commandString << ",vorbis"
353 commandString << ",lame"
355 case hash["Audio3Encoder"]
357 commandString << ",ac3"
359 commandString << ",faac"
361 commandString << ",vorbis"
363 commandString << ",lame"
365 case hash["Audio4Encoder"]
367 commandString << ",ac3"
369 commandString << ",faac"
371 commandString << ",vorbis"
373 commandString << ",lame"
377 commandString << " -B "
378 commandString << hash["Audio1Bitrate"]
379 if hash["Audio2Bitrate"]
380 if hash["Audio2Encoder"] != "AC3 Passthru"
381 commandString << "," << hash["Audio2Bitrate"]
383 commandString << "," << "auto"
386 if hash["Audio3Bitrate"]
387 if hash["Audio3Encoder"] != "AC3 Passthru"
388 commandString << "," << hash["Audio3Bitrate"]
390 commandString << "," << "auto"
393 if hash["Audio4Bitrate"]
394 if hash["Audio4Encoder"] != "AC3 Passthru"
395 commandString << "," << hash["Audio4Bitrate"]
397 commandString << "," << "auto"
402 commandString << " -R "
403 commandString << hash["Audio1Samplerate"]
404 if hash["Audio2Samplerate"]
405 commandString << "," << hash["Audio2Samplerate"]
407 if hash["Audio3Samplerate"]
408 commandString << "," << hash["Audio3Samplerate"]
410 if hash["Audio4Samplerate"]
411 commandString << "," << hash["Audio4Samplerate"]
415 commandString << " -6 "
416 case hash["Audio1Mixdown"]
418 commandString << "mono"
420 commandString << "stereo"
421 when /Dolby Surround/
422 commandString << "dpl1"
423 when /Dolby Pro Logic II/
424 commandString << "dpl2"
426 commandString << "6ch"
428 commandString << "auto"
431 if hash["Audio2Mixdown"]
432 case hash["Audio2Mixdown"]
434 commandString << ",mono"
436 commandString << ",stereo"
437 when /Dolby Surround/
438 commandString << ",dpl1"
439 when /Dolby Pro Logic II/
440 commandString << ",dpl2"
442 commandString << ",6ch"
444 commandString << ",auto"
448 if hash["Audio3Mixdown"]
449 case hash["Audio3Mixdown"]
451 commandString << ",mono"
453 commandString << ",stereo"
454 when /Dolby Surround/
455 commandString << ",dpl1"
456 when /Dolby Pro Logic II/
457 commandString << ",dpl2"
459 commandString << ",6ch"
461 commandString << ",auto"
465 if hash["Audio4Mixdown"]
466 case hash["Audio4Mixdown"]
468 commandString << ",mono"
470 commandString << ",stereo"
471 when /Dolby Surround/
472 commandString << ",dpl1"
473 when /Dolby Pro Logic II/
474 commandString << ",dpl2"
476 commandString << ",6ch"
478 commandString << ",auto"
483 commandString << " -f "
484 case hash["FileFormat"]
486 commandString << "mp4"
488 commandString << "avi"
490 commandString << "ogm"
492 commandString << "mkv"
496 if hash["Mp4iPodCompatible"].to_i == 1
497 commandString << " -I"
501 if hash["Mp4LargeFile"] == 1
502 commandString << " -4"
506 if hash["PictureAutoCrop"] == 0
507 commandString << " --crop "
508 commandString << hash["PictureTopCrop"].to_s
510 commandString << hash["PictureBottomCrop"].to_s
512 commandString << hash["PictureLeftCrop"].to_s
514 commandString << hash["PictureRightCrop"].to_s
518 if hash["PictureWidth"] != 0
519 commandString << " -X "
520 commandString << hash["PictureWidth"].to_s
522 if hash["PictureHeight"] != 0
523 commandString << " -Y "
524 commandString << hash["PictureHeight"].to_s
528 if hash["Subtitles"] != "None"
529 if hash["Subtitles"] == "Autoselect"
530 commandString << " --subtitle-scan"
532 commandString << " -s "
533 commandString << hash["Subtitles"]
538 if hash["UsesPictureFilters"] == 1
540 case hash["PictureDeinterlace"]
542 commandString << " --deinterlace=\"fast\""
544 commandString << " --deinterlace=\slow\""
546 commandString << " --deinterlace=\"slower\""
548 commandString << " --deinterlace=\"slowest\""
551 case hash["PictureDenoise"]
553 commandString << " --denoise=\"weak\""
555 commandString << " --denoise=\"medium\""
557 commandString << " --denoise=\"strong\""
560 if hash["PictureDetelecine"] == 1 then commandString << " --detelecine" end
561 if hash["PictureDeblock"] == 1 then commandString << " --deblock" end
562 if hash["VFR"].to_i == 1 then commandString << " --vfr" end
563 if hash["PictureDecomb"] == 1 then commandString << " --decomb" end
568 if hash["PicturePAR"] == 1
569 commandString << " -p"
570 elsif hash["PicturePAR"] == 2
571 commandString << " -P"
575 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
576 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
577 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
578 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
581 if hash["x264Option"] != ""
582 commandString << " -x "
583 commandString << hash["x264Option"]
586 # That's it, print to screen now
589 #puts "*" * @columnWidth
594 def generateCLIFolderParse( hash, depth ) # Shows the folder for wrappers to parse
602 commandString << " " << hash["PresetName"] << "\n\n"
606 def generateCLIFolderCloserParse( depth )
614 commandString << "\n\n"
618 def generateCLIParse(hash, depth) # Makes a CLI equivalent of all user presets, for wrappers to parse
623 commandString << '+ ' << hash["PresetName"] << ":"
626 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
627 commandString << " -e "
628 case hash["VideoEncoder"]
630 commandString << "x264"
632 commandString << "xvid"
637 case hash["VideoQualityType"]
639 commandString << " -S " << hash["VideoTargetSize"]
641 commandString << " -b " << hash["VideoAvgBitrate"]
643 commandString << " -q " << hash["VideoQualitySlider"].to_s
647 if hash["VideoFramerate"] != "Same as source"
648 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
649 commandString << " -r " << "23.976"
650 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
651 commandString << " -r " << "29.97"
652 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
653 commandString << " -r " << "25"
655 commandString << " -r " << hash["VideoFramerate"]
660 commandString << " -a "
661 commandString << hash["Audio1Track"].to_s
662 if hash["Audio2Track"]
663 commandString << "," << hash["Audio2Track"].to_s
665 if hash["Audio3Track"]
666 commandString << "," << hash["Audio3Track"].to_s
668 if hash["Audio4Track"]
669 commandString << "," << hash["Audio4Track"].to_s
673 commandString << " -E "
674 case hash["Audio1Encoder"]
676 commandString << "ac3"
678 commandString << "faac"
680 commandString << "vorbis"
682 commandString << "lame"
684 case hash["Audio2Encoder"]
686 commandString << ",ac3"
688 commandString << ",faac"
690 commandString << ",vorbis"
692 commandString << ",lame"
694 case hash["Audio3Encoder"]
696 commandString << ",ac3"
698 commandString << ",faac"
700 commandString << ",vorbis"
702 commandString << ",lame"
704 case hash["Audio4Encoder"]
706 commandString << ",ac3"
708 commandString << ",faac"
710 commandString << ",vorbis"
712 commandString << ",lame"
716 commandString << " -B "
717 commandString << hash["Audio1Bitrate"]
718 if hash["Audio2Bitrate"]
719 if hash["Audio2Encoder"] != "AC3 Passthru"
720 commandString << "," << hash["Audio2Bitrate"]
722 commandString << "," << "auto"
725 if hash["Audio3Bitrate"]
726 if hash["Audio3Encoder"] != "AC3 Passthru"
727 commandString << "," << hash["Audio3Bitrate"]
729 commandString << "," << "auto"
732 if hash["Audio4Bitrate"]
733 if hash["Audio4Encoder"] != "AC3 Passthru"
734 commandString << "," << hash["Audio4Bitrate"]
736 commandString << "," << "auto"
741 commandString << " -R "
742 commandString << hash["Audio1Samplerate"]
743 if hash["Audio2Samplerate"]
744 commandString << "," << hash["Audio2Samplerate"]
746 if hash["Audio3Samplerate"]
747 commandString << "," << hash["Audio3Samplerate"]
749 if hash["Audio4Samplerate"]
750 commandString << "," << hash["Audio4Samplerate"]
754 commandString << " -6 "
755 case hash["Audio1Mixdown"]
757 commandString << "mono"
759 commandString << "stereo"
760 when /Dolby Surround/
761 commandString << "dpl1"
762 when /Dolby Pro Logic II/
763 commandString << "dpl2"
765 commandString << "6ch"
767 commandString << "auto"
770 if hash["Audio2Mixdown"]
771 case hash["Audio2Mixdown"]
773 commandString << ",mono"
775 commandString << ",stereo"
776 when /Dolby Surround/
777 commandString << ",dpl1"
778 when /Dolby Pro Logic II/
779 commandString << ",dpl2"
781 commandString << ",6ch"
783 commandString << ",auto"
787 if hash["Audio3Mixdown"]
788 case hash["Audio3Mixdown"]
790 commandString << ",mono"
792 commandString << ",stereo"
793 when /Dolby Surround/
794 commandString << ",dpl1"
795 when /Dolby Pro Logic II/
796 commandString << ",dpl2"
798 commandString << ",6ch"
800 commandString << ",auto"
804 if hash["Audio4Mixdown"]
805 case hash["Audio4Mixdown"]
807 commandString << ",mono"
809 commandString << ",stereo"
810 when /Dolby Surround/
811 commandString << ",dpl1"
812 when /Dolby Pro Logic II/
813 commandString << ",dpl2"
815 commandString << ",6ch"
817 commandString << ",auto"
823 commandString << " -f "
824 case hash["FileFormat"]
826 commandString << "mp4"
828 commandString << "avi"
830 commandString << "ogm"
832 commandString << "mkv"
836 if hash["Mp4iPodCompatible"].to_i == 1
837 commandString << " -I"
841 if hash["Mp4LargeFile"] == 1
842 commandString << " -4"
846 if hash["PictureAutoCrop"] == 0
847 commandString << " --crop "
848 commandString << hash["PictureTopCrop"].to_s
850 commandString << hash["PictureBottomCrop"].to_s
852 commandString << hash["PictureLeftCrop"].to_s
854 commandString << hash["PictureRightCrop"].to_s
858 if hash["PictureWidth"] != 0
859 commandString << " -X "
860 commandString << hash["PictureWidth"].to_s
862 if hash["PictureHeight"] != 0
863 commandString << " -Y "
864 commandString << hash["PictureHeight"].to_s
868 if hash["Subtitles"] != "None"
869 if hash["Subtitles"] == "Autoselect"
870 commandString << " --subtitle-scan"
872 commandString << " -s "
873 commandString << hash["Subtitles"]
878 if hash["UsesPictureFilters"] == 1
880 case hash["PictureDeinterlace"]
882 commandString << " --deinterlace=\"fast\""
884 commandString << " --deinterlace=\slow\""
886 commandString << " --deinterlace=\"slower\""
888 commandString << " --deinterlace=\"slowest\""
891 case hash["PictureDenoise"]
893 commandString << " --denoise=\"weak\""
895 commandString << " --denoise=\"medium\""
897 commandString << " --denoise=\"strong\""
900 if hash["PictureDetelecine"] == 1 then commandString << " --detelecine" end
901 if hash["PictureDeblock"] == 1 then commandString << " --deblock" end
902 if hash["VFR"].to_i == 1 then commandString << " --vfr" end
903 if hash["PictureDecomb"] == 1 then commandString << " --decomb" end
907 if hash["PicturePAR"] == 1
908 commandString << " -p"
909 elsif hash["PicturePAR"] == 2
910 commandString << " -P"
914 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
915 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
916 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
917 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
920 if hash["x264Option"] != ""
921 commandString << " -x "
922 commandString << hash["x264Option"]
925 # That's it, print to screen now
928 #puts "*" * @columnWidth
933 def generateAPIcalls(hash) # Makes a C version of the preset ready for coding into the CLI
935 commandString = "if (!strcmp(preset_name, \"" << hash["PresetName"] << "\"))\n{\n "
938 case hash["FileFormat"]
940 commandString << "mux = " << "HB_MUX_MP4;\n "
942 commandString << "mux = " << "HB_MUX_AVI;\n "
944 commandString << "mux = " << "HB_MUX_OGM;\n "
946 commandString << "mux = " << "HB_MUX_MKV;\n "
950 if hash["Mp4iPodCompatible"].to_i == 1
951 commandString << "job->ipod_atom = 1;\n "
955 if hash["Mp4LargeFile"] == 1
956 commandString << "job->largeFileSize = 1;\n "
960 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
961 commandString << "vcodec = "
962 case hash["VideoEncoder"]
964 commandString << "HB_VCODEC_X264;\n "
966 commandString << "HB_VCODEC_XVID;\n "
971 case hash["VideoQualityType"]
973 commandString << "size = " << hash["VideoTargetSize"] << ";\n "
975 commandString << "job->vbitrate = " << hash["VideoAvgBitrate"] << ";\n "
977 commandString << "job->vquality = " << hash["VideoQualitySlider"].to_s << ";\n "
978 commandString << "job->crf = 1;\n "
982 if hash["VideoFramerate"] != "Same as source"
983 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
984 commandString << "job->vrate_base = " << "1126125;\n "
985 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
986 commandString << "job->vrate_base = " << "900900;\n "
987 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
988 commandString << "job->vrate_base = " << "1080000\n "
989 # Gotta add the rest of the framerates for completion's sake.
991 commandString << "job->cfr = 1;\n "
995 commandString << "if( !atracks )\n "
996 commandString << "{\n "
997 commandString << " atracks = strdup(\""
998 commandString << hash["Audio1Track"].to_s
999 if hash["Audio2Track"]
1000 commandString << "," << hash["Audio2Track"].to_s
1002 if hash["Audio3Track"]
1003 commandString << "," << hash["Audio3Track"].to_s
1005 if hash["Audio4Track"]
1006 commandString << "," << hash["Audio4Track"].to_s
1008 commandString << "\");\n "
1009 commandString << "}\n "
1012 commandString << "if( !abitrates )\n "
1013 commandString << "{\n "
1014 commandString << " abitrates = strdup(\""
1015 if hash["Audio1Encoder"] != "AC3 Passthru"
1016 commandString << hash["Audio1Bitrate"]
1018 commandString << "auto"
1020 if hash["Audio2Bitrate"]
1021 if hash["Audio2Encoder"] != "AC3 Passthru"
1022 commandString << "," << hash["Audio2Bitrate"]
1024 commandString << "," << "auto"
1027 if hash["Audio3Bitrate"]
1028 if hash["Audio3Encoder"] != "AC3 Passthru"
1029 commandString << "," << hash["Audio3Bitrate"]
1031 commandString << "," << "auto"
1034 if hash["Audio4Bitrate"]
1035 if hash["Audio4Encoder"] != "AC3 Passthru"
1036 commandString << "," << hash["Audio4Bitrate"]
1038 commandString << "," << "auto"
1041 commandString << "\");\n "
1042 commandString << "}\n "
1045 commandString << "if( !arates )\n "
1046 commandString << "{\n "
1047 commandString << " arates = strdup(\""
1048 commandString << hash["Audio1Samplerate"]
1049 if hash["Audio2Samplerate"]
1050 commandString << "," << hash["Audio2Samplerate"]
1052 if hash["Audio3Samplerate"]
1053 commandString << "," << hash["Audio3Samplerate"]
1055 if hash["Audio4Samplerate"]
1056 commandString << "," << hash["Audio4Samplerate"]
1058 commandString << "\");\n "
1059 commandString << "}\n "
1062 commandString << "if( !acodecs )\n "
1063 commandString << "{\n "
1064 commandString << " acodecs = strdup(\""
1065 case hash["Audio1Encoder"]
1067 commandString << "ac3"
1069 commandString << "faac"
1071 commandString << "vorbis"
1073 commandString << "lame"
1075 case hash["Audio2Encoder"]
1077 commandString << ",ac3"
1079 commandString << ",faac"
1081 commandString << ",vorbis"
1083 commandString << ",lame"
1085 case hash["Audio3Encoder"]
1087 commandString << ",ac3"
1089 commandString << ",faac"
1091 commandString << ",vorbis"
1093 commandString << ",lame"
1095 case hash["Audio4Encoder"]
1097 commandString << ",ac3"
1099 commandString << ",faac"
1101 commandString << ",vorbis"
1103 commandString << ",lame"
1105 commandString << "\");\n "
1106 commandString << "}\n "
1109 commandString << "if( !mixdowns )\n "
1110 commandString << "{\n "
1111 commandString << " mixdowns = strdup(\""
1112 case hash["Audio1Mixdown"]
1114 commandString << "mono"
1116 commandString << "stereo"
1117 when /Dolby Surround/
1118 commandString << "dpl1"
1119 when /Dolby Pro Logic II/
1120 commandString << "dpl2"
1122 commandString << "6ch"
1124 commandString << "auto"
1126 if hash["Audio2Mixdown"]
1127 case hash["Audio2Mixdown"]
1129 commandString << ",mono"
1131 commandString << ",stereo"
1132 when /Dolby Surround/
1133 commandString << ",dpl1"
1134 when /Dolby Pro Logic II/
1135 commandString << ",dpl2"
1137 commandString << ",6ch"
1139 commandString << ",auto"
1142 if hash["Audio3Mixdown"]
1143 case hash["Audio3Mixdown"]
1145 commandString << ",mono"
1147 commandString << ",stereo"
1148 when /Dolby Surround/
1149 commandString << ",dpl1"
1150 when /Dolby Pro Logic II/
1151 commandString << ",dpl2"
1153 commandString << ",6ch"
1155 commandString << ",auto"
1158 if hash["Audio4Mixdown"]
1159 case hash["Audio4Mixdown"]
1161 commandString << ",mono"
1163 commandString << ",stereo"
1164 when /Dolby Surround/
1165 commandString << ",dpl1"
1166 when /Dolby Pro Logic II/
1167 commandString << ",dpl2"
1169 commandString << ",6ch"
1171 commandString << ",auto"
1174 commandString << "\");\n "
1175 commandString << "}\n "
1178 if hash["PictureAutoCrop"] == 0
1179 commandString << "job->crop[0] = " << hash["PictureTopCrop"].to_s << ";\n "
1180 commandString << "job->crop[1] = " << hash["PictureBottomCrop"].to_s << ";\n "
1181 commandString << "job->crop[2] = " << hash["PictureLeftCrop"].to_s << ";\n "
1182 commandString << "job->crop[4] - " << hash["PictureRightCrop"].to_s << ";\n "
1186 if hash["PictureWidth"] != 0
1187 commandString << "maxWidth = "
1188 commandString << hash["PictureWidth"].to_s << ";\n "
1190 if hash["PictureHeight"] != 0
1191 commandString << "maxHeight = "
1192 commandString << hash["PictureHeight"].to_s << ";\n "
1196 if hash["Subtitles"] != "None"
1197 if hash["Subtitles"] == "Autoselect"
1198 commandString << "subtitle_scan = 1;\n "
1200 commandString << "job->subtitle = "
1201 commandString << ( hash["Subtitles"].to_i - 1).to_s << ";\n "
1206 if hash["x264Option"] != ""
1207 commandString << "if( !x264opts )\n "
1208 commandString << "{\n "
1209 commandString << " x264opts = strdup(\""
1210 commandString << hash["x264Option"] << "\");\n "
1211 commandString << "}\n "
1215 if hash["UsesPictureFilters"] == 1
1217 case hash["PictureDeinterlace"]
1219 commandString << "deinterlace = 1;\n "
1220 commandString << "deinterlace_opt = \"-1\";\n "
1222 commandString << "deinterlace = 1;\n "
1223 commandString << "deinterlace_opt = \"2\";\n "
1225 commandString << "deinterlace = 1;\n "
1226 commandString << "deinterlace_opt = \"0\";\n "
1228 commandString << "deinterlace = 1;\n "
1229 commandString << "deinterlace_opt = \"1:-1:1\";\n "
1232 case hash["PictureDenoise"]
1234 commandString << "denoise = 1;\n "
1235 commandString << "denoise_opt = \"2:1:2:3\";\n "
1237 commandString << "denoise = 1;\n "
1238 commandString << "denoise_opt = \"3:2:2:3\";\n "
1240 commandString << "denoise = 1;\n "
1241 commandString << "denoise_opt = \"7:7:5:5\";\n "
1244 if hash["PictureDetelecine"] == 1 then commandString << "detelecine = 1;\n " end
1245 if hash["PictureDeblock"] == 1 then commandString << "deblock = 1;\n " end
1246 if hash["VFR"].to_i == 1 then commandString << "vfr = 1;\n " end
1247 if hash["PictureDecomb"] == 1 then commandString << "decomb = 1;\n " end
1252 if hash["PicturePAR"] == 1
1253 commandString << "pixelratio = 1;\n "
1254 elsif hash["PicturePAR"] == 2
1255 commandString << "pixelratio = 2;\n "
1259 if hash["ChapterMarkers"] == 1 then commandString << "job->chapter_markers = 1;\n " end
1260 if hash["VideoGrayScale"] == 1 then commandString << "job->grayscale = 1;\n " end
1261 if hash["VideoTwoPass"] == 1 then commandString << "twoPass = 1;\n " end
1262 if hash["VideoTurboTwoPass"] == 1 then commandString << "turbo_opts_enabled = 1;\n" end
1264 commandString << "}"
1266 # That's it, print to screen now
1268 #puts "*" * @columnWidth
1272 def generateAPIFolderList( hash, depth )
1275 commandString << " printf(\"\\n"
1277 commandString << " "
1280 commandString << "<"
1282 commandString << " " << hash["PresetName"]
1283 commandString << "\\n\");\n\n"
1287 def generateAPIFolderCloserList( depth )
1290 commandString << " printf(\"\\n"
1292 commandString << " "
1295 commandString << ">"
1297 commandString << "\\n\");\n\n"
1301 def generateAPIList(hash, depth) # Makes a list of the CLI options a built-in CLI preset uses, for wrappers to parse
1303 commandString << " printf(\"\\n"
1305 commandString << " "
1308 commandString << "+ " << hash["PresetName"] << ": "
1311 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
1312 commandString << " -e "
1313 case hash["VideoEncoder"]
1315 commandString << "x264 "
1317 commandString << "xvid "
1322 case hash["VideoQualityType"]
1324 commandString << " -S " << hash["VideoTargetSize"]
1326 commandString << " -b " << hash["VideoAvgBitrate"]
1328 commandString << " -q " << hash["VideoQualitySlider"].to_s
1332 if hash["VideoFramerate"] != "Same as source"
1333 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
1334 commandString << " -r " << "23.976"
1335 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
1336 commandString << " -r " << "29.97"
1337 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
1338 commandString << " -r " << "25"
1340 commandString << " -r " << hash["VideoFramerate"]
1345 commandString << " -a "
1346 commandString << hash["Audio1Track"].to_s
1347 if hash["Audio2Track"]
1348 commandString << "," << hash["Audio2Track"].to_s
1350 if hash["Audio3Track"]
1351 commandString << "," << hash["Audio3Track"].to_s
1353 if hash["Audio4Track"]
1354 commandString << "," << hash["Audio4Track"].to_s
1358 commandString << " -E "
1359 case hash["Audio1Encoder"]
1361 commandString << "ac3"
1363 commandString << "faac"
1365 commandString << "vorbis"
1367 commandString << "lame"
1369 case hash["Audio2Encoder"]
1371 commandString << ",ac3"
1373 commandString << ",faac"
1375 commandString << ",vorbis"
1377 commandString << ",lame"
1379 case hash["Audio3Encoder"]
1381 commandString << ",ac3"
1383 commandString << ",faac"
1385 commandString << ",vorbis"
1387 commandString << ",lame"
1389 case hash["Audio4Encoder"]
1391 commandString << ",ac3"
1393 commandString << ",faac"
1395 commandString << ",vorbis"
1397 commandString << ",lame"
1401 commandString << " -B "
1402 commandString << hash["Audio1Bitrate"]
1403 if hash["Audio2Bitrate"]
1404 if hash["Audio2Encoder"] != "AC3 Passthru"
1405 commandString << "," << hash["Audio2Bitrate"]
1407 commandString << "," << "auto"
1410 if hash["Audio3Bitrate"]
1411 if hash["Audio3Encoder"] != "AC3 Passthru"
1412 commandString << "," << hash["Audio3Bitrate"]
1414 commandString << "," << "auto"
1417 if hash["Audio4Bitrate"]
1418 if hash["Audio4Encoder"] != "AC3 Passthru"
1419 commandString << "," << hash["Audio4Bitrate"]
1421 commandString << "," << "auto"
1426 commandString << " -R "
1427 commandString << hash["Audio1Samplerate"]
1428 if hash["Audio2Samplerate"]
1429 commandString << "," << hash["Audio2Samplerate"]
1431 if hash["Audio3Samplerate"]
1432 commandString << "," << hash["Audio3Samplerate"]
1434 if hash["Audio4Samplerate"]
1435 commandString << "," << hash["Audio4Samplerate"]
1439 commandString << " -6 "
1440 case hash["Audio1Mixdown"]
1442 commandString << "mono"
1444 commandString << "stereo"
1445 when /Dolby Surround/
1446 commandString << "dpl1"
1447 when /Dolby Pro Logic II/
1448 commandString << "dpl2"
1450 commandString << "6ch"
1452 commandString << "auto"
1455 if hash["Audio2Mixdown"]
1456 case hash["Audio2Mixdown"]
1458 commandString << ",mono"
1460 commandString << ",stereo"
1461 when /Dolby Surround/
1462 commandString << ",dpl1"
1463 when /Dolby Pro Logic II/
1464 commandString << ",dpl2"
1466 commandString << ",6ch"
1468 commandString << ",auto"
1472 if hash["Audio3Mixdown"]
1473 case hash["Audio3Mixdown"]
1475 commandString << ",mono"
1477 commandString << ",stereo"
1478 when /Dolby Surround/
1479 commandString << ",dpl1"
1480 when /Dolby Pro Logic II/
1481 commandString << ",dpl2"
1483 commandString << ",6ch"
1485 commandString << ",auto"
1489 if hash["Audio4Mixdown"]
1490 case hash["Audio4Mixdown"]
1492 commandString << ",mono"
1494 commandString << ",stereo"
1495 when /Dolby Surround/
1496 commandString << ",dpl1"
1497 when /Dolby Pro Logic II/
1498 commandString << ",dpl2"
1500 commandString << ",6ch"
1502 commandString << ",auto"
1507 commandString << " -f "
1508 case hash["FileFormat"]
1510 commandString << "mp4"
1512 commandString << "avi"
1514 commandString << "ogm"
1516 commandString << "mkv"
1520 if hash["Mp4iPodCompatible"].to_i == 1
1521 commandString << " -I"
1525 if hash["Mp4LargeFile"] == 1
1526 commandString << " -4"
1530 if hash["PictureAutoCrop"] == 0
1531 commandString << " --crop "
1532 commandString << hash["PictureTopCrop"].to_s
1533 commandString << ":"
1534 commandString << hash["PictureBottomCrop"].to_s
1535 commandString << ":"
1536 commandString << hash["PictureLeftCrop"].to_s
1537 commandString << ":"
1538 commandString << hash["PictureRightCrop"].to_s
1542 if hash["PictureWidth"] != 0
1543 commandString << " -X "
1544 commandString << hash["PictureWidth"].to_s
1546 if hash["PictureHeight"] != 0
1547 commandString << " -Y "
1548 commandString << hash["PictureHeight"].to_s
1552 if hash["Subtitles"] != "None"
1553 if hash["Subtitles"] == "Autoselect"
1554 commandString << " --subtitle-scan"
1556 commandString << " -s "
1557 commandString << hash["Subtitles"]
1562 if hash["UsesPictureFilters"] == 1
1564 case hash["PictureDeinterlace"]
1566 commandString << " --deinterlace=\\\"fast\\\""
1568 commandString << " --deinterlace=\\\slow\\\""
1570 commandString << " --deinterlace=\\\"slower\\\""
1572 commandString << " --deinterlace=\\\"slowest\\\""
1575 case hash["PictureDenoise"]
1577 commandString << " --denoise=\\\"weak\\\""
1579 commandString << " --denoise=\\\"medium\\\""
1581 commandString << " --denoise=\\\"strong\\\""
1584 if hash["PictureDetelecine"] == 1 then commandString << " --detelecine" end
1585 if hash["PictureDeblock"] == 1 then commandString << " --deblock" end
1586 if hash["VFR"].to_i == 1 then commandString << " --vfr" end
1587 if hash["PictureDecomb"] == 1 then commandString << " --decomb" end
1591 if hash["PicturePAR"] == 1
1592 commandString << " -p"
1593 elsif hash["PicturePAR"] == 2
1594 commandString << " -P"
1598 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
1599 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
1600 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
1601 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
1604 if hash["x264Option"] != ""
1605 commandString << " -x "
1606 commandString << hash["x264Option"]
1609 commandString << "\\n\");"
1611 # That's it, print to screen now
1618 # First grab the specified CLI options
1619 options = readOptions
1621 # Only run if one of the useful CLI flags have been passed
1622 if options.cliraw == true || options.cliparse == true || options.api == true || options.apilist == true
1623 # This line is the ignition -- generates hashes of
1624 # presets and then displays them to the screen
1625 # with the options the user selects on the CLI.
1626 Display.new( Presets.new.hashMasterList, options )
1628 # Direct the user to the help
1629 puts "\n\tUsage: manicure.rb [options]"
1630 puts "\tSee help with -h or --help"