#!/bin/bash echo "Re-encoding script (c) 2008 Zider" main () { checkapps getsrcinfo printsrcinfo calcaudiosize calcvidres printdstinfo if [ "$copyaudio" = "yes" ]; then audio else audfile=$infile fi encode 1 encode 2 } getconfig () { vid_maxx="720" vid_maxy="576" cfg_aspect="4:3" vid_bitrate="1500" aud_bitrate="128" aud_format="vorbis" threads=1 tmpfile="/dev/null" tmpvid="$HOME/.reencode.$$.vid" tmpaud="$HOME/.reencode.$$.aud" tmptime="$HOME/.reencode.$$.time" tmpout="$HOME/.reencode.$$.out" tmppipe="$HOME/.reencode.$$.pipe" logfile="$HOME/.reencode.$$.log" rm -f $logfile $tmpvid $tmpaud cfg_ratio=$(echo "scale=10; `echo ${cfg_aspect} | awk -F\: '{print $1}'`/`echo ${cfg_aspect} | awk -F\: '{print $2}'`"|bc) vid_realx=$(echo "scale=0; $vid_maxx * $cfg_ratio"|bc|awk -F\. '{print $1}') if [ $(echo "scale=1; $vid_maxx * $cfg_ratio"|bc|awk -F\. '{print $2}') -gt 5 ]; then ((vid_realx++)) fi } checkapps () { timepath=$(which time 2>/dev/null) if [ -n "$timepath" ]; then timecmd="eval $timepath -o $tmptime --format=\" (finished in %E, using %P CPU)\"" else timecmd="" fi mplayerpath=$(which mplayer 2>/dev/null) if [ -z "$mplayerpath" ];then echo "ERR: mplayer not found, exiting" exit 1 fi mencoderpath=$(which mencoder 2>/dev/null) if [ -z "$mencoderpath" ];then echo "ERR: mencoder not found, exiting" exit 1 fi mkvmergepath=$(which mkvmerge 2>/dev/null) if [ -z "$mkvmergepath" ];then echo "ERR: mkvmerge not found, exiting" exit 1 fi } trap 'echo "ERR: some command failed, exiting" ; exit 1' ERR trap 'echo Control-C trap caught && rm -f $logfile $tmpvid $tmpaud $tmptime && exit 1' 2 ### Get information from the source file.. getsrcinfo () { # echo $infile audid_count=0 while read line do STR=$line var="`echo $line | awk -F\= '{print $1}'`" val=`echo $line | awk -F\= '{print $2}'` if [ "$var" = "ID_AUDIO_ID" ]; then if [ ! -z "$ID_AUDIO_ID" ];then oldvar=$ID_AUDIO_ID fi if [ "$audid_count" == 0 ];then eval `echo $var`=$val else eval `echo $var`="$oldvar $val" fi ((audid_count++)) else eval `echo $line | awk -F\= '{print $1}'`=\"$val\" fi done < <(mplayer -vo null -ao null -frames 1 -identify "$infile" 2>/dev/null | awk '/^ID_/') if [[ -n ${vid_aspect} ]]; then if [[ ${vid_aspect} =~ [0-9]*\.[0-9]* ]]; then ID_VIDEO_ASPECT=${vid_aspect} elif [[ ${vid_aspect} =~ [0-9]*:[0-9]* ]]; then ID_VIDEO_ASPECT=$(echo "scale=4; `echo ${vid_aspect} | awk -F\: '{print $1}'`/`echo ${vid_aspect} | awk -F\: '{print $2}'`"|bc) else echo "-va must be in the form of 16:9 or 1.7778!" exit 0 fi fi echo $ID_VIDEO_ASPECT } ### ..and print it.. printsrcinfo () { seconds=$(echo "$ID_LENGTH"|awk -F\. '{print $1}') echo "Source file info:" echo "Play length: $((seconds / 3600)):$(printf "%.2d" $(($((seconds % 3600)) / 60))):$(printf "%.2d" $((seconds % 60)))" echo "Video format: $ID_VIDEO_FORMAT" echo "Video resolution: $ID_VIDEO_WIDTH x $ID_VIDEO_HEIGHT (aspect $ID_VIDEO_ASPECT)" echo "Audio format: $ID_AUDIO_CODEC" echo "" } ## Calculate audio track size and video bitrate.. calcaudiosize () { if [ "$copyaudio" = "yes" ]; then aud_br=0 for ID_AUDIO_ID in $ID_AUDIO_ID;do aud_br=$(echo "$aud_br+($aud_bitrate*1000)"|bc) done else aud_br=$ID_AUDIO_BITRATE aud_format="$ID_AUDIO_CODEC (copy)" fi if [ -n "$vid_size" ];then vid_bitrate="$(echo "((($vid_size*1024)-(($aud_br/1024/8)*$ID_LENGTH)/1024)/$ID_LENGTH)*10"|bc)" fi } ### Calculate video resolution.. calcvidres () { ID_VIDEO_WIDTH=$(echo "scale=0; $ID_VIDEO_WIDTH * $ID_VIDEO_ASPECT"|bc|awk -F\. '{print $1}') rx=$(echo "scale=10; $ID_VIDEO_HEIGHT / $ID_VIDEO_WIDTH"|bc) ry=$(echo "scale=10; $ID_VIDEO_WIDTH / $ID_VIDEO_HEIGHT"|bc) if [ ${ID_VIDEO_WIDTH} -gt $vid_realx ]; then ID_VIDEO_WIDTH=$vid_realx ID_VIDEO_HEIGHT=$(echo "scale=10; $ID_VIDEO_WIDTH * $rx"|bc|awk -F\. '{print $1}') fi # echo "scale=10; $ID_VIDEO_WIDTH * $rx"|bc|awk -F\. '{print $2}' if [ ${ID_VIDEO_HEIGHT} -gt $vid_maxy ]; then ID_VIDEO_HEIGHT=$vid_maxy ID_VIDEO_WIDTH=$(echo "scale=10; $ID_VIDEO_HEIGHT * $ry"|bc|awk -F\. '{print $1}') fi echo "$ID_VIDEO_WIDTH x $ID_VIDEO_HEIGHT" # echo "scale=10; $ID_VIDEO_WIDTH / $cfg_ratio"|bc|awk -F\. '{print $2}' ID_VIDEO_WIDTH=$(echo "scale=0; $ID_VIDEO_WIDTH / $cfg_ratio"|bc|awk -F\. '{print $1}') # ((ID_VIDEO_WIDTH++)) ID_VIDEO_WIDTH=$(echo "scale=0; ($ID_VIDEO_WIDTH/16)*16"|bc) ID_VIDEO_HEIGHT=$(echo "scale=0; ($ID_VIDEO_HEIGHT/16)*16"|bc) } ### Print out what we will encode to.. printdstinfo () { if [ -z "$vid_size" ];then vid_size="$(echo "(($vid_bitrate/8)+($aud_br/1024/8))*$ID_LENGTH/1024"|bc)" # echo "(($vid_bitrate/8)+($aud_br/1024/8))*$ID_LENGTH/1024" fi echo "Destination file info:" echo "Video format: XVID @ $vid_bitrate kbps" echo "Video resolution: $ID_VIDEO_WIDTH x $ID_VIDEO_HEIGHT (${cfg_aspect})" echo "Audio format: $aud_format @ $(($aud_br/1000)) kbps" echo "File size: $vid_size MB" echo "" } ### Extract audio track(s).. audio () { audid_count=1 aud_size=0 for ID_AUDIO_ID in $ID_AUDIO_ID;do echo -n "Extracting audio track $audid_count.. " rm -f $tmppipe && mkfifo $tmppipe $($timecmd $mplayerpath $short "$infile" -vo null -vc dummy -aid $ID_AUDIO_ID -ao pcm:waveheader:file="/dev/fd/3" 3>&1 1>$tmppipe 2>&1| oggenc -Q -b $aud_bitrate -o "$tmpaud-$audid_count" /dev/stdin | cat $tmppipe | tr "\r" "\n" | sed -u -n '0~5p' >$tmpout)& mppid=$! while [ "$(ps -p $mppid | wc -l)" = "2" ];do sleep 1 line="$(tail -n 2 $tmpout|head -n 1)" vid_pos="$(printf "%6s" `echo -n "$line" | sed -n -e "s/.*A:\([ ,0-9]*\.[0-9]\) (.*/\1/p"`)" if [ ! "$vid_pos" = "" ]; then if [ "$short" = "" ]; then vid_length=$(printf "%4s" `echo $ID_LENGTH | awk -F\. '{print $1}'`) vid_pct="$(printf "%2s" `echo "scale=2; ($vid_pos/$vid_length)*100"|bc|awk -F\. '{print $1s}'`)%" else vid_length=" 30" vid_pct="$(printf "%2s" `echo "scale=2; ($vid_pos/$vid_length)*100"|bc|awk -F\. '{print $1s}'`)%" fi echo -en "$(echo "$vid_pos" | awk -F\. '{print $1}')/$vid_length sec ($vid_pct)\033[19D" fi done audfile=$tmpaud-$audid_count ((audid_count++)) aud_size=$(echo "$aud_size+(($aud_bitrate/8)*$ID_LENGTH)"|bc) echo "OK $(cat $tmptime)" rm -f $tmppipe done } ### Start video encoding pass 1 and 2.. encode () { pass=$1 echo -n "Encoding to temp file (pass $pass).. " $($timecmd $mencoderpath \"$infile\" -lavdopts threads=$threads $short -vf scale=$ID_VIDEO_WIDTH:$ID_VIDEO_HEIGHT -nosound -ovc lavc -lavcopts vcodec=mpeg4:threads=2:vpass=$pass:turbo -ffourcc XVID -passlogfile \"$logfile\" -o \"$tmpvid\" 2>&1 | tr "\r" "\n" | sed -u -n '0~5p' >$tmpout)& mppid="$!" while [ "$(ps -p $mppid | wc -l)" = "2" ];do sleep 1 line="$(tail -n 2 $tmpout|head -n 1)" vid_pos="$(echo -n "$line" | sed -n -e "s/.*Pos:\([ ,0-9]*\.[0-9]\)s.*/\1/p")" if [ ! "$vid_pos" = "" ]; then if [ "$short" = "" ]; then vid_length=$(printf "%4s" `echo $ID_LENGTH | awk -F\. '{print $1}'`) vid_pct="$(printf "%3s" `echo -n "$line" | sed -n -e "s/.*(\([ ,0-9]*%\)).*/\1/p"`)" else vid_length=" 30" vid_pct="$(printf "%3s" `echo "scale=2; ($vid_pos/$vid_length)*100"|bc|awk -F\. '{print $1s}'`)%" fi # echo -en "$(echo "$vid_pos" | awk -F\. '{print $1}')/$vid_length sec ($vid_pct)\033[19D" echo -en "\r\033[34C$(printf "%5s" `echo "$vid_pos" | awk -F\. '{print $1}'`)/$(printf "%5s" `echo $vid_length`) sec ($vid_pct)" fi done echo -e "\r\033[34COK $(cat $tmptime)" } getconfig getargs () { mkvmopts="/dev/null" debug="no" short= copyaudio="no" infile= outfile= alang= slang= vid_size= vid_aspect= while [ $# -gt 0 ] do case "$1" in -ab) aud_bitrate="$2"; copyaudio="yes"; shift;; -am) aud_format="mp3"; shift;; -vb) vid_bitrate=$2; shift;; -vx) vid_maxx="$2"; shift;; -vy) vid_maxy="$2"; shift;; -vs) vid_size="$2"; shift;; -va) vid_aspect="$2"; shift;; -c) copyaudio="yes";; -d) mkvmopts="/dev/stdout" debug="yes";; -s) short="-endpos 00:00:30";; -t) tmpfile="$tmpvid";; -i) infile="$2"; shift;; -o) outfile="$2"; shift;; -alang) alang="--language 0:$2"; shift;; -slang) slang="--language 0:$2"; shift;; -*) echo >&2 \ "usage: $0 -i infile -o outfile [-ab ] [-vb ] [-x ] [-y ] [-alang