ANNOUNCEMENT!
The tutorial instructions and scripts have been updated.
Changes:
BatchRip, BatchEncode and the HandBrakeCLI-batch.sh have been updated to correctly parse spaces in the directory tree
BatchEncode now displays progress through Terminal and saves output to a text file.
Thx.
batchRip.scpt
Code: Select all
---------- BatchRip.scpt ----------
---------- Updated: 01-22-2009 ----------
(* This script opens DVDs with FairMount and copies them to a destination folder with a ditto shell script. This script includes support for dual DVD drives installed in a Mac Pro, if two disks are inserted. This script also uses Growl to notify you when completed *)
global diskCount, dvd1Src, dvd1copy, dvd2src, dvd2copy
---------- Properties ----------
-- The output directory for all DVD files. Default is ~/Movies/BatchRip. This folder will be automatically created on first run.
property outputPath1 : "~/Movies/BatchRip"
-- Set ejectDisk to yes if you want your disk(s) to eject when completed. Default is no.
property ejectDisk : no
---------- Optional Properties ----------
-- Dual-Drive: If you have two DVD Drives, you can set a second output directory below to rip two disks at once. The default is ~/Movies/BatchRip2. This folder will be automatically created if 2 disks are mounted and the script is executed.
property outputPath2 : "~/Movies/BatchRip2"
-- Setup Growl Support: Set useGrowl to yes and set the path to the GrowlNotifyLib.scpt.
property useGrowl : no -- If you have growl, set to yes. Default is no.
property growlTitle : "Batch Rip"
property growlLibraryPath : POSIX file "Users/userloginname/Movies/BatchScripts/GrowlNotifyLib.scpt" -- Set the path to the GrowlNotifyLib.scpt.
---------- Batch Script ----------
try
tell application "FairMount.app" to launch
delay 20
countDisks()
copyDisks()
tell application "FairMount.app" to quit
end try
---------- Sub-routines ----------
on countDisks()
try
if useGrowl is yes then setGrowl(growlTitle) of (load script growlLibraryPath)
end try
try
tell application "System Events" to set DVDs to name of disks whose capacity is less than 8.589934592E+9
set diskCount to count of DVDs
set dvd1Src to quoted form of (POSIX path of item 1 of DVDs)
set dvd1copy to escapePath(outputPath1 & "/" & item 1 of DVDs)
set dvd2src to quoted form of (POSIX path of item 2 of DVDs)
set dvd2copy to escapePath(outputPath2 & "/" & item 2 of DVDs)
end try
end countDisks
on escapePath(outputPath)
set the search_string to " "
set the replacement_string to "\\ "
set AppleScript's text item delimiters to the " "
set the text_item_list to every text item of the outputPath
set AppleScript's text item delimiters to the replacement_string
set the new_item_name to the text_item_list as string
set AppleScript's text item delimiters to ""
set the outputPath to new_item_name
end escapePath
on copyDisks()
if diskCount is less than 2 then
mkDir(outputPath1)
do shell script "ditto " & dvd1Src & " " & dvd1copy
cleanUp(dvd1Src, dvd1copy)
else
mkDir(outputPath1)
mkDir(outputPath2)
do shell script "ditto " & dvd1Src & " " & dvd1copy & " &> /dev/null & " & "ditto " & dvd2src & " " & dvd2copy
cleanUp(dvd1Src, dvd1copy)
cleanUp(dvd2src, dvd2copy)
end if
end copyDisks
on mkDir(outputPath)
do shell script "mkdir -p " & escapePath(outputPath)
end mkDir
on cleanUp(dvd, dvdcopy)
try
do shell script "chmod -R 755 " & dvdcopy
if useGrowl is yes then set growlMessage to (characters (10 + 1) thru -2 of the dvd as string) & " has been copied."
if ejectDisk is yes then do shell script "diskutil eject " & dvd
if useGrowl is yes then growlMe(growlTitle, growlMessage) of (load script growlLibraryPath)
end try
end cleanUp
---------- End Script ----------
HandBrakeCLI-batch.sh
Code: Select all
#!/bin/sh
# UPDATED: 01-22-2009
# HandBrakeCLI-batch.sh is a script to batch execute the HandBrakeCLI.
# This script is based upon the MediaForkCLI-batch.sh.
# Original Copyright (C) 2007 Brian Beardmore
# Since MediaForkCLI has been replaced by HandBrakeCLI, some edits were required
# to make it compatible with HandBrakeCLI. The changes are listed below:
# - Changed toolName="HandBrakeCLI" to allow it to execute the HandBrakeCLI
# - Added fileType=".mp4" to allow user to set output container from an external script
# - Updated some of the introductory text to include references to HandBrakeCLI
# - Updated script to correctly parse paths with spaces in the directory tree
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# This script requires HandBrakeCLI.sh tool. The HandBrakeCLI.sh tool can
# be obtained from http://handbrake.fr
# This script searches the entire input directory directory tree looking
# for TS_VIDEO directories looking for DVDs to encode. The output m4v
# filename is the DVD volume name. When multiple tracks are to encoded
# from a DVD, the output filename is appended with the track number.
# For example, 'Monsters, Inc.' DVD has both standard and wide screen tracks
# so there are 'Monsters, Inc.1.m4v' & 'Monsters, Inc.10.m4v' files created.
# For addition information on this script contact the scripts author,
# Brian Beardmore at medfk(at)realisticsoftware(dot)com or
# http://www.realisticsoftware.com
# Examples
# $ ./HandBrakeCLI-batch.sh
# [ encodes all DVDs mounted and encodes any tracks longer then 60min ]
# [ to the mp4 folder in the users Movies folder ]
# $ HandBrakeCLI-batch.sh -i ~/Movies -o toPod -b 1000 -w 576 --minGetTime 50
# [ encodes all DVDs found in the users Movies folder and encodes any ]
# [ tracks longer then 50min, with a 1000kb/s bitrate and scales the output ]
# [ movie to a width of 576 pixels and puts the resulting mp4 files in the ]
# [ toPod folder in the current directory that the command was executed from ]
# Usage: HandBrakeCLI-batch.sh [options]
#
# arg1: inputSearchDir=<string> Set input directory to process all DVDs in it (example: ~/Movies/Batch Rip) "
# arg2: outputDir=<string> Set output directory for all output files (example: ~/Movies/Batch Encode) "
# arg3: fileType=<string> Set the file type: .mp4, .avi, .omg, .mkv, .m4v (example: .m4v) "
# arg4: minTrackTime=<number> Set the minimum time (mins) of the track/s to encode (example: 30) "
# arg5: toolArgs=<string> Set the HandBrakeCLI encode settings (example: -2 -w 640) "
# HandBrakeCLI possible options
# -u, --update Check for updates and exit
# -v, --verbose Be verbose
# -C, --cpu Set CPU count (default: autodetected)
# -f, --format <string> Set output format (avi/mp4/ogm, default:
# autodetected from file name)
# -t, --title <number> Select a title to encode (0 to scan only,
# default: 1)
# -c, --chapters <string> Select chapters (e.g. "1-3" for chapters
# 1 to 3, or "3" for chapter 3 only,
# default: all chapters)
# -a, --audio <string> Select audio channel(s) ("none" for no
# audio, default: first one)
# -s, --subtitle <number> Select subtitle (default: none)
# -e, --encoder <string> Set video library encoder (ffmpeg,xvid,
# x264,x264b13,x264b30 default: ffmpeg)
# -E, --aencoder <string> Set audio encoder (faac/lame/vorbis/ac3, ac3
# meaning passthrough, default: guessed)
# -2, --two-pass Use two-pass mode
# -d, --deinterlace Deinterlace video
# -g, --grayscale Grayscale encoding
# -p, --pixelratio Store pixel aspect ratio in video stream
# -r, --rate Set video framerate (5/10/12/15/23.976/24/25/29.97)
# -R, --arate Set audio samplerate (22.05/24/32/44.1/48 kHz)
# -b, --vb <kb/s> Set video bitrate (default: 1000)
# -q, --quality <float> Set video quality (0.0..1.0)
# -Q, --crf Use with -q for CRF instead of CQP
# -S, --size <MB> Set target size
# -B, --ab <kb/s> Set audio bitrate (default: 128)
# -w, --width <number> Set picture width
# -l, --height <number> Set picture height
# --crop <T:B:L:R> Set cropping values (default: autocrop)
# Revision history:
# 0.20070329.0 - initial release
# 0.20081125.0 - revised for HandBrakeCLI
# 0.20090122.0 - fixed problem with spaces in the directory tree
#############################################################################
# globals
# const global variables
scriptName=`basename "$0"`
scriptVers="2.0"
scriptPID=$$
saveDVDinfo=1 # the dvd track info is also saved as txt file when on
skipDuplicates=1 # if this option is off (-0),
# the new output files will overwrite existing files
E_BADARGS=65
# set the global variables to default
toolName="HandBrakeCLI"
toolPath="/Applications/$toolName"
toolTrackArgs="-t 0" # scans dvd title list for all tracks
inputSearchDir=$1 # set input search directory: "~/Movies/Batch Rip"
outputDir="$2" # set output directory: "~/Movies/Batch Encode"
fileType="$3" # set output container: .m4v, .mp4, .avi, .omg, .mkv
minTrackTime="$4" # this is in minutes: "30"
toolArgs="$5" # set handbrakecli encode settings: "-2 -w 640"
#############################################################################
# functions
verifyFindCLTool()
{
# attempt to find the HandBrakeCLI if the script toolPath is not good
if [ ! -x "$toolPath" ];
then
toolPathTMP=`PATH=.:/Applications:/:/usr/bin:/usr/local/bin:$HOME:$PATH which $toolName | sed '/^[^\/]/d' | sed 's/\S//g'`
if [ ! -z $toolPathTMP ]; then
toolPath=$toolPathTMP
fi
fi
}
displayUsageExit()
{
echo "Usage: $scriptName [options]"
echo ""
echo " -h, --help Print help"
echo " arg1: inputSearchDir=<string> Set input directory to process all DVDs in it (example: ~/Movies/Batch Rip) "
echo " arg2: outputDir=<string> Set output directory for all output files (example: ~/Movies/Batch Encode) "
echo " arg3: fileType=<string> Set the file type: .mp4, .avi, .omg, .mkv, .m4v (example: .m4v) "
echo " arg4: minTrackTime=<number> Set the minimum time (mins) of the track/s to encode (example: 30) "
echo " arg5: toolArgs=<string> Set the HandBrakeCLI encode settings (example: -2 -w 640) "
if [ -x "$toolPath" ];
then
echo " $toolName possible options"
mForkHelp=`$toolPath --help 2>&1`
mForkHelpPt=`printf "$mForkHelp" | egrep -v '( --input| --output| --help|Syntax: |^$)'`
printf "$mForkHelpPt\n"
else
echo " The options available to HandBrakeCLI except -o and -i"
if [ -e "$toolPath" ];
then
echo " ERROR: $toolName command tool is not setup to execute"
echo " ERROR: attempting to use tool at $toolPath"
else
echo " ERROR: $toolName command tool could not be found"
echo " ERROR: $toolName can be install in ./ /usr/local/bin/ /usr/bin/ ~/ or /Applications/"
fi
fi
echo ""
exit $E_BADARGS
}
getTrackListLongerThan()
{
# Two input arguments are are need.
# arg1 is the time in minutes selector
# arg2 is the raw text stream from the track 0 call to HandBrake
# returns: a list of track numbers of tracks longer then the selector
if [ $# -lt 2 ]; then
return ""
fi
minTime="$1"
shift
allTrackText="$*"
aReturn=""
trackList=`eval "echo \"$allTrackText\" | egrep '(^\+ title |\+ duration\:)' | sed -e 's/^[^+]*+ //'g -e 's/title \([0-9]*\):/\1-/'g -e 's/duration: //'g"`
trackNumber=""
for aline in $trackList
do
trackLineFlag=`echo $aline | sed 's/[0-9]*-$/-/'`
if [ $trackLineFlag = "-" ];
then
trackNumber=`echo $aline | sed 's/\([0-9]*\)-/\1/'`
else
set -- `echo $aline | sed -e 's/(^[:0-9])//g' -e 's/:/ /g'`
if [ $3 -gt 29 ];
then let trackTime=($1*60)+$2+1
else let trackTime=($1*60)+$2
fi
if [ $trackTime -gt $minTime ];
then aReturn="$aReturn $trackNumber"
fi
fi
done
echo "$aReturn"
}
makeFullPath()
{
aReturn=""
currentPath=`pwd`
if [ $# -gt 0 ]; then
inPath="$*"
# put full path in front of path if needed
aReturn=`echo "$inPath" | sed -e "s!~!$currentPath/!" -e "s!^./!$currentPath/!" -e "s!^\([^/]\)!$currentPath/\1!" -e "s!^../!$currentPath/../!"`
# remove ../ from path - only goes 4 deep
aReturn=`echo "$aReturn" | sed -e 's!/[^\.^/]*/\.\./!/!g' | sed -e 's!/[^\.^/]*/\.\./!/!g' | sed -e 's!/[^\.^/]*/\.\./!/!g' | sed -e 's!/[^\.^/]*/\.\./!/!g'`
# cleanup by removing //
aReturn=`echo "$aReturn" | sed -e 's!//!/!g'`
fi
echo "$aReturn"
}
isPIDRunning()
{
aResult=0
if [ $# -gt 0 ]; then
txtResult="`ps ax | egrep \"^[ \t]*$1\" | sed -e 's/.*/1/'`"
if [ -z "$txtResult" ];
then aResult=0
else aResult=1
fi
fi
echo $aResult
}
#############################################################################
# MAIN SCRIPT
# initialization functions
verifyFindCLTool
# fix input and output paths to be full paths
inputSearchDir=`makeFullPath "$inputSearchDir"`
outputDir=`makeFullPath "$outputDir"`
# see if the output directory needs to be created
if [ ! -e $outputDir ]; then
mkdir -p "$outputDir"
fi
# sanity checks
if [[ ! -x $toolPath || ! -d $inputSearchDir || ! -d $outputDir || -z "$toolArgs" ]]; then
displayUsageExit
fi
# display the basic setup information
echo "$scriptName $scriptVers"
echo " Start: `date`"
echo " Input directory: $inputSearchDir"
echo " Output directory: $outputDir"
echo " File type: $fileType"
echo " Minimum get track time: $minTrackTime mins"
echo " Tool path: $toolPath"
echo " Tool args: $toolArgs"
echo " - - - - - - - - - - - - - - - -"
# find all the DVD videos in the input search directory tree
# spaces in file path temporarily become /008 and paths are separ with spaces
dvdTSVidList=`find "$inputSearchDir" -name VIDEO_TS -print0 | tr ' ' '\007' | tr '\000' ' '`
# process each DVD video found
for dvdTSDir in $dvdTSVidList
do
# correct the tmp char back to spaces in the DVD file paths
dvdTSDir=`echo $dvdTSDir | tr '\007' ' '`
# get the DVD's name and path to root of the DVD
dvdVolPath=`dirname "$dvdTSDir"`
dvdName=`basename "$dvdVolPath"`
dvdNameALNUM=`basename "$dvdVolPath" | sed 's/[^[:alnum:]^-^_]//g'`
# display information
echo " * Processing DVD '$dvdName'"
# create tmp link to the dvdVolPath to workaround a problem that the
# HandBrakeCLI tool has a problem with the input file paths with space
# when in a script
tmpNoSpacePath="/tmp/dvdVol-$dvdNameALNUM-$scriptPID"
ln -s "$dvdVolPath" $tmpNoSpacePath
# get the track list information from the DVD
cmd="$toolPath -i $tmpNoSpacePath $toolTrackArgs /dev/null 2>&1"
dvdTrackInfo=`eval $cmd`
# save the DVD info
outputFilePath="$outputDir/${dvdName}_Info.txt"
if [ $saveDVDinfo -eq 1 ]; then
if [[ ! -e $outputFilePath || skipDuplicates -eq 0 ]]; then
echo "$dvdTrackInfo" | egrep '[ \t]*\+' > "$outputFilePath"
fi
fi
# get the track number of tracks which are longer then the time desired
trackFetchList=`getTrackListLongerThan $minTrackTime "$dvdTrackInfo"`
if [ ! -z "$trackFetchList" ];
then
echo " Will encode the following tracks: `echo $trackFetchList | sed 's/ /, /g'` "
else
echo " No tracks on this DVD are longer then the minimum track time setting"
fi
trackCount=`echo $trackFetchList | wc -w`
for aTrack in $trackFetchList
do
if [ $trackCount -gt 1 ]
then outputFilePath="$outputDir/${dvdName}${aTrack}$fileType"
else outputFilePath="$outputDir/${dvdName}$fileType"
fi
cmd="$toolPath -i $tmpNoSpacePath $toolArgs -t $aTrack -o \"$outputFilePath\" > /tmp/${dvdNameALNUM}Results.txt 2>&1"
if [[ ! -e $outputFilePath || skipDuplicates -eq 0 ]];
then
# simple command execution
#ripResult=`eval $cmd`
# background command execution with some status
eval $cmd &
cmdPID=$!
while [ `isPIDRunning $cmdPID` -eq 1 ]; do
cmdStatusTxt="`tail -n 1 /tmp/${dvdNameALNUM}Results.txt | grep 'Encoding: '`"
if [ ! -z "$cmdStatusTxt" ]; then
echo -n "$cmdStatusTxt"
fi
sleep 1s
done
echo ""
wait $cmdPID
else
echo " Output file SKIPPED because it ALREADY EXISTS"
fi
if [ -e /tmp/${dvdNameALNUM}Results.txt ]; then
rm /tmp/${dvdNameALNUM}Results.txt
fi
done
rm $tmpNoSpacePath
done
echo " - - - - - - - - - - - - - - - -"
echo " End: `date`"
exit 0
# End Script
batchEncode.scpt
Code: Select all
---------- BatchEncode.scpt ----------
---------- Updated: 01-22-2009 ----------
global batchScript1, batchScript2
---------- Properties ----------
-- The input directory to process all DVDs (TS Folders) in it. Default is: ~/Movies/BatchRip. This folder will be automatically created on first run, but the script will fail since there isn't anything in the folder.
property inputPath1 : "~/Movies/BatchRip"
-- The output directory for all output files. Default is: ~/Movies/BatchEncode. This folder will be automatically created on first run.
property outputPath : "~/Movies/BatchEncode"
-- The path to your HandBrakeCLI-batch.sh script. Default is: ~/Movies/BatchScripts/HandBrakeCLI-batch.sh
property scriptPath : "~/Movies/BatchScripts/HandBrakeCLI-batch.sh" -- Insert the path to HandBrakeCLI-batch.sh.
-- Set your HandBrakeCLI encode settings. Default is the Universal preset, HandBrake's universally compatible, full resolution settings for all current Apple devices: iPod, iPhone, AppleTV, and Macs). For more info in setting parameters, visit http://handbrake.fr and read the CLI Guide Wiki.
property encodeSettings : "--preset=\"Universal\"" -- Note: you must escape quotes for presets.
-- Set the minimum time (minutes) of the track/s to encode (default: 20)
property minGetTime : "20"
---------- Optional Properties ----------
-- Dual-Encode: If you have a fast multi-core processor and hard disk, you can setup two batch folders to encode two RIPs at once.
property batchFolders : 1 -- If adding a second input directory, change number of batch folders to 2.
property inputPath2 : "~/Movies/BatchRip2" -- Set second input directory to process all DVDs in it. Default is: ~/Movies/BatchRip2. This folder will be automatically created if the batchFolders property is set to 2.
-- Output Container: This script's default output container is .m4v(mp4). HandBrake can also save files in: .mkv, .avi, and .ogm.
property fileType : ".m4v"
-- Setup Growl Support: Set useGrowl to yes and set the path to the GrowlNotifyLib.scpt.
property useGrowl : no -- If you have growl, set to yes.
property growlTitle : "Batch Encode"
property growlMessage : "Your HandBrake Encodes Are Done!"
property growlLibraryPath : POSIX file "Users/userloginname/Movies/BatchScripts/GrowlNotifyLib.scpt" -- Set the path to the GrowlNotifyLib.scpt.
---------- Encode Script ----------
try
if useGrowl is yes then setGrowl(growlTitle) of (load script growlLibraryPath)
end try
try
createBatchScript()
mkDir(inputPath1) & mkDir(outputPath)
if batchFolders is 2 then mkDir(inputPath2)
with timeout of 36000 seconds
doScript()
growlMe(growlTitle, growlMessage) of (load script growlLibraryPath)
end timeout
end try
---------- Sub-routines ----------
to doScript()
tell application "Terminal"
activate
tell application "System Events" to keystroke "n" using {command down}
if batchFolders is 2 then repeat 1 times
tell application "System Events" to keystroke "t" using {command down}
end repeat
do script batchScript1 in tab 1 of window 1
if batchFolders is 2 then do script batchScript2 in tab 2 of window 1
repeat until tab 1 of window 1 is not busy
delay 4
end repeat
if batchFolders is 2 then repeat until tab 2 of window 1 is not busy
delay 4
end repeat
end tell
end doScript
to setInput(batchFolder)
set inputDir to quoted form of batchFolder
end setInput
to createBatchScript()
set spc to " "
set inputDir1 to setInput(inputPath1)
set inputDir2 to setInput(inputPath2)
set logFile to " | tee " & escapePath(outputPath)
set outputDir to quoted form of outputPath
set batchScript1 to escapePath(scriptPath) & spc & inputDir1 & spc & outputDir & spc & quoted form of fileType & spc & quoted form of minGetTime & spc & quoted form of encodeSettings & logFile & "/BatchEncode.log"
set batchScript2 to escapePath(scriptPath) & spc & inputDir2 & spc & outputDir & spc & quoted form of fileType & spc & quoted form of minGetTime & spc & quoted form of encodeSettings & logFile & "/BatchEncode2.log"
end createBatchScript
on escapePath(outputPath)
set the search_string to " "
set the replacement_string to "\\ "
set AppleScript's text item delimiters to the " "
set the text_item_list to every text item of the outputPath
set AppleScript's text item delimiters to the replacement_string
set the new_item_name to the text_item_list as string
set AppleScript's text item delimiters to ""
set the outputPath to new_item_name
end escapePath
on mkDir(somepath)
do shell script "mkdir -p " & escapePath(somepath)
end mkDir
---------- End Script ---------