#!/usr/bin/env ruby # Copyright (c) 2008, Bem Jones-Bey # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. require 'optparse' require 'pp' require 'yaml' class BatchHB def initialize @options = { "input_device" => nil, "dvdinfo" => 'dvdinfo.yaml', # FIXME we need something that works on Windows as well. "config" => ENV['HOME'] + '/.batchhbrc', "handbrake" => 'HandBrakeCLI', } end def parse_options(args) opts = OptionParser.new do |opts| opts.banner = "Usage"" batchhb [@options]" opts.separator "" opts.separator "Options""" opts.on("-h", "--help", "Print this help") do |h| print opts.help exit 0 end opts.on("-i", "--input-device DEVICE", "Rip from file or device DEVICE") do |dev| @options["input_device"] = dev end opts.on("-d", "--dvd-info FILE", "YAML file describing the DVD to rip") do |di| @options["dvdinfo"] = di end opts.on("-c", "--config FILE", "Read configuration from FILE") do |config| @options["config"] = config end opts.on("-h", "--handbrake HANDBRAKE", "Run command line handbrake executable HANDBRAKE") do |hb| @options["handbrake"] = hb end end begin opts.parse!(args) rescue OptionParser::InvalidOption => io puts io print opts.help exit 1 end end def load_config @config = File.open(@options["config"]) { |cf| YAML::load(cf) } unless @options.nil?: @options.each do |key,value| if value: @config[key] = value end end end end def load_dvd_info @dvd_info = File.open(@config["dvdinfo"]) { |df| YAML::load(df) } end def rip local_config = @config.dup # shallow copy, don't modify contents @dvd_info["titles"].each do |title| local_config["output_name"] = title["name"] + '.' + @config["output_format"] local_config["title_number"] = title["number"] local_config["audio_track"] = title["audio_track"] if title.has_key?("chapters"): local_config["chapters"] = title["chapters"] end if title["subtitles"]: local_config["subtitle_track"] = title["subtitle_track"] end puts "Now encoding #{local_config["output_name"]}" run_handbrake(local_config) end end def run_handbrake(cf) command = [ cf["handbrake"] ] cf.each do |key,value| boolean_arg = false arg = case key when "input_device": '-i' when "cpu_count": '-C' when "output_format": '-f' when "max_height": '-Y' when "max_width": '-X' when "video_encoder": '-e' when "video_framerate": '-r' when "video_quality": '-q' when "video_file_size": '-S' when "video_bitrate": '-b' when "chapter_markers": boolean_arg=true; '-m' when "two_pass_encode": boolean_arg=true; '-2' when "deinterlace_video": boolean_arg=true; '-d' when "grayscale": boolean_arg=true; '-g' when "store_pixel_aspect_ratio": boolean_arg=true; '-p' when "audio_encoder": '-E' when "audio_bitrate": '-B' when "audio_downmix_format": '-6' when "audio_samplerate": '-R' when "x264opts": '-x' when "title_number": '-t' when "audio_track": '-a' when "subtitle_track": '-s' when "output_name": '-o' when "chapters": '-c' else next end if boolean_arg: command << arg if value else command << arg command << value.to_s end end system(*command) or raise "Handbrake (#{command.to_s}) failed with status #{$?}" end end bhb = BatchHB.new bhb.parse_options(ARGV) bhb.load_config bhb.load_dvd_info bhb.rip