#! /usr/bin/ruby # manincure.rb version 0.1 $presetMasterList = [] $hashMasterList = [] $presetCount = 0 $outputCommands =[] class Command @@aPSNRmetric = {"metric" => 0, "opt" => 0, "value" => 0} @@gPSNRmetric = {"metric" => 0, "opt" => 0, "value" => 0} @@mSSIMmetric = {"metric" => 0, "opt" => 0, "value" => 0} @@aBitratemetric = {"metric" => 0, "opt" => 0, "value" => 0} @@timeMetric = {"metric" => 0, "staitcOpts" => 0} def initialize(command, presetName, iteration) @formattedCommand = '( '+command+' ) 2>/tmp/peakaboo.log' @presetName = presetName @iteration = iteration end def getFormattedCommand @formattedCommand end def getIteration @iteration end def run puts '*'+`#{@formattedCommand}` end def parseLog puts '*********' puts '*' @averagePSNR = `cat /tmp/peakaboo.log | grep "kb/s" | awk '{print $8}' | sed -e 's/Avg://'` puts '* Average PSNR: '+@averagePSNR.to_s if @averagePSNR.to_f > @@aPSNRmetric["metric"].to_f @@aPSNRmetric["metric"] = @averagePSNR.chomp @@aPSNRmetric["presetName"] = @presetName.chomp end @globalPSNR = `cat /tmp/peakaboo.log | grep "kb/s" | awk '{print $9}' | sed -e 's/Global://'` puts '* Global PSNR: '+@globalPSNR.to_s if @globalPSNR.to_f > @@gPSNRmetric["metric"].to_f @@gPSNRmetric["metric"] = @globalPSNR.chomp @@gPSNRmetric["presetName"] = @presetName.chomp end @meanSSIM = `cat /tmp/peakaboo.log | grep "SSIM" | awk '{print $5}' | sed -e 's/Y://'` puts '* Mean SSIM: '+@meanSSIM.to_s if @meanSSIM.to_f > @@mSSIMmetric["metric"].to_f @@mSSIMmetric["metric"] = @meanSSIM.chomp @@mSSIMmetric["presetName"] = @presetName.chomp end @averageBitrate = `cat /tmp/peakaboo.log | grep kb/s:*| awk '{print $NF}' | awk -F\: '{print $2}'` puts '* Average Bitrate: '+@averageBitrate.to_s if ((@averageBitrate.to_f < @@aBitratemetric["metric"].to_f) || (@@aBitratemetric["metric"].to_f == 0)) @@aBitratemetric["metric"] = @averageBitrate.chomp @@aBitratemetric["presetName"] = @presetName.chomp end puts '* Elapsed Time: '+@elapsedTime.to_s if ( (@elapsedTime < @@timeMetric["metric"].to_f) || (@@timeMetric["metric"].to_f == 0) ) @@timeMetric["metric"] = @elapsedTime.to_s @@timeMetric["presetName"] = @presetName.chomp end puts '*' puts '*********' end def compareMetrics puts '*********' puts '*' puts '* Results' puts '*' puts '*********' puts '*' puts '* The best average PSNR is '+@@aPSNRmetric["metric"].to_s+' from '+@@aPSNRmetric["presetName"].to_s puts '* The best global PSNR is '+@@gPSNRmetric["metric"].to_s+' from '+@@gPSNRmetric["presetName"].to_s puts '* The best mean SSIM is '+@@mSSIMmetric["metric"].to_s+' from '+@@mSSIMmetric["presetName"].to_s puts '* The lowest bitrate is '+@@aBitratemetric["metric"].to_s+' from '+@@aBitratemetric["presetName"].to_s puts '*' puts '*********' puts '*********' end def runReadAndParse(command, j) #puts command.getFormattedCommand puts '*' puts '* Running: '+@presetName puts '*' startTime = Time.new command.run endTime = Time.new @elapsedTime = endTime.to_f - startTime.to_f command.parseLog end def buildDiv div = '
SettingBitrateAvg. PSNRGlo. PSNRSSIM
'+@presetName.chomp+''+@averageBitrate.chomp+''+@averagePSNR.chomp+''+@globalPSNR.chomp+''+@meanSSIM.chomp+'
' @div = div end def Web web = {} web["row"] = ''+@presetName.chomp+''+@averageBitrate.chomp+''+@averagePSNR.chomp+''+@globalPSNR.chomp+''+@meanSSIM.chomp+'' return web end end def buildWebPage(outputCommands) web = [] puts 'Peakaboo Results' puts '' outputCommands.each do |command| web = command.Web puts web["row"] end puts '
SettingBitrateAvg. PSNRGlo. PSNRSSIM
' puts '' end class PresetClass @@columnWidth=40 def initialize rawPresets = readPresetPlist presetStew = [] presetStew = rawPresets.split("\n") presetStew = cleanStew(presetStew) presetBreaks = findPresetBreaks(presetStew) i = 0 while i <= presetBreaks.size if i == 0 #first preset $presetMasterList[i] = presetStew.slice(0..presetBreaks[i].to_i) elsif i < presetBreaks.size #middle presets $presetMasterList[i] = presetStew.slice(presetBreaks[i-1].to_i..presetBreaks[i].to_i) else #final preset $presetMasterList[i] = presetStew.slice(presetBreaks[i-1].to_i..presetStew.length) end i += 1 end buildPresetHash displayCommandStrings end def readPresetPlist # Grab the .plist and store it in presets homeLocation = `echo $HOME`.chomp inputFile = homeLocation+'/Library/Application\ Support/HandBrake/UserPresets.plist' parseCommand = 'cat '+inputFile+' | sed -e \'s/<[a-z]*>//\' -e \'s/<\/[a-z]*>//\' -e \'/<[?!]/d\' ' puts "\n\n" rawPresets = `#{parseCommand}` end def cleanStew(presetStew) #remove tabbed white space presetStew.each do |oneline| oneline.strip! end end def findPresetBreaks(presetStew) #figure out where each preset starts and ends i = 0 j = 0 presetBreaks =[] presetStew.each do |presetLine| if presetLine =~ /AudioBitRate/ presetBreaks[j] = i-1 j += 1 end i += 1 end return presetBreaks end def buildPresetHash #fill up $hashMasterList with hashes of all key/value pairs j = 0 $presetMasterList.each do |singleServing| #iterate presets tempHash = Hash.new i = 1 while i < singleServing.length tempHash[singleServing[i]] = singleServing[i+1] i += 2 end $hashMasterList[j]=tempHash j += 1 end end def displayCommandStrings $hashMasterList.each do |hash| if hash.key?("PresetName") #displayHeader(hash) generateCLIString(hash) end end end def displayHeader(hash) puts "*" * @@columnWidth puts '* '+hash["PresetName"].to_s.center(@@columnWidth-4)+' *' puts '~' * @@columnWidth puts hash["PresetDescription"].to_s.center(@@columnWidth).gsub(/\n/," ").scan(/\S.{0,#{@@columnWidth-2}}\S(?=\s|$)|\S+/) puts '~' * @@columnWidth puts "#{hash["FileCodecs"]}".center(@@columnWidth) if hash["Type"].to_i == 1 puts "Custom Preset".center(@@columnWidth) end if hash["Default"].to_i == 1 puts "This is your default preset.".center(@@columnWidth) end puts "~" * @@columnWidth # puts "\n" end def generateCLIString(hash) commandString = "" commandString << './HandBrakeCLI -i ~/Movies/DVD_VIDEO -c 8 -o /Volumes/Walter/' commandString << hash["PresetName"].gsub(' ', '_') commandString << '.' #Filename suffix case hash["FileFormat"] when /MP4/ commandString << "mp4 " when /AVI/ commandString << "avi " when /OGM/ commandString << "ogm " when /MKV/ commandString << "mkv " end #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 end #VideoRateControl case hash["VideoQualityType"].to_i when 0 commandString << " -S " << hash["VideoTargetSize"] when 1 commandString << " -b " << hash["VideoAvgBitrate"] when 2 commandString << " -q " << hash["VideoQualitySlider"] end #FPS if hash["VideoFramerate"] != "Same as source" if hash["VideoFramerate"] == "23.976 (NTSC Film)" commandString << " -r " << "23.976" elsif hash["VideoFramerate"] == "29.97 (NTSC Video)" commandString << " -r " << "29.97" else commandString << " -r " << hash["VideoFramerate"] end end #Audio bitrate commandString << " -B " << hash["AudioBitRate"] #Audio samplerate commandString << " -R " << hash["AudioSampleRate"] #Audio encoder commandString << " -E " case hash["FileCodecs"] when /AAC/ commandString << "faac" when /AC-3/ commandString << "ac3" when /Vorbis/ commandString << "vorbis" when /MP3/ commandString << "lame" end #Container commandString << " -f " case hash["FileFormat"] when /MP4/ commandString << "mp4" when /AVI/ commandString << "avi" when /OGM/ commandString << "ogm" when /MKV/ commandString << "mkv" end #Cropping if !hash["PictureAutoCrop"].to_i commandString << " --crop " commandString << hash["PictureTopCrop"] commandString << ":" commandString << hash["PictureBottomCrop"] commandString << ":" commandString << hash["PictureLeftCrop"] commandString << ":" commandString << hash["PictureRightCrop"] end #Dimensions if hash["PictureWidth"].to_i != 0 commandString << " -w " commandString << hash["PictureWidth"] end if hash["PictureHeight"].to_i != 0 commandString << " -l " commandString << hash["PictureHeight"] end #Subtitles if hash["Subtitles"] != "None" commandString << " -s " commandString << hash["Subtitles"] end #x264 Options if hash["x264Option"] != "" commandString << " -x " commandString << hash["x264Option"] end #Booleans if hash["ChapterMarkers"].to_i == 1 then commandString << " -m" end if hash["PictureDeinterlace"].to_i == 1 then commandString << " -d" end if hash["PicturePAR"].to_i == 1 then commandString << " -p" end if hash["VideoGrayScale"].to_i == 1 then commandString << " -g" end if hash["VideoTwoPass"].to_i == 1 then commandString << " -2" end if hash["VideoTurboTwoPass"].to_i == 1 then commandString << " -T" end # That's it, print to screen now $outputCommands[$presetCount] = Command.new(commandString, hash["PresetName"], $presetCount) $outputCommands[$presetCount].runReadAndParse($outputCommands[$presetCount], $presetCount) $presetCount += 1 #puts "*" * @@columnWidth puts "\n" end end PresetClass.new $outputCommands[0].compareMetrics buildWebPage($outputCommands)