#! /bin/sh

### Transcode a movie using ffmpeg.
###
### This code is in the public domain.
### Written by Robbert Haarman

### Defaults will use XviD for video, Vorbis for audio,
### AVI for the container format, and try to make the
### movie fit on a CD-RW.
###
### To make your movie fit in a specified number of
### megabytes, use the following formula:
###
### (target size in megabytes) * 8192 /
### (movie duration in seconds) = (maximum bitrate)
###
### Be conservative with this number; the actual file size
### will differ due to container overhead and variable
### bitrate encoding. So keep enough margin, or you will
### have to re-encode with larger values.
###
### Once you have your maximum bitrate, divide that among
### video and audio bitrates. As a rule of thumb, audio
### bitrate should be 80 to 128 Kbps to get decent quality,
### and video should be whatever is left.
###
### Example (this is how the default abitrate and vbitrate
### have been derived):
###
### Movie length: 10800 seconds (3 hours)
### Target size: 700 MB
### Max. bitrate: 700 * 8192 / 10800 = 530 Kbps
### Audio bitrate: 112 Kbps
### Video bitrate: 400 Kbps
### Total bitrate: 512 Kbps
###
### Note that, when specifying bitrates, this would
### be specified as:
### --abitrate 112k --vbitrate 400k

# Defaults
acodec=vorbis
abitrate=112k
infile=''
oformat=avi
outfile=''
vcodec=xvid
vbitrate=400k

usage="$0 [options] <infile>"
help="$usage

Valid options are:
--acodec	Audio codec to use (default: $acodec)
--abitrate	Audio bitrate to use (default: $abitrate)
--oformat	Output format to use (default: $oformat)
-o,--outfile	Output file (default computed from input file)
--vcodec	Video codec to use (default: $vcodec)
--vbitrate	Video bitrate to use (default: $vbitrate)
"

# Parse command line
while [ $# -gt 0 ]
do
  arg="$1"
  shift
  case "$arg" in
      --acodec)
	  acodec="$1"
	  shift
	  ;;
      --abitrate)
	  abitrate="$1"
	  shift
	  ;;
      --oformat)
	  oformat="$1"
	  shift
	  ;;
      -o|--outfile)
	  outfile="$1"
	  shift
	  ;;
      --vcodec)
	  vcodec="$1"
	  shift
	  ;;
      --vbitrate)
	  vbitrate="$1"
	  shift
	  ;;
      -h|--help)
	  echo "$help"
	  exit
	  ;;
      -*)
	  echo "Unknown option: $arg" >&2
	  echo "$usage" >$2
	  exit 128
	  ;;
      *)
	  infile="$arg"
	  shift
	  ;;
  esac
done

# If no input file given, barf
if [ -z "$infile" ]
then
    echo "No input file specified" >&2
    echo "$usage" >&2
    exit 128
fi

# If no output file given, compute from input filename and output format
if [ -z "$outfile" ]
then
    outfile="$(printf '%s' "$infile" | sed 's/\.[^.]*$//').$oformat"
fi

ffmpeg -i "$infile" -acodec "$acodec" -ab "$abitrate" -vcodec "$vcodec" -b "$vbitrate" -f "$oformat" "$outfile"
