From: Alan J. Pippin Date: Sun, 7 Feb 2010 04:28:55 +0000 (-0700) Subject: Major release to support HandBrake video encoder. X-Git-Tag: 2_0~7 X-Git-Url: http://git.pippins.net/embedvideo/.git/?a=commitdiff_plain;h=565219d7465a93a2a714671b7f45c8b0453c3809;p=rip_dvd%2F.git Major release to support HandBrake video encoder. Changed some options around to support this, so old opts may not equal new opts. Added support to encode directly from VOB file if given with -n option --- diff --git a/rip_dvd b/rip_dvd index 50bdb22..6846ba3 100755 --- a/rip_dvd +++ b/rip_dvd @@ -3,7 +3,7 @@ # Author: Alan J. Pippin (apippin@pippins.net) # Date: 05/17/2009 # - REV=1.0 + REV=2.0 # # Description: This script wraps a number of linux utilities to # create a recipe for ripping protected DVDs, circumventing @@ -19,7 +19,7 @@ # lsdvd dvdauthor gddrescue dvdbackup tovid mencoder mplayer genisoimage libdvdcss2 # # Specific Executable (program) Dependencies (must be found in $PATH): -# volname makexml lsdvd dvdauthor gddrescue dvdbackup mencoder mplayer mkisofs +# volname makexml lsdvd dvdauthor gddrescue dvdbackup mencoder mplayer mkisofs HandBrakeCLI # # Optional Dependencies: # lookup imdb info/posters for mythvideo: http://www.mythtv.org/wiki/Fill_mythvideo_metadata.pl @@ -41,6 +41,7 @@ typeset CROP="" typeset profile="xvidvhq" typeset extension="" typeset mailto="" +typeset encoder="" typeset default_alang="en" typeset -i default_aid=128 typeset -i aid_override=-1 @@ -60,6 +61,7 @@ typeset -i mirror_mode=0 typeset -i target_bitrate=2000 typeset -i target_size=0 typeset -i audio_2ch=0 +typeset -i audio_6ch=1 typeset -i invalid_feature_title=0 typeset -i feature_title_override=0 typeset -i mplayer_dumpstream_incompatibility=0 @@ -98,7 +100,7 @@ fi ############################################################################################## # Command line processing ############################################################################################## -while (($#)) && getopts 12mvifkxht:n:d:b:s:t:a:p:e:j:l: opt "$@" +while (($#)) && getopts 162mvifkzx:ht:n:d:b:s:t:a:p:e:j:l: opt "$@" do case $opt in (n) dvdname=$OPTARG;; @@ -106,17 +108,19 @@ do (b) target_bitrate=$OPTARG;; (s) target_size=$OPTARG;; (2) audio_2ch=1;; + (6) audio_6ch=1;; (1) force_onepass_mode=1;; (v) make_final_dest_vob=1;; (i) make_final_dest_iso=1;; (f) make_final_dest_folder=1;; - (x) make_final_dest_comp=1;; + (z) make_final_dest_comp=1;; + (e) encoder=$OPTARG;; (m) mirror_mode=1;; (k) keep_intermediate_files=1;; (t) feature_title_override=$OPTARG;; (a) aspect=$OPTARG;; (p) profile=$OPTARG;; - (e) extension=$OPTARG;; + (x) extension=$OPTARG;; (j) eject_disk=$OPTARG;; (l) aid_override=$OPTARG;; (w) set -$opt;; @@ -139,15 +143,18 @@ function usage() { echo >&2 " 3) If dvdname is a full path to an MPG2 file, it will be ripped as a DVD instead of $dev" echo >&2 " 4) If dvdname is a full path to an ISO file, it will be ripped as a DVD instead of $dev" echo >&2 " -p Specify which encoding profile to use in -x mode as shown below:" + echo >&2 " Mencoder and Handbrake Encoder Profiles:" echo >&2 " - xvidvhq = AVI, very high quality encoding, Xvid codec, 2 pass encoding (default)" echo >&2 " - xvidhq = AVI, high quality encoding, Xvid codec, 2 pass encoding" echo >&2 " - xvid = AVI, fast encoding, Xvid codec, 2 pass encoding" - #echo >&2 " - mp4vhq = MP4, very high quality encoding, x264 codec, 2 pass encoding" - #echo >&2 " - mp4hq = MP4, high quality encoding, x264 codec, 2 pass encoding" - #echo >&2 " - mp4 = MP4, fast encoding, x264 codec, 2 pass encoding" echo >&2 " - iphone = MP4, x264 codec, 2 pass encoding, forced 480:320 scaling" echo >&2 " - ipod = MP4, x264 codec, 2 pass encoding, forced 320:240 scaling" - echo >&2 " -e Specify a suffix extension to apply to the end of the final image filename (like .xvid, .ipod, etc)" + echo >&2 " Handbrake Only Encoder Profiles:" + echo >&2 " - mp4vhq = MP4, very high quality encoding, x264 codec, 2 pass encoding" + echo >&2 " - mp4hq = MP4, high quality encoding, x264 codec, 2 pass encoding" + echo >&2 " - mp4 = MP4, fast encoding, x264 codec, 2 pass encoding" + echo >&2 " - hb_ = Any predefined HandBrake profile" + echo >&2 " -x Specify a suffix extension to apply to the end of the final image filename (like .xvid, .ipod, etc)" echo >&2 " If you run multiple instances of this script ripping the same DVD, you need to specify this option." echo >&2 " -m Make a mirror image of the DVD and save it as a DVD ISO file" echo >&2 " The default operation is non-mirror mode where only the main" @@ -155,7 +162,8 @@ function usage() { echo >&2 " -v Make the final image a DVD VOB file" echo >&2 " -i Make the final image a DVD ISO file" echo >&2 " -f Make the final image a DVD folder" - echo >&2 " -x Make the final image a compressed file based on your profile selection" + echo >&2 " -z Make the final image a compressed file based on your profile selection and encoder" + echo >&2 " -e Specify the encoder to use to make the compressed file (valid encoders=mencoder|handbrake) (default=handbrake if found)" echo >&2 " You must also specify the target size or bitrate using the '-s' or '-b' options" echo >&2 " -s Set the target size of the compressed file in MB (ex: 700, 1000, etc)" echo >&2 " -b Set the bitrate desired in the compressed file in kbits/sec (ex: 1500, 2000 (default), etc)" @@ -169,6 +177,7 @@ function usage() { echo >&2 " The last option will allow you to start ripping another disk while the encoding process is running on a previous" echo >&2 " -1 Force 1-pass encoding mode across all profiles" echo >&2 " -2 Use 2 channel MP3 audio encoding when making a compressed file (default is 6 channel AC3)" + echo >&2 " -6 Use 6 channel AC3 audio encoding when making a compressed file (default)" echo >&2 " -k Keep the intermediate files (good for debugging)" echo >&2 " In -x mode, run with this option to keep the original .VOB file" echo >&2 " By default, all intermediary files are deleted. Only the final image is kept" @@ -202,7 +211,7 @@ fi if [ $make_final_dest_vob -eq 0 ] && [ $make_final_dest_iso -eq 0 ] && [ $make_final_dest_folder -eq 0 ] && [ $make_final_dest_comp -eq 0 ] && [ $mirror_mode -eq 0 ]; then - echo "-E- You must specify what type of final destination you want: '-m' or '-v' or '-i' or '-f' or '-x'" | tee -a $logfile + echo "-E- You must specify what type of final destination you want: '-m' or '-v' or '-i' or '-f' or '-z'" | tee -a $logfile usage fi @@ -214,6 +223,24 @@ if [ $mirror_mode -eq 1 ]; then fi fi +# Make handbrake the default encoder if not specified and we can find it +if [ -z "$encoder" ]; then + encoder="mencoder"; # If we can't find handbrake, set mencoder as the default + [[ -x `which $handbrake_xvid` ]] && [[ "$profile" =~ "xvid" ]] && encoder="handbrake"; + [[ -x `which $handbrake_mp4` ]] && [[ "$profile" =~ "mp4" ]] && encoder="handbrake"; + [[ -x `which $handbrake_mp4` ]] && [[ "$profile" =~ "hb" ]] && encoder="handbrake"; +fi + +# Sanity check the profile selection +if [[ "$encoder" == "mencoder" ]]; then + [[ "$profile" =~ "mp4" ]] && echo "-E- invalid encoder $encoder selected for mp4 profile: $profile" && exit +fi + +if [[ "$encoder" != "mencoder" ]] && [[ "$encoder" != "handbrake" ]]; then + echo "-E- Invalid encoder specified: $encoder" + exit 1 +fi + # If the aspect ratio option was specified, set the scale variable appropriately for mencoder if [ "$aspect" != "" ]; then echo "$aspect" | grep -q "x" @@ -229,7 +256,6 @@ if [ "$aspect" != "" ]; then fi fi - # Sanity Check - Key executables [[ ! -x `which lsdvd` ]] && echo "-E- missing dependency: lsdvd" && exit [[ ! -x `which volname` ]] && echo "-E- missing dependency: volname" && exit @@ -239,6 +265,9 @@ fi [[ ! -x `which makexml` ]] && echo "-E- missing dependency: makexml" && exit [[ ! -x `which dvdauthor` ]] && echo "-E- missing dependency: dvdauthor" && exit [[ ! -x `which mkisofs` ]] && echo "-E- missing dependency: mkisofs" && exit +[[ "$encoder" == "handbrake" ]] && [[ "$profile" =~ "xvid" ]] && [[ ! -x `which $handbrake_xvid` ]] && echo "-E- missing encoder: $handbrake_xvid" && exit +[[ "$encoder" == "handbrake" ]] && [[ "$profile" =~ "mp4" ]] && [[ ! -x `which $handbrake_mp4` ]] && echo "-E- missing encoder: $handbrake_mp4" && exit +[[ "$encoder" == "handbrake" ]] && [[ "$profile" =~ "hb" ]] && [[ ! -x `which $handbrake_mp4` ]] && echo "-E- missing encoder: $handbrake_mp4" && exit ############################################################################################## @@ -301,6 +330,18 @@ else valid_file=1 fi + # check to see if dvdname is a full path to an ISO file + # if it is, set dvdname and isofile appropriately + file "$dvdname" | grep -q -e "VOB" + if [ $? == 0 ]; then + # It is a valid VOB file, now strip the extension off our dvdname + vobfile="$dvdname" + dvdname=`basename "$dvdname"` + dvdname=${dvdname%.[^.]*} + keep_vobfile=1 + valid_file=1 + fi + # If we didn't find a handler for the file above, complain if [ $valid_file -eq 0 ]; then echo "-E- Unsupported file type: $vobfile" @@ -407,8 +448,155 @@ trap cleanup EXIT # processing functions ############################################################################################## -# encode the vob file into a compressed file format -function encode_vob_file { +# encode the vob file into a compressed file format using handbrake +function encode_vob_file_handbrake { + + # declare some globals + typeset handbrake_cli="" + typeset handbrake_video_encoder_opts="" + typeset filetype="" + typeset handbrake_audio_opts="" + + # Set a variable that we will use later to determine if we found a handler for $profile or not + typeset -i found_profile=0 + + # For a given profile, to override the 2 pass behavior to be single pass, + # simply set the PASSES variable below to "2" instead of "1 2" inside your profile handler. + # It indicates which PASS numbers to loop over. PASSES="2" means just do pass 2 => single pass mode. + PASSES="-2" + + # Check the global force_onepass_mode. If it is set, change our variables appropriately + # to force 1-pass encoding across all profiles. + if [ $force_onepass_mode -eq 1 ]; then + PASSES="" + fi + + # XVID profile + if [[ "$profile" =~ "xvid" ]]; then + found_profile=1 + handbrake_cli="$handbrake_xvid" + final_output_file="$dest/$dvdname.avi" + filetype="avi" + + # Very High Quality (16fps) + if [ "$profile" == "xvidvhq" ]; then + handbrake_opts[0]="-f avi" + handbrake_opts[1]="-b $target_bitrate" + handbrake_opts[2]="-e ffmpeg" + handbrake_opts[3]="-T" + handbrake_opts[4]="-5" + handbrake_opts[5]="-8" + fi + # High Quality (20fps) + if [ "$profile" == "xvidhq" ]; then + handbrake_opts[0]="-f avi" + handbrake_opts[1]="-b $target_bitrate" + handbrake_opts[2]="-e ffmpeg" + handbrake_opts[3]="-T" + handbrake_opts[4]="-5" + fi + # Fast (28fps) + if [ "$profile" == "xvid" ]; then + handbrake_opts[0]="-f avi" + handbrake_opts[1]="-b $target_bitrate" + handbrake_opts[2]="-e ffmpeg" + handbrake_opts[3]="-T" + fi + fi + + # MP4 profile + if [[ "$profile" =~ "mp4" ]]; then + found_profile=1 + handbrake_cli="$handbrake_mp4" + final_output_file="$dest/$dvdname.mp4" + PASSES="" + + # Very High Quality + if [ "$profile" == "mp4vhq" ]; then + profile="hb_High_Profile" + fi + # High Quality + if [ "$profile" == "mp4hq" ]; then + profile="hb_Normal" + fi + # Fast + if [ "$profile" == "mp4" ]; then + profile="hb_Classic" + fi + fi + + # iphone and ipod MP4 profiles + if [ "$profile" == "iphone" ] || [ "$profile" == "ipod" ]; then + found_profile=1 + handbrake_cli="$handbrake_mp4" + final_output_file="$dest/$dvdname.mp4" + PASSES="" + + # iphone + if [ "$profile" == "iphone" ]; then + profile="hb_iPhone" + fi + # ipod + if [ "$profile" == "ipod" ]; then + profile="hb_iPod" + fi + fi + + # Predefined Handbrake Profile Handling + if [[ "$profile" =~ "hb" ]]; then + found_profile=1 + handbrake_cli="$handbrake_mp4" + final_output_file="$dest/$dvdname.mp4" + PASSES="" + + # extract the HandBrake Profile name from $profile + hb_profile=`echo "$profile" | sed 's/hb_//g' | sed 's/_/ /g'` + handbrake_opts[0]="-Z \"$hb_profile\"" + fi + + # Make sure we found a handler for the given profile + if [ $found_profile -eq 0 ]; then + fatal_and_exit "-E- Unable to find a profile handler for profile: $profile" + fi + + # setup our audio option + if [ $audio_2ch -eq 1 ] && [ $audio_6ch -eq 1 ]; then + handbrake_audio_opts="-E faac,ac3 -6 dpl2,6ch" + fi + if [ $audio_6ch -eq 1 ]; then + handbrake_audio_opts="-E ac3 -6 6ch" + fi + if [ $audio_2ch -eq 1 ]; then + handbrake_audio_opts="-E faac -6 dpl2" + fi + + # Convert our array of opts into a string + for OPTS in "${video_encoder_opts[@]}"; do + handbrake_video_encoder_opts="$handbrake_video_encoder_opts:$OPTS" + done + if [ -n "$handbrake_video_encoder_opts" ]; then + handbrake_video_encoder_opts="-x $handbrake_video_encoder_opts" + fi + for OPTS in "${handbrake_opts[@]}"; do + handbrake_cmd_line_opts="$handbrake_cmd_line_opts $OPTS" + done + + # Execute the handbrake command to encode the video + echo -e "\n Encoding: $handbrake_cli -i \"$vobfile\" -o \"$final_output_file\" $handbrake_cmd_line_opts $handbrake_audio_opts $handbrake_video_encoder_opts $PASSES >> $encodelog 2>&1" >> "$logfile" + $handbrake_cli -i "$vobfile" -o "$final_output_file" $handbrake_cmd_line_opts $handbrake_audio_opts $handbrake_video_encoder_opts $PASSES >> $encodelog 2>&1 + handbrake_retval=$? + if [ $handbrake_retval != 0 ]; then + fatal_and_exit "-E- Unhandled handbrake error" + fi + + # Concatenate the encode log to our main log file, greping out unwanted lines + cat $encodelog | grep -v "Encoding" >> "$logfile" + cat $encodelog | grep "Encoding:" | sed 's/ /\n/g' | grep "Encoding:" | grep "ETA" | head -1 >> "$logfile" + cat $encodelog | grep "Encoding:" | sed 's/ /\n/g' | grep "Encoding:" | grep "ETA" | tail -1 >> "$logfile" +} + +# encode the vob file into a compressed file format using mencoder +function encode_vob_file_mencoder { # Set a variable that we will use later to determine if we found a handler for $profile or not typeset -i found_profile=0 @@ -431,7 +619,7 @@ function encode_vob_file { fi # XVID profile - if [ "$profile" == "xvid" ] || [ "$profile" == "xvidhq" ] || [ "$profile" == "xvidvhq" ]; then + if [[ "$profile" =~ "xvid" ]]; then found_profile=1 final_output_file="$dest/$dvdname.avi" mencoder_general_opts="$lang_opts $passlogfile_opt" @@ -487,73 +675,6 @@ function encode_vob_file { fi - # MP4 encoding profiles - # These are currently in BETA. They don't work that great. A new recipe is needed, for the audio. - if [ "$profile" == "mp4" ] || [ "$profile" == "mp4hq" ] || [ "$profile" == "mp4vhq" ]; then - found_profile=1 - final_output_file="$dest/$dvdname.mp4" - mencoder_general_opts="$lang_opts $passlogfile_opt" - mencoder_output_opts="-ofps 30000/1001 -sws 9 -of lavf -lavfopts format=mp4" - mencoder_video_filter_opts="-vf harddup$CROP$SCALE"; - mencoder_video_encoder_opts="-ovc x264 -x264encopts $pass_opt" - - # Very High Quality (6fps) - if [ "$profile" == "mp4vhq" ]; then - video_encoder_opts[0]="bitrate=$target_bitrate" - video_encoder_opts[1]="threads=$mencoder_threads" - video_encoder_opts[2]="subq=6" - video_encoder_opts[3]="frameref=5" - video_encoder_opts[4]="bframes=3" - video_encoder_opts[5]="8x8dct" - video_encoder_opts[6]="me=umh" - video_encoder_opts[7]="b_pyramid" - video_encoder_opts[8]="weight_b" - video_encoder_opts[9]="partitions=all" - fi - # High Quality (13fps) - if [ "$profile" == "mp4hq" ]; then - video_encoder_opts[0]="bitrate=$target_bitrate" - video_encoder_opts[1]="threads=$mencoder_threads" - video_encoder_opts[2]="subq=5" - video_encoder_opts[3]="frameref=2" - video_encoder_opts[4]="bframes=3" - video_encoder_opts[5]="8x8dct" - video_encoder_opts[6]="b_pyramid" - video_encoder_opts[7]="weight_b" - fi - # Fast (17fps) - if [ "$profile" == "mp4" ]; then - video_encoder_opts[0]="bitrate=$target_bitrate" - video_encoder_opts[1]="threads=$mencoder_threads" - video_encoder_opts[2]="subq=4" - video_encoder_opts[3]="bframes=2" - video_encoder_opts[4]="b_pyramid" - video_encoder_opts[5]="weight_b" - fi - - for OPTS in "${video_encoder_opts[@]}"; do - mencoder_video_encoder_opts="$mencoder_video_encoder_opts:$OPTS" - done - - if [ $audio_2ch -eq 0 ]; then - # These options produce good 6 channel audio for linux and windows - #mencoder_audio_opts="-oac copy" - # There are 3 different ways to specify 6 channel encoding. We'll try the other ones in order if one of them fails. - #mencoder_audioch_opts[0]="-channels 6 -af channels=6" - #mencoder_audioch_opts[1]="-af channels=6" - #mencoder_audioch_opts[2]="" - mencoder_audio_opts="-oac faac -faacopts mpeg=4:object=2:br=$audio_bitrate:raw" - mencoder_audioch_opts[0]="-channels 6 -srate 48000 -af volnorm=1" - else - # These options produce good 2 channel audio for linux and windows (including the internal mythvideo player) - #mencoder_audio_opts="-oac mp3lame -lameopts cbr:br=$audio_bitrate" - #mencoder_audioch_opts[0]="" - mencoder_audio_opts="-oac faac -faacopts mpeg=4:object=2:br=$audio_bitrate:raw" - mencoder_audioch_opts[0]="-channels 2 -srate 48000 -af volnorm=1" - fi - - fi - # iphone and ipod MP4 profiles if [ "$profile" == "iphone" ] || [ "$profile" == "ipod" ]; then found_profile=1 @@ -1276,11 +1397,13 @@ if [ $mirror_mode -eq 0 ]; then remove_intermediate_iso_file else - echo "-> Skipping VOB creation. VOB DVD video already exists: $vobfile" | tee -a "$logfile" - # get our audio id from the VOB file - get_audio_id_from_vob "$vobfile" - # get the crop value from the VOB - get_crop_from_vob + if [ "$encoder" != "handbrake" ]; then + echo "-> Skipping VOB creation. VOB DVD video already exists: $vobfile" | tee -a "$logfile" + # get our audio id from the VOB file + get_audio_id_from_vob "$vobfile" + # get the crop value from the VOB + get_crop_from_vob + fi fi # eject the DVD disk since we are finished with it @@ -1288,13 +1411,18 @@ if [ $mirror_mode -eq 0 ]; then # encode the VOB file to a compressed file format if [ $make_final_dest_comp -eq 1 ]; then - echo "-> Encoding the DVD video to a compressed file" | tee -a "$logfile" + echo "-> Encoding the DVD video to a compressed file using $encoder" | tee -a "$logfile" # determine what our bitrate needs to be if a target size was specified instead calculate_bitrate_from_target_size # encode the vob file into a compressed file format - encode_vob_file + if [[ "$encoder" == "mencoder" ]]; then + encode_vob_file_mencoder + fi + if [[ "$encoder" == "handbrake" ]]; then + encode_vob_file_handbrake + fi if [ $keep_intermediate_files -eq 0 ] && [ $make_final_dest_vob -eq 0 ]; then [[ -e "$vobfile" ]] && [[ $keep_vobfile -eq 0 ]] && rm -f "$vobfile"; diff --git a/rip_dvd.conf.dist b/rip_dvd.conf.dist index c05e4b4..4c7d0da 100644 --- a/rip_dvd.conf.dist +++ b/rip_dvd.conf.dist @@ -53,4 +53,10 @@ trust_feature_title_autodetect_when_uncertain=0 # note: the xvid codec seems to be fastest with threads set to 2. mencoder_threads=2 +# handbrake parameters +# handbrake version 0.9.3 was the last one to support xvid encoding +# handbrake version 0.9.4 is all about mp4 encoding +handbrake_xvid="HandBrakeCLI-0.9.3" +handbrake_mp4="HandBrakeCLI-0.9.4" + ########################################################################################### diff --git a/rip_dvd_menu.xml b/rip_dvd_menu.xml index 4c82912..2adb1a0 100644 --- a/rip_dvd_menu.xml +++ b/rip_dvd_menu.xml @@ -9,13 +9,13 @@