It seems that some people are trying to use this script to directly encode the movie from the disk. This won't be possible, but in the near future I'll implement this.
I have written a bash script that from a directory containing vob files, will make an extremely good looking XviD dvdrip. I'd really appreciate it if you would try it out and let me know if there are any bugs. I've had great success with it. At the moment it only works on a PAL DVD source, but it the future this will be updated to make perfect rips from an NTSC source. Will also be updated to make rips of DVD's containing tv-eps.
28/12/2006 Fixed : Bug causing all files to be hidden! 27/12/2006 Added : It should now be possible to encode to XviD directly from the DVD disc, provided the DVD only has CSS encryption and nothing too fancy :) If the Supplied dir argument is a mounted DVD (cannot be written to), then the $PWD will be used as our working directory, otherwise the vob dir will be used as our working directory. Added : Added some xvidenc options to set quantization type as H.263 and to make sure that qpel and gmc are not used as these can cause problems on standalone players. 26/12/2006 Added : Title and Output Filename options are now mandatory and the script will now detect if they are missing. Fixed : Listing .vob files now working. 25/12/2006 Added : Different range of possible resolutions for the output video, depending on whether we have a WS or FS source.
#!/bin/sh # #This is is a wrapper around the -identify functionality. # It is supposed to escape the output properly, so it can be easily # used in shellscripts by 'eval'ing the output of this script. # # Written by Tobias Diedrich <ranma+mplayer@tdiedrich.de> # Licensed under GNU GPL. if [ -z "$1" ]; then echo "Usage: midentify <file> [<file> ...]" exit 1 fi mplayer -vo null -ao null -frames 0 -identify "$@" 2>/dev/null | sed -ne '/^ID_/ { s/[]()|&;<>`'"'"'\\!$" []/\\&/g;p }'
RIGHT change_rectangle 2 +2 LEFT change_rectangle 2 -2 DOWN change_rectangle 3 +2 UP change_rectangle 3 -2 KP6 change_rectangle 0 +2 KP4 change_rectangle 0 -2 KP2 change_rectangle 1 +2 KP8 change_rectangle 1 -2 PGUP seek +60 PGDWN seek -60 q quit ESC quit ENTER pt_step 1 1 p pause SPACE pause f vo_fullscreen
So Here It Is:
#!/bin/bash calculate_ar_error() { resized_ar=$(echo "scale=10;$1/$2" | bc ) ar_error=$(echo "scale=4; (($crop_ar - $resized_ar) / $resized_ar) * 100" | bc ) } function best_mult16() { calculate_ar_error $1 $2 ar_error_1=$ar_error calculate_ar_error $1 $3 ar_error_2=$ar_error echo "AR Error $1 x $2 : ${ar_error_1}%" echo "AR Error $1 x $3 : ${ar_error_2}%" if [ `echo "${ar_error_2#-} < ${ar_error_1#-}" | bc ` -eq 1 ]; then best_error=$ar_error_2 return 0; else best_error=$ar_error_1 return 1; fi } function find_best_height() { #Find Closest Multiple of 16 perfect_height=$(echo "scale=10; $1 / $crop_ar" | bc) round_down_mult16=$(echo "$perfect_height - ($perfect_height % 16)" | bc) round_down_mult16=${round_down_mult16%%.*} best_mult16 $1 $round_down_mult16 $(echo "$round_down_mult16 + 16" | bc) if [ $? -eq 0 ]; then best_height=$(expr $round_down_mult16 + 16) else best_height=$round_down_mult16 fi echo "The Best height out of $round_down_mult16 and $(expr $round_down_mult16 + 16) is $best_height" } echo "Welcome to Staz's XviD Video Encoder" echo "At the moment this can only be used to encode PAL DVD Movies to XviD" echo "Email any bugs/fixes to ben.staz@gmail.com" echo "-------------------------------------" #Create Constants To Be Used In Script (Could use 'readonly foo==moo', 'declare -r foo=moo' or 'typeset -r foo=moo' readonly CD_SIZE=716800 readonly PAL_MIN_RUNTIME_PER_CD=6000 readonly NTSC_MIN_RUNTIME_PER_CD=5220 readonly FILM_MIN_RUNTIME_PER_CD=6300 #First argument supplied is the directory containing the vobs. if [ -d $1 ]; then vob_dir=$1; #S if [ "${vob_dir:0:1}" != "/" ]; then echo "This vob dir is relevant to the PWD" if [ "$vob_dir" == "." ]; then vob_dir=${PWD}/ else vob_dir=${PWD}/${vob_dir#./} fi else echo "The vob dir is a full path." fi echo "Vob Dir : $vob_dir"; echo "Vob Files:" for i in ${vob_dir}/*.[Vv][Oo][Bb] ; do echo $i; done; #Check if the supplied vob directory is a mounted DVD. #The 2> /dev/null part avoids the 'unary operator' message when it is not a mounted DVD dir. if [ `df -T $vob_dir | awk '$2 == "udf" || $2 == "iso9660" {print "0"}'` -eq 0 ]; then echo "This is a mounted DVD. Will use ${PWD}/ as the working directory" working_dir=${PWD}/ else echo "Will use $vob_dir as the working directory" working_dir=$vob_dir fi 2> /dev/null else echo "Error : You did not supply a valid directory!" fi; shift; exit #Set the default arguments (If user does not specify otherwise) max_ar_error=3 echo "-------------------------------------" echo " User Chosen Options" echo "-------------------------------------" #Following variables are used to make sure the two compulsory options (title and output) are supplied. t=1 o=1 while test "$1" != ""; do case $1 in --list-titles|-l) echo "-------------------------------------" echo " Listing Titles" echo "-------------------------------------" lsdvd $vob_dir 2> /dev/null echo "Choose a Title by using --title <n>" echo "-------------------------------------" exit ;; --title|-t) #TODO: WE WILL BE ABLE TO SUPPLY MULTIPLE TITLES HERE t=0 echo "Chosen Title : $2" title=$2 tmp=$(lsdvd -v $vob_dir 2> /dev/null ) length=$(echo "$tmp" | egrep -o '[0-9]{2}:[0-9]{2}:[0-9]{2}' | sed -n "${title}p") ar=$(echo "$tmp" | egrep -o '[0-9]+/[0-9]+' | sed -n "${title}p") echo "Title Length : $length" echo "Title AR : $ar" length_seconds=$(echo $length | { IFS='[:.]'; read h m s; echo "(${h##0} * 3600) + (${m##0} * 60) + ${s##0}" | bc; } ) echo "Length in Seconds : $length_seconds" shift ;; --max-ar-error|-e) echo "Max AR % Error : ${2}%" max_ar_error=$2 shift ;; --output|-o) o=0; echo "Output File : $2" output_file=$2 output_name=${2%.[Aa][Vv][Ii]} shift ;; *) echo "Invalid Argument : $1" echo "Will print usage in the future" exit 1 ;; esac shift done #Check that both the title and output options have been supplied. if [ "$t" -eq 1 -o "$o" -eq 1 ] ; then #Uh oh something is missing echo "-------------------------------------" echo "ERRORS!" if [ "$t" -eq 1 ]; then echo "You need To specify a Title. Usage : -t <title>" fi if [ "$o" -eq 1 ]; then echo "You need to specify an Output File. Usage : -o <output file>" fi echo "-------------------------------------" exit fi echo "-------------------------------------" echo " Source Information" echo "-------------------------------------" #Calculate Source Video Format/Resolution/Framerate by parsing lsdvd's output. video_format=$(lsdvd $vob_dir -v 2> /dev/null | egrep -o '(PAL|NTSC)' | tail -1 ) echo "Video Format......: $video_format" case $video_format in PAL) frame_rate=25 source_width=720 source_height=576 min_runtime_per_cd=$PAL_MIN_RUNTIME_PER_CD ;; NTSC) frame_rate=29.97 source_width=720 source_height=480 min_runtime_per_cd=$NTSC_MIN_RUNTIME_PER_CD ;; esac echo "Source Resolution.: $source_width x $source_height" echo "Source FrameRate..: $frame_rate" echo "-------------------------------------" echo " Crop Information" echo "-------------------------------------" #Calculate Cropping Values/Resolution based on parsed mplayer output. crop_values=$(mplayer -dvd-device $vob_dir dvd://${title} -aid 128 -vf rectangle=720:576 -input conf=cropping.conf 2> /dev/null | egrep -o '[0-9]+:[0-9]+:[0-9]+:[0-9]+' | tail -1 ) echo "Crop Vals : $crop_values" left_right_crop=$((source_width - $(echo "$crop_values" | cut -d ':' -f 1) )); top_bottom_crop=$((source_height - $(echo "$crop_values" | cut -d ':' -f 2) )); echo "Total Left/Right Cropping : $left_right_crop" echo "Total Top/Bottom Cropping : $top_bottom_crop" crop_ar=$(echo "scale=10;(($source_width - $left_right_crop) / $source_width) * ($source_height / ($source_height - $top_bottom_crop)) * ($ar)" | bc ) echo "Crop AR : $crop_ar" found_a_res=0 if [ "$ar" == "16/9" ]; then for width in $(seq 672 -16 512) ; do echo "-------------------------------------" echo "Horizontal Resolution : $width" echo "-------------------------------------" find_best_height $width if [ `echo "${best_error#-} < $max_ar_error" | bc` -eq 1 ]; then final_width=$width final_height=$best_height found_a_res=1; break; fi done; elif [ "$ar" == "4/3" ]; then for width in $(seq 576 -16 448) ; do echo "-------------------------------------" echo "Horizontal Resolution : $width" echo "-------------------------------------" find_best_height $width if [ `echo "${best_error#-} < $max_ar_error" | bc` -eq 1 ]; then final_width=$width final_height=$best_height found_a_res=1; break; fi done; fi #Check We Have Finally Came Up With a Resolution if [ $found_a_res -eq 1 ]; then echo "The Final Resolution is : $final_width x $final_height" echo "The AR Error Is: ${best_error}%" else echo "Couldn't Find A Resolution!" echo "Try Lowering the max AR Error %" fi echo "-------------------------------------" #Work Out How Many CDS Our Encode Will Take Up if [ "$length_seconds" -le "$min_runtime_per_cd" ]; then num_cds=1; else num_cds=$(( ($length_seconds / $min_runtime_per_cd) + 1 )); fi echo "Number of CDS : $num_cds" if [ $num_cds -eq 1 ]; then #Now We Rip The DVD Audio Stream To PCM .wav (Uncompressed Audio) mplayer -dvd-device $vob_dir dvd://${title} -aid 128 -vo null -vc dummy -mc 0 -ao pcm:file=${working_dir}${output_name}.wav #Use Lame to Encode to VBR MP3 (-V 3 --vbr-new seems to result in a bitrate close to 128 which I am after) lame -h -V 3 --vbr-new ${working_dir}${output_name}.wav ${working_dir}${output_name}.mp3 #Time To Apply Some Gain Or Else Our Movie Is Far Too Quiet! #The switches will make sure that mp3gain applies the maximum gain possible WITHOUT any clipping mp3gain -r -k ${working_dir}${output_name}.mp3 audio_format=mp3 else echo "We are ripping to AC3 Audio NOW...." tmp=$(mencoder -dvd-device $vob_dir dvd://${title} -aid 128 -oac copy -of rawaudio -ovc copy -mc 0 -o ${working_dir}${output_name}.ac3 2> /dev/null | grep 'audio stream: 0' | grep -o '(.*)' ) #I DONT KNOW THE OUTPUT OF MPLAYER IF THE AUDIO STREAM IS MONO. WILL HAVE TO FIND A DVD WITH A MONO AUDIO STREAM. num_channels=$(echo "$tmp" | sed -e 's/(5.1)/6/' -e 's/(stereo)/2/' ) echo "Number Of Channels : $num_channels" audio_format=ac3 fi #Time To Calculate Overhead echo "-------------------------------------" echo "Overhead Calculations" echo "-------------------------------------" if [ "$audio_format" == "mp3" ]; then frames_per_chunk=1 audio_overhead=$(echo "scale=10; ($length_seconds*1000) / (24*$frames_per_chunk)" | bc) audio_size=$(du -k ${working_dir}${output_name}.mp3 | cut -f 1) elif [ "$audio_format" == "ac3" ]; then frames_per_chunk=2 audio_overhead=$(echo "scale=10; ($length_seconds*1000) / (32*$frames_per_chunk)" | bc) audio_size=$(du -k ${working_dir}${output_name}.ac3 | cut -f 1) fi echo "Audio Overhead : ${audio_overhead%%.*}" if [ $num_cds -ge 3 ]; then #We will get an OPEN-DML .avi (with or without a legacy index?? will have to ask the mplayer devs) overhead_kilobytes=$(echo "scale=10; (16 * $audio_overhead) / 1024" | bc ) else #We will get a standard avi output. echo "STANDARD AVI OUTPUT" overhead_kilobytes=$(echo "scale=10; (24 * $audio_overhead) / 1024" | bc ) fi echo "Total Overhead (Kilobytes) : ${overhead_kilobytes%.*}" echo "-------------------------------------" echo "Audio Size : $audio_size Kb's" video_size=$(((num_cds*CD_SIZE) - audio_size - ${overhead_kilobytes%%.*} )) echo "Video Size : $video_size kb's" #We Now Have All The Info Needed To Start The XviD Encode. #Note: -nosound disables processing the audio stream. #First Pass mencoder -dvd-device $vob_dir dvd://${title} -nosound -vf crop=${crop_values},scale=${final_width}:${final_height} -sws 9 -ovc xvid -passlogfile ${working_dir}${output_name}_2pass.log -xvidencopts pass=1:quant_type=h263:nogmc:noqpel:bitrate=-${video_size} -mc 0 -noskip -o /dev/null pass1_filesize=$(echo "$(cat ${working_dir}${output_name}_2pass.log | awk '$6 ~ "^[0-9]" { total += $6; print $total} END { print total } ') / 1024" | bc) echo "At a constant quantizer value of 2, the output filesize is $pass1_filesize Kb's in size" #Is the pass1 filesize smaller than what we desire? if [ $pass1_filesize -lt $video_size ]; then echo "Oh my God It is Smaller!!!" fi #min_pquant/iquant/bquant (add this later) #Second Pass: mencoder -dvd-device $vob_dir dvd://${title} -nosound -vf crop=${crop_values},scale=${final_width}:${final_height} -sws 9 -ovc xvid -passlogfile ${working_dir}${output_name}_2pass.log -xvidencopts pass=2:quant_type=h263:nogmc:noqpel:bitrate=-${video_size} -mc 0 -noskip -o ${working_dir}${output_name}_nosound.avi #ITS MUXING TIME!!! if [ "$audio_format" == "mp3" ]; then mencoder ${working_dir}${output_name}_nosound.avi -ovc copy -oac copy -audiofile ${working_dir}${output_name}.mp3 -mc 0 -noskip -o ${working_dir}${output_name}.avi else #GET AC3 INFO AND THEN MUX midentify ${working_dir}${output_name}.ac3 | sed -ne '/ID_AUDIO_BITRATE/p' -ne '/ID_AUDIO_RATE/p' | head -2 | awk -F '=' '{ print $2 }' | { read audio_bitrate; read audio_rate; mencoder ${working_dir}${output_name}_nosound.avi -ovc copy -oac copy -audiofile ${working_dir}${output_name}.ac3 -audio-demuxer 20 -rawaudio format=0x2000:channels=${num_channels}:rate=${audio_rate}:bitrate=${audio_bitrate} -mc 0 -noskip -o ${working_dir}${output_name}.avi; } fi #If We Encoded To 2CDS+ then we will want to split the encoded video into the appropriate number of parts. if [ "$num_cds" -gt 1 ]; then #Split into $num_cds parts avisplit -i ${working_dir}${output_name}.avi -o ${working_dir}${output_name}-cd -s 700 counter=1; for i in ${working_dir}${output_name}-cd-000[0-9].avi ; do mv $i ${working_dir}${output_name}-cd${counter}.avi; counter=$((counter+1)); done; fi exit
Soon after typing this command mplayer will popup and start playing your chosen title from the DVD. You will notice the outline of a white rectangle that overlays the video. Basically what you want to do is to manipulate the rectangle so that it surrounds the video and crops out any black area around the video. Use the main arrow keys to move the entire rectangle and the numpad arrow keys to increase/decrease the width and height. What I recommend is.
No page links to PerfectDVDRips.