Script for batch conversion on network share

Discussion of the HandBrake command line interface (CLI)
Forum rules
An Activity Log is required for support requests. Please read How-to get an activity log? for details on how and why this should be provided.
Post Reply
KerryXEX
Posts: 6
Joined: Sat Aug 17, 2013 10:53 am

Script for batch conversion on network share

Post by KerryXEX » Sat Oct 05, 2013 4:50 pm

Hi all,

I have compiled now a script to batch-convert all my media to Airplay suitable format in a comfy script which also handles difficulties with dropped network shares. In my case I run the handbrake conversion on a Mac Mini and all the files reside on my Synology. Just wanted to share this as I think might be useful to others too.

The script handles:
- files in current directory (and subs)
- files in a fully qualified (local) path
- files in a subdir (and subs of this) of a pre-defined network share

Options:
- delete or rename original files
- set Handbrake conversion profile

The conversion is designed to replace the old file. At start you can opt to either actually delete or move to a ".old" extension the original file. For security, both the handbrake result "Conversion done" and the resulting filesize of the the converted file vs. original file is checked for validity. So, even if handbrake says it's done correctly, an original file won't be deleted if the converted file appears to be invalid because it's less then 40% smaller than the original file (or whatever threshold you set).

All variables that might need adjustment (like network share names, passwords etc) are setup at the beginning of the script for easy maintenance.

The actual conversion script is started by an an additional starter script which will then show the progress of the logfile. The batch conversion itself runs in background and won't stop if you exit the terminal session.

Here's the starter script "convert.sh":

Code: Select all

#!/bin/bash
###################################################
### convert downloaded avi/mkv/flv to mp4 files ###
###---------------------------------------------###
### pre: bash                                   ###
### out: $1 = Scan folder in afp share location ###
###      $2 = delete switch                     ###
###      $3 = Handbrake preset                  ###
###---------------------------------------------###
### Auth: Kerry Kerschbaumer; kerry@kerry.de    ###
### Vers: 1.0, Oct 5, 2013                      ###
### www.kerry.de                                ###
###################################################
MCS="$HOME/Dev/mediaconvert.sh"
LOG="$HOME/Dev/MediaConv.log"

log() {
    echo `date "+%Y-%m-%d %H:%M:%S"` "$1" >> $LOG
}

clear
echo "############################################"
echo "### CONVERT media to mp4                 ###"
echo "############################################"
echo " "

myPath=""
read -p "Scan folder (blank for current OR subfolder name for standard server share OR fully qualified folder path): " myPath
if [ "$myPath" == "" ]
then
    myPath="."
fi

CSW=""
while [ "$CSW" != "y" -a "$CSW" != "n" ]
do
    read -p "Delete old file after conversion (y/n)? " CSW
done

PRE=""
read -p "Handbrake Preset (blank for Normal): " PRE
if [ "$PRE" == "" ]
then
    PRE="Normal"
fi

nohup $MCS "$myPath" $CSW $PRE 2>>$LOG &
tail -f $LOG

exit

And here the actual conversion script "mediaconvert.sh"

Code: Select all

#!/bin/bash
###################################################
### convert downloaded avi/mkv/flv to mp4 files ###
###---------------------------------------------###
### pre: convert (bash)                         ###
### in : $1 = Scan folder in afp share location ###
###      $2 = delete switch                     ###
###      $3 = Handbrake preset                  ###
###---------------------------------------------###
### Auth: Kerry Kerschbaumer; kerry@kerry.de    ###
### Vers: 1.0, Oct 5, 2013                      ###
### www.kerry.de                                ###
###################################################

##### Settings and vars                   #########
AFPuser="[YourUserName]"
AFPpass="[YourPassword]"
AFPsrvr="[YourServer]"      ### e.g. 192.168.0.2
AFPfldr="[YourShare]"       ### e.g. Movies

if [ "$1" == "." -o "${1:0:1}" == "/" ]
then     ### current dir or fully qualified folder 
    TDIR=$1
else     ### subdir to AFPserver share
    TDIR="/Volumes/$AFPfldr/$1"
fi
DSW=$2
PRE=$3
LOG="$HOME/Dev/MediaConv.log"
CLI="/usr/bin/HandBrakeCLI"

##### Function definitions                #########
log() {
    echo `date "+%Y-%m-%d %H:%M:%S"` "$1" >> $LOG
}

##### Main function                       #########
log "######### BEGIN of new Conversion Scan ################"
log "Dir = $TDIR"
log "Del = $DSW"
log "Pre = $PRE"
log "-------------------------------------------------------"

### Check for running instance
while [ `ps -ef | grep HandBrakeCLI | grep -v grep | wc -l` -gt 0 ]; do 
    log "Already running... wait...."
    sleep 30
done	

### Check availability of afp mount
if [ ! -d "$TDIR" ]; then
    log "Mounting server folder..."
    mkdir "/Volumes/$AFPfldr"
    mount_afp "afp://$AFPuser:$AFPpass@$AFPsrvr/$AFPfldr/" "/Volumes/$AFPfldr"
else
    log "OK: Server folder available"
fi

### Check availability of scan folder
if [ -d "$TDIR" ]
then
	cd "$TDIR"
    ### Log files to be converted
    log "Files found = $(find "$TDIR" -type f \( -name "*.avi" -o -name "*.flv" -o -name "*.wmv" -o -name "*.mkv" \) -print)"

	### Main loop for file conversion
    while IFS= read -d "" -r INFILE
	do
        ### check if network mount is still available
        if [ ! -d "$TDIR" ]; then
            log "Mounting server folder..."
            mkdir "/Volumes/$AFPfldr"
            mount_afp "afp://$AFPuser:$AFPpass@$AFPsrvr/$AFPfldr/" "/Volumes/$AFPfldr"
        fi

        ### generate target filename
        OUTFILE="${INFILE%.*}.mp4"

		log "$INFILE >> $OUTFILE"

        ### Conversion execute  (echo "" required to stay in loop after finish of CLI)
        echo "" | $CLI -i "$INFILE" -o "$OUTFILE" --preset=$PRE 2>&1 | grep "Encode done"

        ### Check validity of conversion before deleting/moving
        if [ "$?" == "0" ]; then 
            log "OK: Encode done!"
            INsize=$(du "$INFILE" | cut -f1)
            OUTsize=$(du "$OUTFILE" | cut -f1)
            myRatio=$(echo "scale=2;(($OUTsize - $INsize) / $INsize * 100)" | bc | cut -d. -f1)
            log "Ratio = $myRatio % of old file size"
            if [ $myRatio -lt -40 ]; then     #### outfile more than 40% smaller than infile
                log "ERROR: Output file does not appear valid: $myRatio % smaller!"
            elif [ "$DSW" == "y" ]; then
                log "Delete $INFILE"
                rm "$INFILE"
            else
                log "Rename $INFILE to .old"
                mv "$INFILE" "$INFILE.old"
            fi
        else
            log "ERROR: Handbrake exited without finishing encoding!"
		fi
        
	done< <(find . -type f \( -name "*.avi" -o -name "*.flv" -o -name "*.wmv" -o -name "*.mkv" \) -print0) 

else    ## no scan folder
    log "ERROR: scan folder not available!!"
fi

log "######### END of Conversion Scan ################"

exit

AlBundy
Bright Spark User
Posts: 370
Joined: Mon Dec 31, 2012 4:47 am

Re: Script for batch conversion on network share

Post by AlBundy » Sun Oct 06, 2013 6:01 pm

A lot of the functionality should be covered by my script (except mounting a share because this is OS dependent).
You can have a look if you want.
viewtopic.php?f=10&t=26163

Al

KerryXEX
Posts: 6
Joined: Sat Aug 17, 2013 10:53 am

Re: Script for batch conversion on network share

Post by KerryXEX » Tue Oct 08, 2013 10:58 am

Yes, I've seen yours. Your script is more focused on a CLI wrapper with all its functionality (which I didn't cover) while mine is more focused on a reliable batch-conversion for a whole library. :-)

AlBundy
Bright Spark User
Posts: 370
Joined: Mon Dec 31, 2012 4:47 am

Re: Script for batch conversion on network share

Post by AlBundy » Tue Oct 08, 2013 3:51 pm

My script was also build to convert a complete library but it's grown to a CLI wrapper. :-)

You can use wildcards for input-files and placeholders for output-names to convert a complete library (also recursive). ;-)

ch1p2014
Posts: 3
Joined: Wed Apr 22, 2015 11:00 pm

Re: Script for batch conversion on network share

Post by ch1p2014 » Thu Apr 23, 2015 8:09 pm

hi buddy could anyone point out the problem im having please - line 89 and 91 giving me this error

2015-04-23 21:55:12 -------------------------------------------------------
2015-04-23 21:55:12 OK: Server folder available
2015-04-23 21:55:12 Files found = /Volumes/05 - Toy.Story.1995.DVDRip.XViD.iNTERNAL-TDF/tdf-toystory.avi
/Volumes/09 - Robin.Hood.1973.WS.DVDRip.XviD-PARTiCLE/robin.hood.1973.ws.dvdrip.xvid.particle.avi
2015-04-23 21:55:12 ./05 - Toy.Story.1995.DVDRip.XViD.iNTERNAL-TDF/tdf-toystory.avi >> ./05 - Toy.Story.1995.DVDRip.XViD.iNTERNAL-TDF/tdf-toystory.mp4
2015-04-23 22:00:43 OK: Encode done!
/root/Dev/mediaconvert.sh: line 89: bc: command not found
2015-04-23 22:00:43 Ratio = % of old file size
/root/Dev/mediaconvert.sh: line 91: [: -lt: unary operator expected
2015-04-23 22:00:43 Delete ./05 - Toy.Story.1995.DVDRip.XViD.iNTERNAL-TDF/tdf-toystory.avi
2015-04-23 22:00:44 ./09 - Robin.Hood.1973.WS.DVDRip.XviD-PARTiCLE/robin.hood.1973.ws.dvdrip.xvid.particle.avi >> ./09 - Robin.Hood.1973.WS.DVDRip.XviD-PARTiCLE/robin.hood.1973.ws.dvdrip.xvid.particle.mp4

AlBundy
Bright Spark User
Posts: 370
Joined: Mon Dec 31, 2012 4:47 am

Re: Script for batch conversion on network share

Post by AlBundy » Thu Apr 23, 2015 8:17 pm

$myRatio is empty because command bc was not found.

ch1p2014
Posts: 3
Joined: Wed Apr 22, 2015 11:00 pm

Re: Script for batch conversion on network share

Post by ch1p2014 » Thu Apr 23, 2015 8:24 pm

not quite sure what i need to change buddy

ch1p2014
Posts: 3
Joined: Wed Apr 22, 2015 11:00 pm

Re: Script for batch conversion on network share

Post by ch1p2014 » Thu Apr 23, 2015 8:29 pm

not quite sure what i need to type in when it say " HandBrake Preset (blank for normal) ?

all im doing is converting some .avi to mp4 to play direct in plex

cheers for the help

Post Reply