#!/bin/bash

[ "$convertfolder" ] && destfolder="$convertfolder" || destfolder=.
# [ "$scale" ] || scale=480x270
[ "$scale" ] || scale=640x360
[ "$videorate" ] || videorate=800k
[ "$audiorate" ] || audiorate=160k
[ "$preset" ] || preset=medium
[ "$blur" ] || blur=yes

PGM=`basename "$0"`
TMP="/tmp/$PGM.$$"
ORIPWD=$PWD

DEBUG=yes
# STAMP=`date +"%Y%m%d-%H%M%S" 2>/dev/null`
PATH=$(dirname "$0"):$PATH

which ffmpeg | grep -q ffmpeg || alias ffmpeg=avconv
ffmpeg -version >/dev/null 2>/dev/null || exit $?

for app in /usr/bin/avconv avconv ffmpeg MP4Box catmovie
do
    which $app | grep -q $app || continue
#    case $app in
#	ffmpeg|avconv)
#	    $app -c copy 2>&1 | grep -q "Unrecognized option 'c'" && continue
#	    ;;
#   esac
    method=$app && vapp=$app && break
done

helpers="$(which helpers)"
[ "$helpers" ] && . $helpers
log "help functions loaded" 2>/dev/null || exit 1

for prefs in /etc/$PGM ~/etc/$PGM ~/.$PGM
do
	[ -f "$prefs" ] && . "$prefs"
done

os=$(uname -s)
# uname -a | grep -q "Darwin Kernel Version 9.8.0" && os=leopard
# uname -a | grep -q "Darwin Kernel Version 12\.4\." && os=leopard

OPTS="a:b:d:o:p:s:HVQ"

PAR=`echo $OPTS|sed 's/.://g'|grep -v "^$"|sed "s/\([a-zA-Z0-9]*\)/[-\\1]/g" `
PAROPT=`echo $OPTS | sed "s/-://" | sed 's/\(.\)/\\1\//g' \
    | sed 's/\(.\)\/:\//[-\\1 <value>] /g' \
    | sed "s/.\///g" `
USAGE=`echo $PGM $PAR $PAROPT "[<args>]" | sed "s/  / /g"`

HELP="
      -s <scale>
      -b <videorate>
      -a <audiorate>
      -H display this help
      -V verbose mode
      -Q quiet mode

sorry, helpman is in a minimalist mood"

while getopts $OPTS PARAM
  do
    case $PARAM in
	"?")
	    ERROR=1
	    ;;
	-)
	    case $OPTARG in
		help)
		    help
		    ;;
		*)
		    printf "$PGM: illegal option -- $OPTARG"
#		    ERROR=1
	    esac
	    ;;
	d)
	    destfolder=$OPTARG
	    ;;
	s)
	    scale=$OPTARG
	    ;;
	b)
	    videorate=$OPTARG
	    ;;
	a)
	    audiorate=$OPTARG
	    ;;
	o)
	    output=$OPTARG
	    ;;
	p)
	    preset=$OPTARG
	    ;;
	H)
	    help
	    ;;
	V)
	    STDERR="&1"
	    DEBUG=yes
	    ;;
	Q)
	    STDOUT="/dev/null"
		QUIET=yes
	    DEBUG=no
	            ;;
	*)
	    VALUES="$VALUES $PARAM"
	    LASTVAL=$PARAM
    esac

done 2>/dev/null

shift `expr $OPTIND - 1`


unit=$(echo "$videorate" | sed "s/[0-9]//g")
rate=$(echo "$videorate" | sed "s/[^0-9]//g")
buffer=$(($rate * 2))$unit

[ "$ERROR" ] && {
    usage
    end $ERROR "error $ERROR, type '$PGM --help' for more info"
}

[ ! "$1" ] && end 2>/dev/null

cd "$destfolder" || end 4
destfolder="$PWD"

# echo "$scale" | egrep -q -e "^[0-9]+x[0-9]+$" -e "^-1:[0-9]+$" || {
#     [ "$scale" = "o" ] || end 5 "invalid size, use '<width>x<height>', for example 640x480"
# }

TMP="$destfolder/.$PGM.$$"
TMP=.$PGM.$$

errors=0

if [ "$preset" -a "$method" = "avconv" ]
then
    for path in $AVCONV_DATADIR $HOME/.avconv /usr/share/avconv
    do
	ls "$path" | grep -q "^$preset\.avpreset" && goodpreset=$preset && break
    done
fi
[ "$goodpreset" ] && preset=$goodpreset || unset preset
[ "$preset" ] && log "using preset $preset" || log "no preset"

for file in "$@"
do
    cd "$ORIPWD"
    cd "$(dirname "$file")" || break

    name=$(basename "$file" | sed "s/\.[a-zA-Z0-9]*$//")
    tmpfile=$TMP.processing.mp4
    ext=$(echo "$file" | sed "s/.*\.//")
    alias=$TMP.alias.$ext
    alias=$(realpath "$alias")

    log "file $file"
    log "  alias $alias"
    log "  tmpfile $tmpfile"

    rm -f $tmpfile "$alias"
    ln -s "$file" "$alias" || end 1 "could not make alias"
    if [ "$scale" = "o" ]
    then
      convertsize=$($vapp -i "$alias" 2>&1 | egrep "Stream #.*Video:" | sed "s/.*[^0-9]\([0-9]*x[0-9]*\)[^0-9].*/\\1/")
    else
      convertsize=$scale
    fi

    command="$vapp -i $alias"
    [ ! "$output" ] && output=$destfolder/$name.mp4
    [ -f "$output" ] && echo "$PGM: $output exists" && continue

    for codec in aac mp3
    do
	log trying $codec
	$vapp -codecs 2>&1 | grep -q "^[[:blank:]]*.E.....$codec[[:blank:]]" || continue
	acodec=$codec
	break
    done
    [ ! "$acodec" ] && end 1 "no suitable audio codec"
    log "acodec: $acodec"

    for codec in h264 libx64 libx264
    do
	$vapp -codecs 2>&1 | grep -q "^[[:blank:]]*D*E.....$codec[[:blank:]]" || continue
	vcodec=$codec
	break
    done

    [ ! "$vcodec" ] && end 1 "no suitable video codec"
    log "vcodec: $vcodec"

    case $os in
	# Darwin)
	*)
	    acodec="$acodec -strict experimental"
	    directpred="-direct-pred"
	    osparams=""
	    ;;
	# *)
	#     acodec=libfaac
	#     directpred="-directpred"
	#     osparams="-cmp +chroma -partitions +parti8x8+parti4x4+partp8x8+partb8x8 -flags2 +bpyramid+mixed_refs+wpred+dct8x8+fastpskip -flags2 -wpred-dct8x8 -level 30"
    esac

#    avconv --help 2>/dev/null | grep -q profile && profile="-profile main"
    if [ "$preset" ]
    then
	for var in pre preset
	do
	    avconv --help 2>/dev/null | grep -q "\-$var[[:blank:]]" \
		&& preset="-$var $preset" && break
	done
    fi

  ow=$(echo $scale | tr ":" "x" | cut -d x -f 1)
  oh=$(echo $scale | tr ":" "x" | cut -d x -f 2)
  if istrue $blur
  then
    sourceinfo=$(ffprobe "$alias" -v error -select_streams v:0 -show_entries stream=width,height:stream_tags=rotate -of csv=p=0)
    rotate=$(echo $sourceinfo | grep ',.*,' | cut -d , -f 3)
    [ "$rotate" ] && rotate=$(($rotate % 180))
    if [ "$rotate" = "90" ]
    then
      height=$(echo $sourceinfo | cut -d, -f1)
      width=$(echo $sourceinfo | cut -d, -f2)
    else
      width=$(echo $sourceinfo | cut -d, -f1)
      height=$(echo $sourceinfo | cut -d, -f2)
    fi
    if [ $width -lt $height -a "$blur" ]
    then
      log "width $width < height $height let's blur the lines"
      vfilterblur=",split[original][copy];[copy]scale=${ow}:-1,crop=${ow}:${oh},gblur=sigma=20[blurred];[blurred][original]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2"
    else
      unset vfilterblur
    fi
  fi

  command="$command -ac 2 -acodec $acodec -ab $audiorate -vcodec $vcodec $profile $preset -vb $videorate -maxrate $videorate -bufsize $buffer -pix_fmt yuv420p -vf scale=iw/ih*$oh:$oh$vfilterblur"
  # command="$command -ac 2 -vcodec $vcodec $profile $preset -vb $videorate -maxrate $videorate -bufsize $buffer -vf scale=$convertsize -pix_fmt yuv420p -acodec $acodec -ab $audiorate"
  # -threads auto
  # command="$command -acodec $acodec -ab 160000 -s $convertsize -vcodec libx264 -coder 1 -flags +loop $osparams -me_method umh -subq 8 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 2 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -bf 3 -refs 5 $directpred 3 -trellis 1 -wpredp 2 -coder 0 -bf 0 -refs 1 -level 30 -maxrate 10000000 -bufsize 10000000 -wpredp 0 -b $videorate -threads 0 -f mp4"
  command="$command $tmpfile"
  $command || end $? "ERROR processing $command"

  # [ -f $tmpfile ] && mv "$tmpfile" "$output" || {
  ffprobe -i $tmpfile -v error && mv "$tmpfile" "$output" || {
    errors=$(($errors + 1))
    log 1 Could not make $tmpfile
  }
  rm -f $tmpfile
  unset output
done

#echo "errors $errors"
[ $errors -eq 1 ] && errors="$errors $errors error" || {
    [ $errors -gt 1 ] && errors="$errors $errors errors"
}
end $errors
