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"]
315 if hash["VideoFrameratePFR"] == 1
316 commandString << " --pfr "
324 audioSamplerates = ""
327 audioCount = hash["AudioList"].size
329 hash["AudioList"].each do |audioTrack|
330 audioCount = audioCount - 1
333 audioBitrates << audioTrack["AudioBitrate"]
336 case audioTrack["AudioEncoder"]
338 audioEncoders << "copy:ac3"
340 audioEncoders << "ac3"
342 audioEncoders << "faac"
344 audioEncoders << "vorbis"
346 audioEncoders << "lame"
350 case audioTrack["AudioMixdown"]
352 audioMixdowns << "mono"
354 audioMixdowns << "stereo"
355 when /Dolby Surround/
356 audioMixdowns << "dpl1"
357 when /Dolby Pro Logic II/
358 audioMixdowns << "dpl2"
360 audioMixdowns << "6ch"
362 audioMixdowns << "auto"
366 audioSamplerates << audioTrack["AudioSamplerate"]
369 audioTracks << audioTrack["AudioTrack"].to_s
372 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
378 audioSamplerates << ","
380 audioTrackDRCs << ","
384 commandString << " -a " << audioTracks
385 commandString << " -E " << audioEncoders
386 commandString << " -B " << audioBitrates
387 commandString << " -6 " << audioMixdowns
388 commandString << " -R " << audioSamplerates
389 commandString << " -D " << audioTrackDRCs
392 commandString << " -f "
393 case hash["FileFormat"]
395 commandString << "mp4"
397 commandString << "mkv"
401 if hash["Mp4iPodCompatible"].to_i == 1
402 commandString << " -I"
406 if hash["Mp4LargeFile"] == 1
407 commandString << " -4"
411 if hash["PictureAutoCrop"] == 0
412 commandString << " --crop "
413 commandString << hash["PictureTopCrop"].to_s
415 commandString << hash["PictureBottomCrop"].to_s
417 commandString << hash["PictureLeftCrop"].to_s
419 commandString << hash["PictureRightCrop"].to_s
423 if hash["PictureWidth"] != 0
424 commandString << " -X "
425 commandString << hash["PictureWidth"].to_s
427 if hash["PictureHeight"] != 0
428 commandString << " -Y "
429 commandString << hash["PictureHeight"].to_s
433 if hash["Subtitles"] && hash["Subtitles"] != "None"
434 if hash["Subtitles"] == "Autoselect"
435 commandString << " --subtitle-scan"
437 commandString << " -s "
438 commandString << hash["Subtitles"]
443 if hash["UsesPictureFilters"] == 1
445 case hash["PictureDeinterlace"]
447 commandString << " --deinterlace=\"fast\""
449 commandString << " --deinterlace=\slow\""
451 commandString << " --deinterlace=\"slower\""
453 commandString << " --deinterlace=\"slowest\""
456 case hash["PictureDenoise"]
458 commandString << " --denoise=\"weak\""
460 commandString << " --denoise=\"medium\""
462 commandString << " --denoise=\"strong\""
465 if hash["PictureDetelecine"] == 2 then commandString << " --detelecine" end
466 if hash["PictureDeblock"] != 0 then commandString << " --deblock=" << hash["PictureDeblock"].to_s end
467 if hash["PictureDecomb"] == 2 then commandString << " --decomb" end
472 if hash["PicturePAR"] == 1
473 commandString << " --strict-anamorphic"
474 elsif hash["PicturePAR"] == 2
475 commandString << " --loose-anamorphic"
476 elsif hash["PicturePAR"] == 3
477 commandString << " --custom-anamorphic"
481 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
482 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
483 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
484 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
487 if hash["x264Option"] != ""
488 commandString << " -x "
489 commandString << hash["x264Option"]
492 # That's it, print to screen now
495 #puts "*" * @columnWidth
500 def generateCLIFolderParse( hash, depth ) # Shows the folder for wrappers to parse
508 commandString << " " << hash["PresetName"] << "\n\n"
512 def generateCLIFolderCloserParse( depth )
520 commandString << "\n\n"
524 def generateCLIParse(hash, depth) # Makes a CLI equivalent of all user presets, for wrappers to parse
529 commandString << '+ ' << hash["PresetName"] << ":"
532 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
533 commandString << " -e "
534 case hash["VideoEncoder"]
536 commandString << "x264"
538 commandString << "theora"
543 case hash["VideoQualityType"]
545 commandString << " -S " << hash["VideoTargetSize"]
547 commandString << " -b " << hash["VideoAvgBitrate"]
549 commandString << " -q " << hash["VideoQualitySlider"].to_s
553 if hash["VideoFramerate"] != "Same as source"
554 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
555 commandString << " -r " << "23.976"
556 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
557 commandString << " -r " << "29.97"
558 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
559 commandString << " -r " << "25"
561 commandString << " -r " << hash["VideoFramerate"]
564 if hash["VideoFrameratePFR"] == 1
565 commandString << " --pfr "
573 audioSamplerates = ""
576 audioCount = hash["AudioList"].size
578 hash["AudioList"].each do |audioTrack|
579 audioCount = audioCount - 1
582 audioBitrates << audioTrack["AudioBitrate"]
585 case audioTrack["AudioEncoder"]
587 audioEncoders << "copy:ac3"
589 audioEncoders << "ac3"
591 audioEncoders << "faac"
593 audioEncoders << "vorbis"
595 audioEncoders << "lame"
599 case audioTrack["AudioMixdown"]
601 audioMixdowns << "mono"
603 audioMixdowns << "stereo"
604 when /Dolby Surround/
605 audioMixdowns << "dpl1"
606 when /Dolby Pro Logic II/
607 audioMixdowns << "dpl2"
609 audioMixdowns << "6ch"
611 audioMixdowns << "auto"
615 audioSamplerates << audioTrack["AudioSamplerate"]
618 audioTracks << audioTrack["AudioTrack"].to_s
621 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
627 audioSamplerates << ","
629 audioTrackDRCs << ","
633 commandString << " -a " << audioTracks
634 commandString << " -E " << audioEncoders
635 commandString << " -B " << audioBitrates
636 commandString << " -6 " << audioMixdowns
637 commandString << " -R " << audioSamplerates
638 commandString << " -D " << audioTrackDRCs
641 commandString << " -f "
642 case hash["FileFormat"]
644 commandString << "mp4"
646 commandString << "mkv"
650 if hash["Mp4iPodCompatible"].to_i == 1
651 commandString << " -I"
655 if hash["Mp4LargeFile"] == 1
656 commandString << " -4"
660 if hash["PictureAutoCrop"] == 0
661 commandString << " --crop "
662 commandString << hash["PictureTopCrop"].to_s
664 commandString << hash["PictureBottomCrop"].to_s
666 commandString << hash["PictureLeftCrop"].to_s
668 commandString << hash["PictureRightCrop"].to_s
672 if hash["PictureWidth"] != 0
673 commandString << " -X "
674 commandString << hash["PictureWidth"].to_s
676 if hash["PictureHeight"] != 0
677 commandString << " -Y "
678 commandString << hash["PictureHeight"].to_s
682 if hash["Subtitles"] && hash["Subtitles"] != "None"
683 if hash["Subtitles"] == "Autoselect"
684 commandString << " --subtitle-scan"
686 commandString << " -s "
687 commandString << hash["Subtitles"]
692 if hash["UsesPictureFilters"] == 1
694 case hash["PictureDeinterlace"]
696 commandString << " --deinterlace=\"fast\""
698 commandString << " --deinterlace=\slow\""
700 commandString << " --deinterlace=\"slower\""
702 commandString << " --deinterlace=\"slowest\""
705 case hash["PictureDenoise"]
707 commandString << " --denoise=\"weak\""
709 commandString << " --denoise=\"medium\""
711 commandString << " --denoise=\"strong\""
714 if hash["PictureDetelecine"] == 2 then commandString << " --detelecine" end
715 if hash["PictureDeblock"] != 0 then commandString << " --deblock=" << hash["PictureDeblock"].to_s end
716 if hash["PictureDecomb"] == 2 then commandString << " --decomb" end
720 if hash["PicturePAR"] == 1
721 commandString << " --strict-anamorphic"
722 elsif hash["PicturePAR"] == 2
723 commandString << " --loose-anamorphic"
724 elsif hash["PicturePAR"] == 3
725 commandString << " --custom-anamorphic"
729 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
730 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
731 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
732 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
735 if hash["x264Option"] != ""
736 commandString << " -x "
737 commandString << hash["x264Option"]
740 # That's it, print to screen now
743 #puts "*" * @columnWidth
748 def generateAPIcalls(hash) # Makes a C version of the preset ready for coding into the CLI
750 commandString = "if (!strcmp(preset_name, \"" << hash["PresetName"] << "\"))\n{\n "
753 commandString << "if( !mux )\n "
754 commandString << "{\n "
756 case hash["FileFormat"]
758 commandString << " mux = " << "HB_MUX_MP4;\n "
760 commandString << " mux = " << "HB_MUX_MKV;\n "
762 commandString << "}\n "
765 if hash["Mp4iPodCompatible"].to_i == 1
766 commandString << "job->ipod_atom = 1;\n "
770 if hash["Mp4LargeFile"] == 1
771 commandString << "job->largeFileSize = 1;\n "
775 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
776 commandString << "vcodec = "
777 case hash["VideoEncoder"]
779 commandString << "HB_VCODEC_X264;\n "
781 commandString << "HB_VCODEC_THEORA;\n "
786 case hash["VideoQualityType"]
788 commandString << "size = " << hash["VideoTargetSize"] << ";\n "
790 commandString << "job->vbitrate = " << hash["VideoAvgBitrate"] << ";\n "
792 commandString << "job->vquality = " << hash["VideoQualitySlider"].to_s << ";\n "
796 if hash["VideoFramerate"] != "Same as source"
797 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
798 commandString << "job->vrate_base = " << "1126125;\n "
799 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
800 commandString << "job->vrate_base = " << "900900;\n "
801 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
802 commandString << "job->vrate_base = " << "1080000\n "
803 # Gotta add the rest of the framerates for completion's sake.
806 if hash["VideoFrameratePFR"] == 1
807 commandString << "job->cfr = 2;\n "
809 commandString << "job->cfr = 1;\n "
817 audioSamplerates = ""
820 audioCount = hash["AudioList"].size
822 hash["AudioList"].each do |audioTrack|
823 audioCount = audioCount - 1
826 audioBitrates << audioTrack["AudioBitrate"]
829 case audioTrack["AudioEncoder"]
831 audioEncoders << "copy:ac3"
833 audioEncoders << "ac3"
835 audioEncoders << "faac"
837 audioEncoders << "vorbis"
839 audioEncoders << "lame"
843 case audioTrack["AudioMixdown"]
845 audioMixdowns << "mono"
847 audioMixdowns << "stereo"
848 when /Dolby Surround/
849 audioMixdowns << "dpl1"
850 when /Dolby Pro Logic II/
851 audioMixdowns << "dpl2"
853 audioMixdowns << "6ch"
855 audioMixdowns << "auto"
859 audioSamplerates << audioTrack["AudioSamplerate"]
862 audioTracks << audioTrack["AudioTrack"].to_s
865 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
871 audioSamplerates << ","
873 audioTrackDRCs << ","
877 commandString << "if( !atracks )\n "
878 commandString << "{\n "
879 commandString << " atracks = strdup(\"" << audioTracks
880 commandString << "\");\n "
881 commandString << "}\n "
883 commandString << "if( !acodecs )\n "
884 commandString << "{\n "
885 commandString << " acodecs = strdup(\"" << audioEncoders
886 commandString << "\");\n "
887 commandString << "}\n "
889 commandString << "if( !abitrates )\n "
890 commandString << "{\n "
891 commandString << " abitrates = strdup(\"" << audioBitrates
892 commandString << "\");\n "
893 commandString << "}\n "
895 commandString << "if( !mixdowns )\n "
896 commandString << "{\n "
897 commandString << " mixdowns = strdup(\"" << audioMixdowns
898 commandString << "\");\n "
899 commandString << "}\n "
901 commandString << "if( !arates )\n "
902 commandString << "{\n "
903 commandString << " arates = strdup(\"" << audioSamplerates
904 commandString << "\");\n "
905 commandString << "}\n "
907 commandString << "if( !dynamic_range_compression )\n "
908 commandString << "{\n "
909 commandString << " dynamic_range_compression = strdup(\"" << audioTrackDRCs
910 commandString << "\");\n "
911 commandString << "}\n "
914 if hash["PictureAutoCrop"] == 0
915 commandString << "job->crop[0] = " << hash["PictureTopCrop"].to_s << ";\n "
916 commandString << "job->crop[1] = " << hash["PictureBottomCrop"].to_s << ";\n "
917 commandString << "job->crop[2] = " << hash["PictureLeftCrop"].to_s << ";\n "
918 commandString << "job->crop[4] = " << hash["PictureRightCrop"].to_s << ";\n "
922 if hash["PictureWidth"] != 0
923 commandString << "maxWidth = "
924 commandString << hash["PictureWidth"].to_s << ";\n "
926 if hash["PictureHeight"] != 0
927 commandString << "maxHeight = "
928 commandString << hash["PictureHeight"].to_s << ";\n "
932 if hash["Subtitles"] != "None"
933 if hash["Subtitles"] == "Autoselect"
934 commandString << "subtitle_scan = 1;\n "
936 commandString << "job->subtitle = "
937 commandString << ( hash["Subtitles"].to_i - 1).to_s << ";\n "
942 if hash["x264Option"] != ""
943 commandString << "if( !x264opts )\n "
944 commandString << "{\n "
945 commandString << " x264opts = strdup(\""
946 commandString << hash["x264Option"] << "\");\n "
947 commandString << "}\n "
951 if hash["UsesPictureFilters"] == 1
953 case hash["PictureDeinterlace"]
955 commandString << "deinterlace = 1;\n "
956 commandString << "deinterlace_opt = \"-1\";\n "
958 commandString << "deinterlace = 1;\n "
959 commandString << "deinterlace_opt = \"2\";\n "
961 commandString << "deinterlace = 1;\n "
962 commandString << "deinterlace_opt = \"0\";\n "
964 commandString << "deinterlace = 1;\n "
965 commandString << "deinterlace_opt = \"1:-1:1\";\n "
968 case hash["PictureDenoise"]
970 commandString << "denoise = 1;\n "
971 commandString << "denoise_opt = \"2:1:2:3\";\n "
973 commandString << "denoise = 1;\n "
974 commandString << "denoise_opt = \"3:2:2:3\";\n "
976 commandString << "denoise = 1;\n "
977 commandString << "denoise_opt = \"7:7:5:5\";\n "
980 if hash["PictureDetelecine"] == 2 then commandString << "detelecine = 1;\n " end
981 if hash["PictureDeblock"] != 0
983 commandString << "deblock = 1;\n "
984 commandString << "deblock_opt = \"" << hash["PictureDeblock"].to_s << "\";\n "
986 if hash["PictureDecomb"] == 2 then commandString << "decomb = 1;\n " end
991 if hash["PicturePAR"] != 0
992 commandString << "if( !anamorphic_mode )\n "
993 commandString << "{\n "
994 if hash["PicturePAR"] == 1
995 commandString << " anamorphic_mode = 1;\n "
996 elsif hash["PicturePAR"] == 2
997 commandString << " anamorphic_mode = 2;\n "
998 elsif hash["PicturePAR"] == 3
999 commandString << " anamorphic_mode = 3;\n "
1001 commandString << "}\n "
1005 if hash["ChapterMarkers"] == 1 then commandString << "job->chapter_markers = 1;\n " end
1006 if hash["VideoGrayScale"] == 1 then commandString << "job->grayscale = 1;\n " end
1007 if hash["VideoTwoPass"] == 1 then commandString << "twoPass = 1;\n " end
1008 if hash["VideoTurboTwoPass"] == 1 then commandString << "turbo_opts_enabled = 1;\n" end
1009 commandString << "\n"
1010 commandString << "}"
1012 # That's it, print to screen now
1014 #puts "*" * @columnWidth
1018 def generateAPIFolderList( hash, depth )
1021 commandString << " printf(\"\\n"
1023 commandString << " "
1026 commandString << "<"
1028 commandString << " " << hash["PresetName"]
1029 commandString << "\\n\");\n\n"
1033 def generateAPIFolderCloserList( depth )
1036 commandString << " printf(\"\\n"
1038 commandString << " "
1041 commandString << ">"
1043 commandString << "\\n\");\n\n"
1047 def generateAPIList(hash, depth) # Makes a list of the CLI options a built-in CLI preset uses, for wrappers to parse
1049 commandString << " printf(\"\\n"
1051 commandString << " "
1054 commandString << "+ " << hash["PresetName"] << ": "
1057 if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
1058 commandString << " -e "
1059 case hash["VideoEncoder"]
1061 commandString << "x264 "
1063 commandString << "theora "
1068 case hash["VideoQualityType"]
1070 commandString << " -S " << hash["VideoTargetSize"]
1072 commandString << " -b " << hash["VideoAvgBitrate"]
1074 commandString << " -q " << hash["VideoQualitySlider"].to_s
1078 if hash["VideoFramerate"] != "Same as source"
1079 if hash["VideoFramerate"] == "23.976 (NTSC Film)"
1080 commandString << " -r " << "23.976"
1081 elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
1082 commandString << " -r " << "29.97"
1083 elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
1084 commandString << " -r " << "25"
1086 commandString << " -r " << hash["VideoFramerate"]
1089 if hash["VideoFrameratePFR"] == 1
1090 commandString << " --pfr "
1098 audioSamplerates = ""
1101 audioCount = hash["AudioList"].size
1103 hash["AudioList"].each do |audioTrack|
1104 audioCount = audioCount - 1
1107 audioBitrates << audioTrack["AudioBitrate"]
1110 case audioTrack["AudioEncoder"]
1112 audioEncoders << "copy:ac3"
1114 audioEncoders << "ac3"
1116 audioEncoders << "faac"
1118 audioEncoders << "vorbis"
1120 audioEncoders << "lame"
1124 case audioTrack["AudioMixdown"]
1126 audioMixdowns << "mono"
1128 audioMixdowns << "stereo"
1129 when /Dolby Surround/
1130 audioMixdowns << "dpl1"
1131 when /Dolby Pro Logic II/
1132 audioMixdowns << "dpl2"
1134 audioMixdowns << "6ch"
1136 audioMixdowns << "auto"
1140 audioSamplerates << audioTrack["AudioSamplerate"]
1143 audioTracks << audioTrack["AudioTrack"].to_s
1146 audioTrackDRCs << audioTrack["AudioTrackDRCSlider"].to_s
1149 audioBitrates << ","
1150 audioEncoders << ","
1151 audioMixdowns << ","
1152 audioSamplerates << ","
1154 audioTrackDRCs << ","
1158 commandString << " -a " << audioTracks
1159 commandString << " -E " << audioEncoders
1160 commandString << " -B " << audioBitrates
1161 commandString << " -6 " << audioMixdowns
1162 commandString << " -R " << audioSamplerates
1163 commandString << " -D " << audioTrackDRCs
1166 commandString << " -f "
1167 case hash["FileFormat"]
1169 commandString << "mp4"
1171 commandString << "mkv"
1175 if hash["Mp4iPodCompatible"].to_i == 1
1176 commandString << " -I"
1180 if hash["Mp4LargeFile"] == 1
1181 commandString << " -4"
1185 if hash["PictureAutoCrop"] == 0
1186 commandString << " --crop "
1187 commandString << hash["PictureTopCrop"].to_s
1188 commandString << ":"
1189 commandString << hash["PictureBottomCrop"].to_s
1190 commandString << ":"
1191 commandString << hash["PictureLeftCrop"].to_s
1192 commandString << ":"
1193 commandString << hash["PictureRightCrop"].to_s
1197 if hash["PictureWidth"] != 0
1198 commandString << " -X "
1199 commandString << hash["PictureWidth"].to_s
1201 if hash["PictureHeight"] != 0
1202 commandString << " -Y "
1203 commandString << hash["PictureHeight"].to_s
1207 if hash["Subtitles"] && hash["Subtitles"] != "None"
1208 if hash["Subtitles"] == "Autoselect"
1209 commandString << " --subtitle-scan"
1211 commandString << " -s "
1212 commandString << hash["Subtitles"]
1217 if hash["UsesPictureFilters"] == 1
1219 case hash["PictureDeinterlace"]
1221 commandString << " --deinterlace=\\\"fast\\\""
1223 commandString << " --deinterlace=\\\slow\\\""
1225 commandString << " --deinterlace=\\\"slower\\\""
1227 commandString << " --deinterlace=\\\"slowest\\\""
1230 case hash["PictureDenoise"]
1232 commandString << " --denoise=\\\"weak\\\""
1234 commandString << " --denoise=\\\"medium\\\""
1236 commandString << " --denoise=\\\"strong\\\""
1239 if hash["PictureDetelecine"] == 2 then commandString << " --detelecine" end
1240 if hash["PictureDeblock"] != 0 then commandString << " --deblock=" << hash["PictureDeblock"].to_s end
1241 if hash["PictureDecomb"] == 2 then commandString << " --decomb" end
1245 if hash["PicturePAR"] == 1
1246 commandString << " --strict-anamorphic"
1247 elsif hash["PicturePAR"] == 2
1248 commandString << " --loose-anamorphic"
1249 elsif hash["PicturePAR"] == 3
1250 commandString << " --custom-anamorphic"
1254 if hash["ChapterMarkers"] == 1 then commandString << " -m" end
1255 if hash["VideoGrayScale"] == 1 then commandString << " -g" end
1256 if hash["VideoTwoPass"] == 1 then commandString << " -2" end
1257 if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
1260 if hash["x264Option"] != ""
1261 commandString << " -x "
1262 commandString << hash["x264Option"]
1265 commandString << "\\n\");"
1267 # That's it, print to screen now
1274 # First grab the specified CLI options
1275 options = readOptions
1277 # Only run if one of the useful CLI flags have been passed
1278 if options.cliraw == true || options.cliparse == true || options.api == true || options.apilist == true
1279 # This line is the ignition -- generates hashes of
1280 # presets and then displays them to the screen
1281 # with the options the user selects on the CLI.
1282 Display.new( Presets.new.hashMasterList, options )
1284 # Direct the user to the help
1285 puts "\n\tUsage: manicure.rb [options]"
1286 puts "\tSee help with -h or --help"