Video Encoding For Rockbox - script for Linux/BSD/OS X/Solaris etc

This script is for encoding video to be played on devices running Rockbox.  It’s not for ripping DVD or VCD, it’s for encoding video files such as .avi .mkv ,mp4 .wmv and so on.  This particular script is for screens 220x176 such as Sansa Fuze, Sansa e200, iRiver H320 and H340.  It is easily adapted for other screen sizes.  At the end of the script is a list of the screen sizes of common players which can run Rockbox.

It automatically detects and applies good crop values.  It automatically scales the video to a suitable size.  It detects the audio type in the source video and transcodes it only if necessary.  There are options to make sample encodes (tests), to specify output directory, to disable autocropping, to force a particular fps and to force higher quality encoding.  Run the script with no options or arguments for some short instructions, and read the comments at the end of the script.

Requires:

mplayer and mencoder.

mediainfo.  Get source or binaries from http://mediainfo.sourceforge.net/en

This script comes with the full ‘works-for-me’ warranty and all the benefits of the ‘no-monies-returned’ insurance plan.  For tech support dial 1-800-UR-MOM.

#!/bin/bash  
#   
# vid4rb.sh  
#  
# REQUIREMENTS:  
# Mplayer & Mencoder  
# mediainfo - get it from http://mediainfo.sourceforge.net/en  
  
  
  
# This script encodes video for playback on Rockboxed players. It   
# automatically detects and applies good crop values. It automatically  
# scales the video to a suitable size. It detects the audio type in the  
# source video and transcodes it only if necessary. There are options   
# to make sample encodes (tests), to specify output directory, to   
# disable autocropping, to force a particular fps and to force higher   
# quality encoding. Run the script with no options or arguments for   
# some short instructions & read the comments at the end of the script.  
  
  
#set -x  
  
function usage ()  
{  
 printf "\n\nUSAGE:\n\t$(basename "$0") -o \<full path to output dire\  
ctory\> [videofile1 videofile2 videofile3...]\t\t\t\n\n\tIf -o is not us\  
ed then converted movies are written to their original directories.\n\t  
\t$(basename "$0") -t [videofile1 videofile2 videofile3...] encodes 1\  
20 second test samples.\n\n\tUse -f to set fps. Try 30 for .mov & some \  
old divx encodes\n\n\tUse -c to disable cropping (useful for short clip\  
s)\n\n\tUse -q for High Quality - Video at 400 kbs & Audio at 160 kbs (\  
if transcoded)\n\n\tAll converted movies have old extension removed and\  
 are saved as\n\n\\t\<movie\>\_rb.mpeg\n\n\t or\n\n\t\<movie\>\_sample\_rb.mpe\  
g\n\n"  
}  
  
function getdirname ()  
{  
 # Get original directory name of movie  
 DIRNAME=$(dirname "$MOVIE")  
 echo "$DIRNAME"  
}  
  
function getmoviename ()  
{  
 # Get movie name and strip extension. Allow spaces dots etc  
 VIDOUT=$(basename "$MOVIE" |sed 's/\(.\*\)\..\*/\1/')  
 echo "$VIDOUT"  
}  
function checkaudiocodec ()  
{  
 # Check if audio is already mp3  
 SOUND=$(mediainfo "$MOVIE" |grep "Format" |grep "MPEG Audio" \  
|awk '{print $3}')  
 echo $SOUND  
}  
function checkaudiorate ()  
{  
 # Check if audio is 44.1  
 RATE=$(mediainfo "$MOVIE" |grep "Sampling rate" |grep "44.1" \  
|awk '{print $4}')  
 echo $RATE  
}  
  
function cropdetect ()  
{  
 CROP="1"  
 TOTAL\_LOOPS="10"  
  
 A=0  
 while ["$A" -lt "$TOTAL\_LOOPS"] ; do  
 A="$(( $A + 1 ))"  
 SKIP\_SECS="$(( 30 \* $A ))"  
  
 mplayer "$MOVIE" -ss $SKIP\_SECS \  
 -frames 20 -vo md5sum -nosound -nocache \  
 -vf cropdetect=20:16 2\>&1 \> mplayer.log \< /dev/null  
  
 CROP[$A]=`awk -F 'crop=' '/crop/ {print $2}' \< mplayer.log |\  
 awk -F ')' '{print $1}' | tail -n 1`  
  
done  
 rm md5sums mplayer.log   
  
  
 B=0  
 while ["$B" -lt "$TOTAL\_LOOPS"] ; do  
 B="$(( $B + 1 ))"  
  
 C=0  
 while ["$C" -lt "$TOTAL\_LOOPS"] ; do  
 C="$(( $C + 1 ))"  
  
if ["${CROP[$B]}" == "${CROP[$C]}" ] ; then  
 COUNT\_CROP[$B]="$(( ${COUNT\_CROP[$B]} + 1 ))"  
fi  
done   
done  
  
 HIGHEST\_COUNT=0  
  
 D=0  
 while ["$D" -lt "$TOTAL\_LOOPS"] ; do  
 D="$(( $D + 1 ))"  
  
if ["${COUNT\_CROP[$D]}" -gt "$HIGHEST\_COUNT" ] ; then  
 HIGHEST\_COUNT="${COUNT\_CROP[$D]}"  
 GREATEST="$D"  
fi  
done  
  
 CROP="crop=${CROP[$GREATEST]}"  
 echo -e "$CROP"  
  
}  
  
function getaspect ()  
{  
 # Find movie aspect ratio. This helps with correct scaling and to   
 # write a useful valid header  
 ASPECT=$(mediainfo "$MOVIE" |grep aspect|awk '{print $5}')  
 echo $ASPECT  
}  
  
while getopts 'cf:o:qt' OPTION  
do  
 case $OPTION in  
 c) cflag=1  
 ;;  
 f) fflag=1  
 fval=$OPTARG  
 ;;  
 o) oflag=1  
 oval=$OPTARG  
 ;;  
 q) qflag=1  
 ;;  
 t) tflag=1  
 ;;  
 esac  
done  
shift $(($OPTIND-1))  
  
printf "\n\tMovies to be converted are:\n"  
printf "\n\t\t%s" "$@"  
  
if [$# -lt 1]; then  
 usage  
 exit 1  
fi  
  
for MOVIE in "$@" ; do  
#quit if pebkac  
if [$# -lt 1]; then  
 usage  
 exit 1  
fi  
  
if [! $oflag]; then  
 DEST=$(getdirname)/$(getmoviename)  
 elif [-d "$oval"]; then  
 DEST="$oval"/$(getmoviename)  
 else  
 usage  
 exit 1  
fi  
  
if [$fflag]; then  
 FPS="-ofps $fval"  
 else  
 FPS=""  
fi  
  
if [$tflag]; then  
 SAMPLE=" -ss 120 -endpos 120"  
 MOVIEOUT="$DEST"\_sample\_rb.mpeg  
 else  
 MOVIEOUT="$DEST"\_rb.mpeg  
fi  
  
if [$qflag]; then  
 TRANSCODE="-af resample=44100:0:0:volnorm=2,volume=2 -oac mp3lame \  
-lameopts cbr:preset=160"  
 VBITRATE="vbitrate=400"  
 else  
 TRANSCODE="-af resample=44100:0:0:volnorm=2,volume=2 -oac mp3lame \  
-lameopts cbr:preset=96"  
 VBITRATE="vbitrate=224"  
fi  
  
  
# if audio is already mp1/2/3 at 44.1 then keep it, otherwise transcode.  
  
COPY="-oac copy"  
  
if ["$(checkaudiocodec)" = "MPEG" -a "$(checkaudiorate)" = "44.1"]; \  
then  
 AUDIO=$COPY  
 else  
 AUDIO=$TRANSCODE  
fi   
  
# set scaling to Fuze/iRiver friendly value  
 case $(getaspect) in  
 4:3) SCALE=",scale=224:160"  
 ;;  
 16:9) SCALE=",scale=224:128"  
 ;;  
 \*) SCALE=",scale=224:-11"  
 ;;  
 esac  
  
 printf "\n\n\tConverting $(basename "$MOVIE")\n\t  
 Calculating Cropping, Scaling, Audio...wait\n\n"  
  
  
if [-z $cflag]; then  
# Run cropdetect, discard all the crap, get the crop value  
 CROP=",crop=$(cropdetect| awk -F 'crop=' '/crop/ {print $2}')"  
 echo $CROP  
 else  
 CROP=""  
fi  
  
# Do the encoding  
mencoder "$MOVIE"$SAMPLE \  
-of mpeg $FPS \  
-vf harddup$CROP$SCALE \  
-alang en $AUDIO \  
-ovc lavc -lavcopts vcodec=mpeg2video:$VBITRATE:autoaspect:vmax\_b\_\  
frames=2:threads=2 \  
-o "$MOVIEOUT"  
done  
  
# If mencoder fails with the error "looks like this file was encoded  
# with (divx4/(old)xvid/opendivx) -\> forcing low\_delay flag" then use  
# -f 30 to set the fps to 30. This is also good for some .mov videos  
# which have been encoded at 29.97 fps.  
  
# Cropping  
#  
# The autocrop may often cause a failure if the video is much shorter  
# than 5 minutes. Use -c to disable the autocropping.  
  
# Audio  
#  
# Rockbox's MPEGplayer can play video with mp1, mp2 or mp3 audio, but it  
# can only play audio with a sample rate of 44.1 KHz. It's quite common  
# to find mp3 audio at 48 KHz in video clips. This script detects if   
# audio is mp1/mp2/mp3 at 44.1. If so then the audio is retained. If not  
# then it is transcoded.  
  
# Quality  
#  
# Default settings are video bitrate at 224 and audio at 96.  
# Use -q to switch this to video at 400 and audio at 160.  
# If the existing audio is already mp1/mp2/mp3 at 44.1 then it will not  
# be transcoded even when the -q option is used, only the video bitrate  
# will be increased. This prevents loss of audio quality where possible.  
#  
# Both picture quality and file size increase a lot when raising video  
# bitrate to 400. Above 400 you don't really see any quality  
# improvement at this tiny screen size, only bigger files.  
  
# Screen Size  
#  
# The Fuze and iRiver H3#0 screen are 220x176 but this script uses  
# 224x176. Why? Because to crop and scale and play video requires   
# ideally the dimensions to be multiples of 16 or less ideally 8.  
# 220 is neither but 224 works well and is close enough. It plays fine.  
  
# Screen Sizes of various Rockbox Supported Players  
#  
# iPod Video & Gigabeat 320x240  
# iriver H300, iPod Color/Photo & Sansa e200 220x176  
# iPod Nano 176x132  
# iAudio X5 / M5 and iriver H10 20GB / H120 160x128  
# iPod Mini 1G / 2G 138x110  
# iriver H10 5/6GB 128x128  
# Sansa c200 132x80  
#  
# You can use these values to easily adapt this script for your player.

Message Edited by Takla on 05-26-2010 07:59 PM

You should put the code in [code] tags, otherwise you’re gonna get those smileys…

The code is in code tags and was posted using the ‘Insert Code’ button.  This board’s software doesn’t seem to allow disabling smilies when posting, only globally when viewing.  At least I couldn’t find a way to do it.  Every other board I use allows bbcode and similar to be disabled on a case by case basis when posting, and to to be enabled/disabled globally as preferred.  Every other board I use automatically disables bbcode and smilies in text posted within code boxes…but not here.  This board’s CRM UI is …not my favourite.  By going to My Profile - Preferences - Emoticon Type and checking none, smilies are disabled and code in code boxes displays normally.

Message Edited by Takla on 05-26-2010 08:36 PM