OSDN Git Service

Adds Dark_Shikari's vbv 1 pass patch for x264
[handbrake-jp/handbrake-jp-git.git] / scripts / manicure.rb
index 7c398e5..55a4e64 100755 (executable)
@@ -5,31 +5,79 @@
 # Homepage: <http://handbrake.m0k.org/>.
 # It may be used under the terms of the GNU General Public License.
 
-# This script parses HandBrake's Mac presets into hashes, which can be displayed in various formats for use by the CLI and various wrappers.
+# This script parses HandBrake's Mac presets into hashes, which can
+# be displayed in various formats for use by the CLI and its wrappers.
 
 # For handling command line arguments to the script
 require 'optparse'
 require 'ostruct'
 
+# CLI options: (code based on http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/index.html )
+def readOptions
+  
+  # --[no-]cli-raw, -r gives raw CLI for wiki
+  # --cli-parse, -p gives CLI strings for wrappers
+  # --api, -a gives preset code for test.c
+  # --api-list, -A gives CLI strings for --preset-list display
+  # --[no-]header, -h turns off banner display
+  options = OpenStruct.new
+  options.cliraw = false
+  options.cliparse = false
+  options.api = false
+  options.apilist = false
+  options.header = false
+  
+  opts = OptionParser.new do |opts|
+    opts.banner = "Usage: manicure.rb [options]"
+    
+    opts.separator ""
+    opts.separator "Options:"
+    
+    opts.on("-r", "--cli-raw", "Gives example strings for the HB wiki") do |raw|
+      options.cliraw = raw
+      option_set = true
+    end
+    
+    opts.on("-p", "--cli-parse", "Gives presets as wrapper-parseable CLI", " option strings") do |par|
+      options.cliparse = par
+    end
+    
+    opts.on("-a", "--api", "Gives preset code for test.c") do |api|
+      options.api = api
+    end
+    
+    opts.on("-A", "--api-list", "Gives code for test.c's --preset-list", " options") do |alist|
+      options.apilist = alist
+    end
+    
+    opts.on("-H", "--Header", "Display a banner before each preset") do |head|
+      options.header = head
+    end
+    
+    opts.on_tail("-h", "--help", "Show this message") do
+        puts opts
+        exit
+    end
+  end.parse!
+  
+  return options
+  
+end
+
 # These arrays contain all the other presets and hashes that are going to be used.
 # Yeah, they're global variables. In an object-oriented scripting language.
 # Real smooth, huh?
-$presetMasterList = []
-$hashMasterList = []
 
-# This class is pretty much everything. It contains multitudes.
-class PresetClass
+# This class parses the user's presets .plist into an array of hashes
+class Presets
   
-  # A width of 40 gives nice, compact output.
-  @@columnWidth=40
+  attr_reader :hashMasterList
   
   # Running initialization runs everything.
   # Calling it will also call the parser
   # and display output.
-  def initialize(options)
+  def initialize
     
-    @options = options
-
     # Grab input from the user's presets .plist
     rawPresets = readPresetPlist
     
@@ -47,26 +95,27 @@ class PresetClass
 
     # Now it's time to use that info to store each
     # preset individually, in the master list.
+    @presetMasterList = []
     i = 0
     while i <= presetBreaks.size    
       if i == 0 #first preset
         # Grab the stew, up to the 1st offset.
-        $presetMasterList[i] = presetStew.slice(0..presetBreaks[i].to_i)
+        @presetMasterList[i] = presetStew.slice(0..presetBreaks[i].to_i)
       elsif i < presetBreaks.size #middle presets
         # Grab the stew from the last offset to the current..
-        $presetMasterList[i] = presetStew.slice(presetBreaks[i-1].to_i..presetBreaks[i].to_i)
+        @presetMasterList[i] = presetStew.slice(presetBreaks[i-1].to_i..presetBreaks[i].to_i)
       else #final preset
         # Grab the stew, starting at the last offset, all the way to the end.
-        $presetMasterList[i] = presetStew.slice(presetBreaks[i-1].to_i..presetStew.length)
+        @presetMasterList[i] = presetStew.slice(presetBreaks[i-1].to_i..presetStew.length)
       end
       i += 1
     end
     
     # Parse the presets into hashes
+    @hashMasterList = []
+    
     buildPresetHash
     
-    # Print to screen.
-    displayCommandStrings
   end
 
   def readPresetPlist # Grab the .plist and store it in presets
@@ -106,33 +155,51 @@ class PresetClass
     return presetBreaks
   end
 
-  def buildPresetHash #fill up $hashMasterList with hashes of all key/value pairs
+  def buildPresetHash #fill up @hashMasterList with hashes of all key/value pairs
     j = 0
     
     # Iterate through all presets, treating each in turn as singleServing
-    $presetMasterList.each do |singleServing|
-
+    @presetMasterList.each do |singleServing|
+      
+      # Initialize the hash for preset j (aka singleServing)
+      @hashMasterList[j] = Hash.new
+      
       # Each key and value are on sequential lines.
       # Iterating through by twos, use that to build a hash.
       # Each key, on line i, paired with its value, on line i+1  
-      tempHash = Hash.new
       i = 1
       while i < singleServing.length
-        tempHash[singleServing[i]] = singleServing[i+1]
+        @hashMasterList[j].store( singleServing[i],  singleServing[i+1] )
         i += 2
       end
-      
-      # Now store that hash in the master list.
-      $hashMasterList[j]=tempHash
-      
+            
       j += 1  
     end   
   end
 
+end
+
+# This class displays the presets to stdout in various formats.
+class Display
+  
+  
+  def initialize(hashMasterList, options)
+  
+    @hashMasterList = hashMasterList
+    @options = options
+
+    # A width of 40 gives nice, compact output.
+    @columnWidth=40
+    
+    # Print to screen.
+    displayCommandStrings
+    
+  end
+  
   def displayCommandStrings # prints everything to screen
     
     # Iterate through the hashes.    
-    $hashMasterList.each do |hash|
+    @hashMasterList.each do |hash|
     
       # Check to make there are valid contents
       if hash.key?("PresetName")
@@ -167,35 +234,35 @@ class PresetClass
   def displayHeader(hash) # A distinct banner to separate each preset
     
     # Print a line of asterisks
-    puts "*" * @@columnWidth
+    puts "*" * @columnWidth
     
     # Print the name, centered
-    puts '* '+hash["PresetName"].to_s.center(@@columnWidth-4)+' *'
+    puts '* '+hash["PresetName"].to_s.center(@columnWidth-4)+' *'
     
     # Print a line of dashes
-    puts '~' * @@columnWidth
+    puts '~' * @columnWidth
     
     # Print the description, centered and word-wrapped
-    puts hash["PresetDescription"].to_s.center(@@columnWidth).gsub(/\n/," ").scan(/\S.{0,#{@@columnWidth-2}}\S(?=\s|$)|\S+/)
+    puts hash["PresetDescription"].to_s.center(@columnWidth).gsub(/\n/," ").scan(/\S.{0,#{@columnWidth-2}}\S(?=\s|$)|\S+/)
     
     # Print another line of dashes
-    puts '~' * @@columnWidth
+    puts '~' * @columnWidth
     
     # Print the formats the preset uses
-    puts "#{hash["FileCodecs"]}".center(@@columnWidth)
+    puts "#{hash["FileCodecs"]}".center(@columnWidth)
     
     # Note if the preset isn't built-in
     if hash["Type"].to_i == 1
-      puts "Custom Preset".center(@@columnWidth)
+      puts "Custom Preset".center(@columnWidth)
     end
 
     # Note if the preset is marked as default.
     if hash["Default"].to_i == 1
-      puts "This is your default preset.".center(@@columnWidth)
+      puts "This is your default preset.".center(@columnWidth)
     end
     
     # End with a line of tildes.  
-    puts "~" * @@columnWidth
+    puts "~" * @columnWidth
     
   end
   
@@ -218,13 +285,7 @@ class PresetClass
     #Video encoder
     if hash["VideoEncoder"] != "FFmpeg"
       commandString << " -e "
-      if hash["VideoEncoder"] == "x264 (h.264 Main)"
-        commandString << "x264"
-      elsif hash["VideoEncoder"] == "x264 (h.264 iPod)"
-        commandString << "x264b30"
-      else
-        commandString << hash["VideoEncoder"].to_s.downcase
-      end
+      commandString << hash["VideoEncoder"].to_s.downcase
     end
 
     #VideoRateControl
@@ -251,9 +312,11 @@ class PresetClass
     #Audio encoder (only specifiy bitrate and samplerate when not doing AC-3 pass-thru)
     commandString << " -E "
     case hash["FileCodecs"]
-    when /AC-3/
+    when /AAC + AC3 Audio/
+      commandString << "aac+ac3"
+    when /AC-3 /
       commandString << "ac3"
-    when /AAC/
+    when /AAC Audio/
       commandString << "faac" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
     when /Vorbis/
       commandString << "vorbis" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
@@ -274,6 +337,16 @@ class PresetClass
       commandString << "mkv"
     end
     
+    #iPod MP4 atom
+    if hash["Mp4iPodCompatible"].to_i == 1
+      commandString << " -I"
+    end
+    
+    # 64-bit files
+    if hash["Mp4LargeFile"].to_i == 1
+      commandString << " -4"
+    end
+    
     #Cropping
     if !hash["PictureAutoCrop"].to_i
       commandString << " --crop "
@@ -346,7 +419,7 @@ class PresetClass
     # That's it, print to screen now
     puts commandString
     
-    #puts "*" * @@columnWidth
+    #puts "*" * @columnWidth
 
     puts  "\n"
   end
@@ -358,13 +431,7 @@ class PresetClass
     #Video encoder
     if hash["VideoEncoder"] != "FFmpeg"
       commandString << " -e "
-      if hash["VideoEncoder"] == "x264 (h.264 Main)"
-        commandString << "x264"
-      elsif hash["VideoEncoder"] == "x264 (h.264 iPod)"
-        commandString << "x264b30"
-      else
-        commandString << hash["VideoEncoder"].to_s.downcase
-      end
+      commandString << hash["VideoEncoder"].to_s.downcase
     end
 
     #VideoRateControl
@@ -391,9 +458,11 @@ class PresetClass
     #Audio encoder (only include bitrate and samplerate when not doing AC3 passthru)
     commandString << " -E "
     case hash["FileCodecs"]
+    when /AC3 Audio/
+      commandString << "aac+ac3"
     when /AC-3/
       commandString << "ac3"
-    when /AAC/
+    when /AAC Audio/
       commandString << "faac" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
     when /Vorbis/
       commandString << "vorbis" << " -B " << hash["AudioBitRate"] << " -R " << hash["AudioSampleRate"]
@@ -414,6 +483,16 @@ class PresetClass
       commandString << "mkv"
     end
     
+    #iPod MP4 atom
+    if hash["Mp4iPodCompatible"].to_i == 1
+      commandString << " -I"
+    end
+    
+    # 64-bit files
+    if hash["Mp4LargeFile"].to_i == 1
+      commandString << " -4"
+    end
+    
     #Cropping
     if !hash["PictureAutoCrop"].to_i
       commandString << " --crop "
@@ -486,7 +565,7 @@ class PresetClass
     # That's it, print to screen now
     puts commandString
     
-    #puts "*" * @@columnWidth
+    #puts "*" * @columnWidth
 
     puts  "\n"
   end
@@ -507,13 +586,21 @@ class PresetClass
       commandString << "mux = " << "HB_MUX_MKV;\n    "
     end
     
+    #iPod MP4 atom
+    if hash["Mp4iPodCompatible"].to_i == 1
+      commandString << "job->ipod_atom = 1;\n   "
+    end
+    
+    # 64-bit files
+    if hash["Mp4LargeFile"].to_i == 1
+      commandString << "job->largeFileSize = 1;\n"
+    end
+    
     #Video encoder
     if hash["VideoEncoder"] != "FFmpeg"
       commandString << "vcodec = "
-      if hash["VideoEncoder"] == "x264 (h.264 Main)"
+      if hash["VideoEncoder"] == "x264"
         commandString << "HB_VCODEC_X264;\n    "
-      elsif hash["VideoEncoder"] == "x264 (h.264 iPod)"
-        commandString << "HB_VCODEC_X264;\njob->h264_level = 30;\n    "
       elsif hash["VideoEncoder"].to_s.downcase == "xvid"
         commandString << "HB_VCODEC_XVID;\n    "        
       end
@@ -565,7 +652,11 @@ class PresetClass
     #Audio encoder
     commandString << "acodec = "
     case hash["FileCodecs"]
-    when /AAC/
+    when /AC3 Audio/
+      commandString << "HB_ACODEC_FAAC;\n    "
+      commandString << "audio_mixdown = HB_AMIXDOWN_DOLBYPLII_AC3;\n    "
+      commandString << "arate = 48000;\n    "
+    when /AAC Audio/
       commandString << "HB_ACODEC_FAAC;\n    "
     when /AC-3/
       commandString << "HB_ACODEC_AC3;\n    "
@@ -614,10 +705,10 @@ class PresetClass
         commandString << "deinterlace_opt = \"-1\";\n    "
       when 2
         commandString << "deinterlace = 1;\n    "
-        commandString << "deinterlace_opt = \"0\";\n    "
+        commandString << "deinterlace_opt = \"2\";\n    "
       when 3
         commandString << "deinterlace = 1;\n    "
-        commandString << "deinterlace_opt = \"2:-1:1\";\n    "
+        commandString << "deinterlace_opt = \"0\";\n    "
       when 4
         commandString << "deinterlace = 1;\n    "
         commandString << "deinterlace_opt = \"1:-1:1\";\n    "
@@ -651,7 +742,7 @@ class PresetClass
     
     # That's it, print to screen now
     puts commandString
-    #puts "*" * @@columnWidth
+    #puts "*" * @columnWidth
     puts  "\n"
   end
 
@@ -662,13 +753,7 @@ class PresetClass
     #Video encoder
     if hash["VideoEncoder"] != "FFmpeg"
       commandString << " -e "
-      if hash["VideoEncoder"] == "x264 (h.264 Main)"
-        commandString << "x264"
-      elsif hash["VideoEncoder"] == "x264 (h.264 iPod)"
-        commandString << "x264b30"
-      else
-        commandString << hash["VideoEncoder"].to_s.downcase
-      end
+      commandString << hash["VideoEncoder"].to_s.downcase
     end
 
     #VideoRateControl
@@ -703,7 +788,9 @@ class PresetClass
     #Audio encoder
     commandString << " -E "
     case hash["FileCodecs"]
-    when /AAC/
+    when /AC3 Audio/
+      commandString << "aac+ac3"
+    when /AAC Audio/
       commandString << "faac"
     when /AC-3/
       commandString << "ac3"
@@ -726,6 +813,16 @@ class PresetClass
       commandString << "mkv"
     end
     
+    #iPod MP4 atom
+    if hash["Mp4iPodCompatible"].to_i == 1
+      commandString << " -I"
+    end
+    
+    # 64-bit files
+    if hash["Mp4LargeFile"].to_i == 1
+      commandString << " -4"
+    end
+    
     #Cropping
     if !hash["PictureAutoCrop"].to_i
       commandString << " --crop "
@@ -801,58 +898,18 @@ class PresetClass
     puts commandString
     puts  "\n"
   end
+  
 end
 
-# CLI options: (code based on http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/index.html )
-# --[no-]cli-raw, -r gives raw CLI for wiki
-# --cli-parse, -p gives CLI strings for wrappers
-# --api, -a gives preset code for test.c
-# --api-list, -A gives CLI strings for --preset-list display
-# --[no-]header, -h turns off banner display
-options = OpenStruct.new
-options.cliraw = false
-options.cliparse = false
-options.api = false
-options.apilist = false
-options.header = false
-
-opts = OptionParser.new do |opts|
-  opts.banner = "Usage: manicure.rb [options]"
-  
-  opts.separator ""
-  opts.separator "Options:"
-  
-  opts.on("-r", "--cli-raw", "Gives example strings for the HB wiki") do |r|
-    options.cliraw = r
-    option_set = true
-  end
-  
-  opts.on("-p", "--cli-parse", "Gives presets as wrapper-parseable CLI", " option strings") do |p|
-    options.cliparse = p
-  end
-  
-  opts.on("-a", "--api", "Gives preset code for test.c") do |api|
-    options.api = api
-  end
-  
-  opts.on("-A", "--api-list", "Gives code for test.c's --preset-list", " options") do |A|
-    options.apilist = A
-  end
-  
-  opts.on("-H", "--Header", "Display a banner before each preset") do |H|
-    options.header = H
-  end
-  
-  opts.on_tail("-h", "--help", "Show this message") do
-      puts opts
-      exit
-  end
-end.parse!
+# First grab the specified CLI options
+options = readOptions
 
 # Only run if one of the useful CLI flags have been passed
 if options.cliraw == true || options.cliparse == true || options.api == true || options.apilist == true
-  # This line is the ignition.
-  PresetClass.new(options)
+  # This line is the ignition -- generates hashes of
+  # presets and then displays them to the screen
+  # with the options the user selects on the CLI. 
+  Display.new( Presets.new.hashMasterList, options )
 else
   # Direct the user to the help
   puts "\n\tUsage: manicure.rb [options]"