typeset default_alang="en"
typeset track=""
typeset drc="0.0"
+typeset handbrake_xvid=""
+typeset handbrake_mp4=""
+typeset makemkv=""
+typeset makemkv_disc_id=""
+typeset mkvextract=""
+typeset mkvpropedit=""
+typeset mkvmerge=""
+typeset mp4box=""
+typeset dvdxchap=""
typeset -i default_aid=128
typeset -i aid_override=-1
typeset -i force_onepass_mode=0
typeset -i custom_audio_bitrate=0
typeset -i custom_audio_2ch=0
typeset -i custom_audio_6ch=0
-typeset -i minimum_feature_title_length=10
+typeset -i minimum_feature_title_length=60
typeset -i lsdvd_timeout=10
+typeset -i real_isofile=0
##############################################################################
# Local Machine Settings:
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 " Handbrake Only Encoder Profiles:"
+ echo >&2 " - mkvvhq = MKV, very high quality encoding (0.90 quality) (requires makemkv encoder option)"
+ echo >&2 " - mkvhq = MKV, high quality encoding (0.85 quality) (requires makemkv encoder option)"
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 " -i Make the final image a DVD ISO file"
echo >&2 " -f Make the final image a DVD folder"
echo >&2 " -z Make the final image a compressed file based on your profile selection and encoder"
- echo >&2 " -e <encoder> Specify the encoder to use to make the compressed file (valid encoders=mencoder|handbrake) (default=handbrake if found)"
+ echo >&2 " -e <encoder> Specify the encoder to use to make the compressed file (valid encoders=mencoder|handbrake|makemkv) (default=handbrake if found)"
echo >&2 " You must also specify the target size or bitrate using the '-s' or '-b' options with xvid profiles"
echo >&2 " -s <size> Set the target size of the compressed file in MB (ex: 700, 1000, etc)"
echo >&2 " -b <bitrate> Set the video bitrate desired in the compressed file in kbits/sec (ex: 1500, 2000 (default), etc)"
# 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
+ encoder="mencoder"; # If we can't find handbrake or makemkv, 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" =~ "ip" ]] && encoder="handbrake";
[[ -x `which $handbrake_mp4` ]] && [[ "$profile" =~ "hb" ]] && encoder="handbrake";
+ [[ -x `which $makemkv` ]] && [[ "$profile" =~ "mkv" ]] && encoder="makemkv";
fi
# Sanity check the profile selection
if [[ "$encoder" == "mencoder" ]]; then
[[ "$profile" =~ "mp4" ]] && echo "-E- invalid encoder $encoder selected for mp4 profile: $profile" && exit
+ [[ "$profile" =~ "mkv" ]] && echo "-E- invalid encoder $encoder selected for mkv profile: $profile" && exit
+fi
+if [[ "$encoder" == "handbrake" ]]; then
+ [[ "$profile" =~ "mkv" ]] && echo "-E- invalid encoder $encoder selected for mkv profile: $profile" && exit
fi
-if [[ "$encoder" != "mencoder" ]] && [[ "$encoder" != "handbrake" ]]; then
+if [[ "$encoder" != "mencoder" ]] && [[ "$encoder" != "handbrake" ]] && [[ "$encoder" != "makemkv" ]]; then
echo "-E- Invalid encoder specified: $encoder"
exit 1
fi
[[ ! -x `which mkisofs` ]] && echo "-E- missing dependency: mkisofs" && exit
[[ -n "$handbrake_xvid" ]] && [[ ! -x `which $handbrake_xvid` ]] && echo "-E- missing handbrake xvid encoder, set in rip_dvd.conf to: $handbrake_xvid" && exit
[[ -n "$handbrake_mp4" ]] && [[ ! -x `which $handbrake_mp4` ]] && echo "-E- missing handbrake mp4 encoder, set in rip_dvd.conf to: $handbrake_mp4" && 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" =~ "ip" ]] && [[ ! -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
+[[ -n "$makemkv" ]] && [[ ! -x `which $makemkv` ]] && echo "-E- missing makemkv encoder, set in rip_dvd.conf to: $makemkv" && exit
+[[ "$encoder" == "handbrake" ]] && [[ "$profile" =~ "xvid" ]] && [[ ! -x `which $handbrake_xvid` ]] && echo "-E- missing HandBrake encoder: $handbrake_xvid" && exit
+[[ "$encoder" == "handbrake" ]] && [[ "$profile" =~ "mp4" ]] && [[ ! -x `which $handbrake_mp4` ]] && echo "-E- missing HandBrake encoder: $handbrake_mp4" && exit
+[[ "$encoder" == "handbrake" ]] && [[ "$profile" =~ "ip" ]] && [[ ! -x `which $handbrake_mp4` ]] && echo "-E- missing HandBrake encoder: $handbrake_mp4" && exit
+[[ "$encoder" == "handbrake" ]] && [[ "$profile" =~ "hb" ]] && [[ ! -x `which $handbrake_mp4` ]] && echo "-E- missing HandBrake encoder: $handbrake_mp4" && exit
+[[ "$encoder" == "makemkv" ]] && [[ "$profile" =~ "mkv" ]] && [[ ! -x `which $makemkv` ]] && echo "-E- missing MakeMKV encoder: $makemkv" && exit
+[[ "$encoder" == "makemkv" ]] && [[ "$profile" =~ "mkv" ]] && [[ ! -x `which $mkvextract` ]] && echo "-E- missing mkvextract: $mkvextract" && exit
+[[ "$encoder" == "makemkv" ]] && [[ "$profile" =~ "mkv" ]] && [[ ! -x `which $mkvpropedit` ]] && echo "-E- missing mkvpropedit: $mkvpropedit" && exit
+[[ "$encoder" == "makemkv" ]] && [[ "$profile" =~ "mkv" ]] && [[ ! -x `which $mkvmerge` ]] && echo "-E- missing mkvmerge: $mkvmerge" && exit
+[[ "$encoder" == "handbrake" ]] && [[ "$profile" =~ "mp4" ]] && [[ ! -x `which $mp4box` ]] && echo "-E- missing mp4box: $mp4box" && exit
[[ "$encoder" == "handbrake" ]] && [[ ! -x `which ffmpeg` ]] && echo "-E- missing dependency: ffmpeg" && exit
##############################################################################################
dvdname=${dvdname%.[^.]*}
keep_isofile=1
valid_file=1
+ real_isofile=1
fi
# check to see if dvdname is a full path to an ISO file
dvdname=${dvdname%.[^.]*}
keep_vobfile=1
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 "mkv"
+ if [ $? == 0 ]; then
+ # It is a valid VOB file, now strip the extension off our dvdname
+ isofile="$dvdname"
+ dvdname=`basename "$dvdname"`
+ dvdname=${dvdname%.[^.]*}
+ keep_isofile=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"
return 0
}
+# reduce the size of the mkv src file using handbrake
+function encode_mkv_file_makemkv {
+ src="$1"
+ dst="$2"
+ tmpdst=""
+
+ # Convert our ISO to a MKV if it is a real iso
+ if [[ $real_isofile -eq 1 ]]; then
+ tmpdst="$tmpdir/$dvdname.mkv"
+ make_dvd_mkv_image "$tmpdst" "iso" "$src"
+ src="$tmpdst"
+ fi
+
+ # Set a variable that we will use later to determine if we found a handler for $profile or not
+ typeset -i found_profile=0
+
+ # Globals
+ typeset quality=""
+ typeset handbrake_audio_opts=""
+ typeset handbrake_cli=""
+
+ # Predefined Handbrake Profile Handling
+ if [[ "$profile" =~ "mkvvhq" ]]; then
+ found_profile=1
+ handbrake_cli="$handbrake_mp4"
+ final_output_file="$dst"
+ quality="0.9"
+ fi
+ if [[ "$profile" =~ "mkvhq" ]]; then
+ found_profile=1
+ handbrake_cli="$handbrake_mp4"
+ final_output_file="$dst"
+ quality="0.85"
+ fi
+
+ # setup our audio option
+ if [ $audio_2ch -eq 1 ] && [ $audio_6ch -eq 1 ]; then
+ handbrake_audio_opts="-E faac,ac3 -6 dpl2,auto"
+ fi
+ if [ $audio_6ch -eq 1 ] && [ $audio_2ch -eq 0 ]; then
+ handbrake_audio_opts="-E ac3 -6 auto"
+ fi
+ if [ $audio_2ch -eq 1 ] && [ $audio_6ch -eq 0 ]; then
+ handbrake_audio_opts="-E faac -6 dpl2"
+ fi
+
+ # find out what our audio track is
+ get_audio_track_from_mkv "$src" "$handbrake_cli"
+ if [ -n "$track" ]; then
+ handbrake_audio_opts="$handbrake_audio_opts -a $track"
+ track=""
+ fi
+
+ # Execute the handbrake command to encode the video
+ echo -e "\n Encoding: $handbrake_cli -i \"$src\" -o \"$dst\" --strict-anamorphic --crop 0:0:0:0 -q $quality $handbrake_audio_opts -v 1 -m"
+ $handbrake_cli -i "$src" -o "$dst" --strict-anamorphic --crop 0:0:0:0 -q $quality $handbrake_audio_opts -v 1 | tee -a $encodelog 2>&1
+ handbrake_retval=$?
+
+ if [ $handbrake_retval != 0 ]; then
+ fatal_and_exit "-E- Unhandled handbrake error"
+ fi
+
+ # Extract the chapters from the src and apply to the dst
+ chapter_tmpfile="$tmpdir/$dvdname.xml"
+ $mkvextract chapters "$src" > "$chapter_tmpfile"
+ $mkvpropedit -c "$chapter_tmpfile" "$dst"
+
+ # find out what our default_alang subtitle track is in the src
+ get_subtitle_track_from_mkv "$src" "$handbrake_cli"
+
+ # Extract the subtitles from the src and apply to the dst
+ srt_tmpfile="$tmpdir/$dvdname.srt"
+ sub_tmpfile="$tmpdir/$dvdname.sub"
+ idx_tmpfile="$tmpdir/$dvdname.idx"
+ $mkvextract tracks "$src" $track:$srt_tmpfile
+ $mkvmerge -o "$dst.subs" "$dst" $idx_tmpfile
+ mv "$dst.subs" "$dst"
+
+ # Set the default subtitle track to "no subtitles" in the dst
+ $mkvpropedit "$dst" --edit track:s1 --set flag-default=0
+
+ # Concatenate the encode log to our main log file, greping out unwanted lines
+ cat $encodelog | grep -v "Encoding:" | grep -v "hb_demux_ps" >> "$logfile"
+ cat $encodelog | grep "Encoding:" | sed 's/\r/\n/g' | grep "Encoding:" | grep "ETA" | head -1 >> "$logfile"
+ cat $encodelog | grep "Encoding:" | sed 's/\r/\n/g' | grep "Encoding:" | grep "ETA" | tail -1 >> "$logfile"
+
+ # Remove intermediary file if we created one
+ if [ $keep_intermediate_files -eq 0 ]; then
+ [[ -e "$tmpdst" ]] && rm -f "$tmpdst"
+ rm "$chapter_tmpfile"
+ rm "$idx_tmpfile" "$sub_tmpfile"
+ else
+ echo "-> Keeping intermediate chapter file: $chapter_tmpfile" | tee -a "$logfile"
+ echo "-> Keeping intermediate subtitle files: $idx_tmpfile $sub_tmpfile" | tee -a "$logfile"
+ [[ -e "$tmpdst" ]] && echo "-> Keeping intermediate MKV file: $tmpdst" | tee -a "$logfile"
+ fi
+}
+
# encode the vob file into a compressed file format using handbrake
function encode_vob_file_handbrake {
done
# Append "global" command line options
- handbrake_cmd_line_opts="$handbrake_cmd_line_opts -v 1"
+ handbrake_cmd_line_opts="$handbrake_cmd_line_opts -v 1 -m"
handbrake_cmd_line_opts="$handbrake_cmd_line_opts $PASSES"
handbrake_cmd_line_opts="$handbrake_cmd_line_opts $DRC"
handbrake_cmd_line_opts="$handbrake_cmd_line_opts $SCALE"
fatal_and_exit "-E- Unhandled handbrake error"
fi
+ # Extract the chapters from the ISO/VOB so we can add them to the MP4 file. We can only do this if we have an ISO file and we made an MP4 file.
+ chapter_tmpfile="$tmpdir/$dvdname.chapters"
+ if [[ "$final_output_file" =~ "mp4" ]] && [[ -e "$isofile" ]]; then
+ $dvdxchap -t $feature_title "$isofile" > "$chapter_tmpfile"
+ $mp4box -chap "$chapter_tmpfile" "$final_output_file"
+ fi
+
+ # We could also add subtitles, but we would need to follow this guide to do it:
+ # http://ubuntuforums.org/showthread.php?t=1253635
+ # http://en.gentoo-wiki.com/wiki/Ripping_DVD_to_Matroska_and_H.264
+
+ # Remove intermediary file if we created one
+ if [ $keep_intermediate_files -eq 0 ]; then
+ rm "$chapter_tmpfile"
+ else
+ echo "-> Keeping intermediate chapter file: $chapter_tmpfile" | tee -a "$logfile"
+ fi
+
# Concatenate the encode log to our main log file, greping out unwanted lines
cat $encodelog | grep -v "Encoding:" | grep -v "hb_demux_ps" >> "$logfile"
cat $encodelog | grep "Encoding:" | sed 's/\r/\n/g' | grep "Encoding:" | grep "ETA" | head -1 >> "$logfile"
done
}
+function make_dvd_mkv_image {
+ dstmkv="$1"
+ srctype="$2"
+ srcname="$3"
+ dstdir=${dstmkv%.[^.]*}
+ ((min_length = minimum_feature_title_length * 60))
+
+ echo -e "\n Ripping: $makemkv --minlength=$min_length --decrypt --progress=-same $srctype:$srcname all $dstdir"
+ mkdir -p "$dstdir"
+ $makemkv mkv --minlength=$min_length --decrypt --progress=-same $srctype:$srcname all $dstdir
+ makemkv_retval=$?
+
+ if [ $makemkv_retval != 0 ]; then
+ fatal_and_exit "-E- Unhandled makemkv error"
+ fi
+
+ # Move the created MKV file into place
+ echo -e "\n Moving $dstdir/*.mkv -> $dstmkv"
+ mv "$dstdir"/*.mkv "$dstmkv"
+ if [ $? != 0 ]; then
+ fatal_and_exit "-E- Unhandled mv error"
+ fi
+ if [ $keep_intermediate_files -eq 0 ]; then
+ [[ -d "$dstdir" ]] && rm -rf "$dstdir"
+ fi
+
+ # Concatenate the encode log to our main log file, greping out unwanted lines
+ cat $encodelog | grep -v "Current progress:" >> "$logfile"
+}
+
+function make_dvd_mkv_image_from_folder {
+ src="$1"
+ dst="$2"
+ handle_error=$3
+ dstdir=${dst%.[^.]*}
+ make_dvd_mkv_image "$dst" "file" "$src"
+}
+
function make_dvd_iso_image {
isofile="$1"
echo " Setting mencoder crop filter to: $CROP"
}
+function get_audio_track_from_mkv {
+ mkv="$1"
+ handbrake_cli="$2"
+ aidcheck=`tempfile`
+ alang=$default_alang
+
+ # Find out what audio track matches our alang
+ $handbrake_cli --stop-at duration:1 -i "$mkv" -o /dev/null -v 100 > $aidcheck 2>&1
+ stream=`grep "$alang" $aidcheck | grep "Audio:"`
+
+ # extract the track number that handbrake uses
+ track=`echo "$stream" | awk '{ print $2; }' | awk -F '.' '{ print $2; }' | awk -F '(' '{ print $1; }'`
+
+ if [ -n "$track" ]; then
+ echo " Setting the audio track to $track." | tee -a "$logfile"
+ fi
+}
+
+function get_subtitle_track_from_mkv {
+ mkv="$1"
+ handbrake_cli="$2"
+ aidcheck=`tempfile`
+ alang=$default_alang
+
+ # Find out what audio track matches our alang
+ $handbrake_cli --stop-at duration:1 -i "$mkv" -o /dev/null -v 100 > $aidcheck 2>&1
+ stream=`grep "$alang" $aidcheck | grep "Subtitle:" | head -n 1`
+
+ # extract the track number that handbrake uses
+ track=`echo "$stream" | awk '{ print $2; }' | awk -F '.' '{ print $2; }' | awk -F '(' '{ print $1; }'`
+
+ # add 1 to the track number since mkv tools start at 1, and HandBrake starts at 0
+ ((track = track + 1))
+
+ if [ -n "$track" ]; then
+ echo " Setting the subtitle track to $track." | tee -a "$logfile"
+ fi
+}
+
function get_audio_track_from_vob {
# Adjust our audio ID to find the english audio stream
# This should be 128. However, if 128 is not there, pick the next one that incrementally is.
echo " If using mencoder, the target_size will be entirely disregarded." | tee -a "$logfile"
echo " You may need to rerun with the -b option with a target bitrate to get the desired size." | tee -a "$logfile"
if [[ $encoder -ne "handbrake" ]] || [[ "$profile" =~ "xvid" ]]; then
- fatal_and_exit "-E- You'll need rip this DVD with the handbrake encoder and an MP4 type profile to get a good rip."
+ fatal_and_exit "-E- You'll need rip this DVD with the handbrake or makemkv encoder and an MP4 type profile to get a good rip."
fi
fi
fi
if [[ $vob_length -lt $min_length ]]; then
if [[ $encoder -ne "handbrake" ]] || [[ "$profile" =~ "xvid" ]]; then
echo "-E- The main feature title that was ripped from the DVD has an invalid movie length." | tee -a "$logfile"
- echo " You'll need rip this DVD with the handbrake encoder and an MP4 type profile instead." | tee -a "$logfile"
+ echo " You'll need rip this DVD with the handbrake encoder and an MP4 type or makemkv encoder and an MKV type profile instead." | tee -a "$logfile"
mplayer_dumpstream_incompatibility=1
fatal_and_exit "-E- Aborting encoding step due to invalid movie length."
fi
if [ $mirror_mode -eq 1 ]; then
echo "-> Ripping DVD $dvdname to $dest"
- # use ddrescue to make an ISO image of the disk
- make_dvd_iso_image "$dest/$dvdname.iso"
-
- # add this video data to the mythtv DB
- fill_mythvideo_metadata "$dest/$dvdname.iso"
+ if [[ "$encoder" == "makemkv" ]]; then
+ # use makemkv to make an MKV file of the disk
+ make_dvd_mkv_image "$dest/$dvdname.mkv" "disc" "$makemkv_disc_id"
+ # add this video data to the mythtv DB
+ fill_mythvideo_metadata "$dest_filename"
+ else
+ # use ddrescue to make an ISO image of the disk
+ make_dvd_iso_image "$dest/$dvdname.iso"
+ # add this video data to the mythtv DB
+ fill_mythvideo_metadata "$dest_filename"
+ fi
# eject the disk upon completion
if [ $eject_disk -ne 0 ]; then
# Rip image from DVD
if [ $ripdvd -eq 1 ]; then
echo "-> Ripping DVD $dvdname to $dest" | tee -a "$logfile"
- # use ddrescue to make an ISO image of the disk
- make_dvd_iso_image "$tmpdir/$dvdname.iso"
+ if [[ "$encoder" == "makemkv" ]]; then
+ # use makemkv to make an MKV file of the disk
+ make_dvd_mkv_image "$tmpdir/$dvdname.mkv" "disc" "$makemkv_disc_id"
+ else
+ # use ddrescue to make an ISO image of the disk
+ make_dvd_iso_image "$tmpdir/$dvdname.iso"
+ fi
fi
# Rip image from DVD path
if [ -n "$dvdpath" ]; then
echo "-> Ripping DVD $dvdpath to $dest" | tee -a "$logfile"
- make_dvd_iso_image_from_folder "$dvdpath" "$tmpdir/$dvdname.iso" 1
+ if [[ "$encoder" == "makemkv" ]]; then
+ make_dvd_mkv_image_from_folder "$dvdpath" "$tmpdir/$dvdname.mkv" 1
+ else
+ make_dvd_iso_image_from_folder "$dvdpath" "$tmpdir/$dvdname.iso" 1
+ fi
fi
# make sure our isofile value is set
if [ -z "$isofile" ]; then
- isofile="$tmpdir/$dvdname.iso"
+ if [[ "$encoder" == "makemkv" ]]; then
+ isofile="$tmpdir/$dvdname.mkv"
+ else
+ isofile="$tmpdir/$dvdname.iso"
+ fi
fi
-
+
+ # MakeMKV special case
+ if [[ "$encoder" == "makemkv" ]] && [[ $make_final_dest_comp -eq 1 ]]; then
+ echo "-> Encoding the DVD video to a compressed file using $encoder" | tee -a "$logfile"
+
+ # eject the DVD disk since we are finished with it
+ [ $eject_disk -eq 2 ] && eject -T $dev
+
+ # Encode the final MKV file
+ encode_mkv_file_makemkv "$isofile" "$dest/$dvdname.mkv"
+
+ # remove the intermediate ISO file
+ remove_intermediate_iso_file
+
+ # keep intermediate log files
+ if [ $keep_intermediate_files -eq 0 ]; then
+ [[ -e "$passlogfile" ]] && rm -f "$passlogfile";
+ else
+ echo "-> Keeping mencoder 2pass logfile: $passlogfile"
+ fi
+
+ # add this video data to the mythtv DB
+ fill_mythvideo_metadata "$dest/$dvdname.mkv"
+
+ # All done!
+ exit 0
+ fi
+
if [ $make_final_dest_vob -eq 1 ] || [ $make_final_dest_comp -eq 1 ]; then
if [ ! -e "$vobfile" ]; then