#! /usr/bin/env bash# interactive program to convert videos to MPEG so they can play in Rockbox# these two values depend on the platform!screenwidth=220; screenheight=176# Players LCD size 4:3 video 16:9 video# iPod Video & Gigabeat 320x240 320x240 320x180# iriver H300, iPod Color/Photo & Sansa e200 220x176 220x166 220x124# iPod Nano 176x132 176x128 176x100# iAudio X5 / M5 and iriver H10 20GB / H120 160x128 160x120 160x90# iPod Mini 1G / 2G 138x110 138x104 138x78# iriver H10 5/6GB 128x128 128x96 128x72# Sansa c200 132x80 106x80 132x74# default valuesframerate=25audiobr=64videobr=256croptb=0croplr=0[ $# -ge 2 ] || { echo "Usage: $0 { infile outfile } [ ... ]" exit}opts=getscreensize(){ local w h printf "Screen width (default $screenwidth): " read w screenwidth=${w:-$screenwidth} printf "Screen height (default $screenheight): " read h screenheight=${h:-$screenheight} echo screenwidth=$screenwidth screenheight=$screenheight}getaspectratio(){ local ar x y eof=true echo "Output aspect ratio (5:4 is full screen):" select ar in "4:3" "5:4" "16:9" "221:100" "other"; do eof=false case "$ar" in '4:3') x=4; y=3; break;; '5:4') x=5; y=4; break;; '16:9') x=16; y=9; break;; '221:100') x=221; y=100; break;; 'other') printf 'Other ratio (width height): '; read x y; break;; *) echo "please select one of the options!";; esac eof=true done $eof && return 1 # "x*h > y*w" is mathematically equivalent to "x/w > y/h", but the # former compares only integers (no division hence no fractions) local xy yx let xy='x*screenheight' let yx='y*screenwidth' if [ $xy -gt $yx ]; then # limit width to the screen width width=$screenwidth # /2*2 makes height a multiple of 2 let height='(width*y+x)/(2*x)*2' else # limit height to the screen height height=$screenheight # /2*2 makes width a multiple of 2 let width='(height*x+y)/(2*y)*2' fi echo width=$width height=$height}getyesno(){ local yn while :; do printf "%s" "$1" read yn case "$yn" in [Yy]*) return 0;; [Nn]*) return 1;; *) echo "Please answer 'y' or 'n'";; esac done}getcrop(){ # if there are black bars on the top and bottom (such as a 16:9 video # playing inside a 4:3 video), the amount to crop is # (h - (w / ar)) / 2 # where h is the source height, w is the source width, and ar is the # output aspect ratio. For 320x240 source video containing a 16:9 # video, use 30 for top/bottom crop value. # (240 - (320 / (16/9))) / 2 = 30. printf "Crop top/bottom by amount (in pixels) (default $croptb): " read croptb # the same applies to cropping the sides, except the formula is # inverted (I can't be arsed to do that right now :) printf "Crop left/right by amount (in pixels) (default $croplr): " read croplr echo crop top/bottom=$croptb left/right=$croplr}getframerate(){ local fr r eof=true echo "Output frame rate ($framerate):" select fr in "24" "25" "29.97" "30" "other"; do eof=false case "$fr" in '24') framerate=24; break;; '25') framerate=25; break;; '29.97') framerate=29.97; break;; '30') framerate=30; break;; 'other') printf 'Other frame rate: ' read r framerate=${r:-$framerate} break;; *) echo "please select one of the options!";; esac eof=true done $eof && return 1 echo framerate=$framerate}getvb(){ local vb printf "Output video bitrate ($videobr): " read vb if [ -n "$vb" ]; then videobr="$vb"; fi echo videobr=$videobr}getab(){ local ab printf "Output audio bitrate ($audiobr): " read ab if [ -n "$ab" ]; then audiobr="$ab"; fi echo audiobr=$audiobr}while [ $# -ge 2 ]; do case "$1" in -o) echo got option >&2; opts="$2"; shift 2; continue;; esac infile="$1" outfile="$2" shift 2 echo echo "Configuration for $infile" echo if ! { getscreensize && getaspectratio && getcrop && getframerate && getvb && getab; }; then echo "processing next file..." continue fi ffmpeg -i "$infile" -deinterlace -vcodec mpeg2video -ac 2 -ar 44100 -acodec libmp3lame ${framerate:+-r $framerate} ${croptb:+-croptop $croptb -cropbottom $croptb} ${croplr:+-cropleft $croplr -cropright $croplr} -s ${width}x${height} -vb ${videobr}k -ab ${audiobr}k $opts "$outfile"doneexit