#!/bin/sh # # small wrapper around mencoder and mpeg2enc for quick usage # # Copyright (c) 2003,2004 Mathias Gumz # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # TODO: # # enhance foolproveness :) # # # globals # DLGT="any2avi (c) 2003,2004 by m.gumz" RCFILE="$HOME/.any2avi/any2avirc" MENCODER="mencoder" MPLAYER="mplayer" MPEG2ENC="mpeg2enc" INPUT="$PWD/in.avi" OUTPUT="$PWD/out.avi" TBEGIN="" TEND="" SCALE="" VBITRATE="3000" VCODEC="mpeg4" ISUBJECT="unknown" IARTIST="unknown" ICOPYRIGHT="unknown" INAME="unknown" ACTION="quick" MODE="avis" PIC_TYPE="png" GRAY="" SOUND=" -oac copy" DLG="dialog" # # functions # display_help() { if [ "$1" != "actions" -a "$1" != "modes" -a "$1" != "examples" ]; then cat << EOF ABOUT any2avi is a small wrapper around mencoder to make it easier to use. so it converts almost any incoming videostream to a lot of other videoformats. SYNOPSIS any2avi [-h] [-m mode] [-a action] [-b bitrate] [-s scale] [-B time] [-E time|size] [-NSAC string] [-o name] inputfile(s) OPTIONS -h display help -r configfile file, which contains settings -G runs any2avi in guimode, answer some dialogs and thats it :) -> also known as "easymode" -o name outputfile -a action encodemode, default is quick -m mode inputmode, default is avis -v video-only (remove audio if any) -b rate bitrate (1400 default) -c codec mpeg4 | msmpeg4 -s scale scalefactors (eg 640:480) -B time begin (eg 1:10:02) -E time|mark end (eg 30:00 or 5mb) -N text title of the resulting avi -S text subject of the avi -A text artist information -C text copyright information -V /path/to/mencoder -W /path/to/mplayer -U /path/to/mpeg2enc EOF fi if [ "$1" == "full" -o "$1" == "actions" ]; then cat << EOF ACTIONS help display all actions quick uses some quick settings good single pass encoding with good quality 2pass 2pass encoding with very good quality quick2pass 2pass quick encoding cat appends all input files to the output.avi works correct only with avis which are of the same size and are encoded with the same codec repair create a new index in an avi addinfo adds just the info (copyrights etc) mpeg2 encoding a highquality mpeg2movie, 7500KBit/s and 720x556 resolution EOF fi if [ "$1" == "full" -o "$1" == "modes" ]; then cat << EOF MODES help display all modes vids input files are videostreams pics input files are pictures (sgi|png|tga|jpg) EOF fi if [ "$1" == "full" -o "$1" == "rcfile" ]; then cat << EOF RCFILE any2avi is available to load its defaults from a configfile which is normaly saved at \$HOME/.any2avi/any2avirc . format is plain and simple and straightforward: # comments keyword = value open any2avi with -gui and create a basic one, if you want. EOF fi if [ "$1" == "full" -o "$1" == "examples" ]; then cat << EOF EXAMPLES any2avi -a 2pass -m pics -o out.avi \*.jpg EOF fi if [ "$1" != "actions" -a "$1" != "modes" -a "$1" != "examples" ]; then cat << EOF AUTHOR mathias gumz < gumz at cs.uni-magdeburg.de > LINKS http://www.mplayerhq.hu/ http://www.MPlayerHQ.hu/DOCS/tech/encoding-tips.txt EOF fi } ############################################################################## ############################################################################## # # basic stuff # read_rcfile() { if [ -f "$RCFILE" ] then local t=`mktemp` cat "$RCFILE" | sed '/^[[:space:]]*$/d' | sed '/^[#!]/d' > $t while read l do local opt=`echo $l | cut -d '=' -f 1` local val=`echo $l | cut -d '=' -f 2` local valtrim=`echo $l | cut -d '=' -f 2 | sed -e 's/^[[:space:]]*\([[:graph:]]\+\).*/\1/g'` case "$opt" in mplayer* ) [ -n "$valtrim" ] && MPLAYER="$valtrim";; mencoder* ) [ -n "$valtrim" ] && MENCODER="$valtrim";; mpeg2enc* ) [ -n "$valtrim" ] && MPEG2ENC="$valtrim";; codec* ) [ -n "$valtrim" ] && VCODEC="$valtrim";; bitrate* ) [ -n "$valtrim" ] && VBITRATE="$valtrim";; info_subject* ) ISUBJECT="$val";; info_artist* ) IARTIST="$val";; info_copyright* ) ICOPYRIGHT="$val";; info_name* ) INAME="$val";; action* ) [ -n "$valtrim" ] && ACTION="$valtrim";; mode* ) [ -n "$valtrim" ] && MODE="$valtrim";; pic_type* ) [ -n "$valtrim" ] && PIC_TYPE="$valtrim";; scale* ) [ -n "$valtrim" ] && SCALE="$valtrim";; dialog* ) [ -n "$valtrim" ] && DLG="$valtrim";; esac done < $t rm $t fi } write_rcfile() { echo "# any2avirc - automatic created by any2avi" echo "# edit until you are happy!" echo "" echo "# programs to use" echo "mplayer = $MPLAYER" echo "mencoder = $MENCODER" echo "mpeg2enc = $MPEG2ENC" echo "dialog = $DLG" echo "" echo "# default values" echo "action = $ACTION" echo "bitrate = $VBITRATE" echo "codec = $VCODEC" echo "scale = $SCALE" echo "" echo "" } print_parameters() { echo "input: $INPUT" echo "output: $OUTPUT" echo "- info -------------------" echo "subject: $ISUBJECT" echo "artist: $IARTIST" echo "copyright: $ICOPYRIGHT" echo "name : $INAME" echo "- parameters -------------" echo "action: $ACTION" echo "codec: $VCODEC" echo "bitrate: $VBITRATE" echo "scale: $SCALE" echo "" echo "- programs ---------------" echo "dialog: $DLG" echo "mplayer: $MPLAYER" echo "mencoder: $MENCODER" echo "mpeg2enc: $MPEG2ENC" } ############################################################################## ############################################################################## # # encode functions # menc_input() { case "$MODE" in a | avis) echo -n "$INPUT";; p | pics) echo -n "mf://$INPUT";; esac } menc_vf() { case "$1" in default) echo -n " -vf denoise3d";; scale_denoise) echo -n " -vf denoise3d,scale=$SCALE";; scale) echo -n " -vf scale=$SCALE";; esac } menc_lavc() { echo -n "${SOUND} -ovc lavc" case "$1" in quick ) echo -n " -lavcopts vbitrate=$VBITRATE:vcodec=$VCODEC:vhq:vqmin=2${GRAY}";; good ) case "$VCODEC" in msmpeg* | mpeg*video ) echo -n " -lavcopts vbitrate=$VBITRATE:vcodec=$VCODEC:vhq${GRAY}" ;; * ) echo -n " -lavcopts vbitrate=$VBITRATE:vcodec=$VCODEC:vhq:v4mv:vqmin=2:qpel${GRAY}" ;; esac ;; dummy ) echo -n " -lavcopts vbitrate=$VBITRATE:vcodec=$VCODEC";; # vqscale=2 in pass1 seems to create better values in the log and so better # results pass1 ) case "$VCODEC" in msmpeg* | mpeg*video ) echo -n " -lavcopts vpass=1:vqscale=2:vcodec=$VCODEC:vhq:vqmin=2${GRAY}" ;; * ) echo -n " -lavcopts vpass=1:vqscale=2:vcodec=$VCODEC:vhq:v4mv:vqmin=2:qpel${GRAY}" ;; esac ;; pass2 ) case "$VCODEC" in msmpeg* | mpeg*video ) echo -n " -lavcopts vpass=2:vqscale=2:vcodec=$VCODEC:vhq:vqmin=2${GRAY}" ;; * ) echo -n " -lavcopts vpass=2:vqscale=2:vcodec=$VCODEC:vhq:v4mv:vqmin=2:qpel${GRAY}" ;; esac ;; qpass1 ) echo -n " -lavcopts vpass=1:vqscale=2:vcodec=$VCODEC:vqmin=2${GRAY}";; qpass2 ) echo -n " -lavcopts vpass=2:vbitrate=$VBITRATE:vcodec=$VCODEC:vqmin=2${GRAY}";; esac } menc_add_info() { echo -n "-info name=\"$INAME\":subject=\"$ISUBJECT\":artist=\"$IARTIST\":copyright=\"$ICOPYRIGHT\"" } # mplayer-source/TOOLS/midentify mplay_identify() { $MPLAYER -vo null -ao null -frames 0 -identify "$@" 2>/dev/null | grep "^ID" | sed -e 's/[`\\!$"]/\\&/g' | sed -e '/^ID_FILENAME/ { s/^ID_FILENAME=\(.*\)/ID_FILENAME="\1"/g; }' } ############################################################################## ############################################################################## # gui # dlg_yesno() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --yesno "$*" 0 0 ;; esac } dlg_error() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --title "error" \ --msgbox "$*" 0 0 ;; esac } dlg_success() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --title "success" \ --msgbox "$*" 0 0 ;; esac } dlg_inputfile() { [ -z "$INPUT" ] && INPUT="$PWD/in.avi" case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --stdout --title "choose inputfile" \ --fselect `dirname $INPUT`/ $DLGMAXH $DLGMAXW ;; esac } dlg_outputfile() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --stdout --title "choose outputfile" \ --fselect $OUTPUT $DLGMAXH $DLGMAXW sleep 10 ;; esac } dlg_codec() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --stdout --title "choose codec" \ --radiolist " " $DLGMAXH $DLGMAXW $(( $DLGMAXH - 5 )) \ "mpeg2video" "mpeg2 video" off \ "mpeg4" "mpeg4 video" off \ "msmpeg4" "mpeg4 for windows (divx3)" on sleep 10 ;; esac } dlg_bitrate() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --stdout --title "choose bitrate" \ --inputbox "KBit/s" 0 0 $VBITRATE ;; esac } dlg_scale() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --stdout --title "choose scalefactor" \ --inputbox "Width:Height" 0 0 $SCALE ;; esac } dlg_beginpos() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --stdout --title "startposition" \ --inputbox "Time in sec" 0 0 $TBEGIN ;; esac } dlg_endpos() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --stdout --title "endposition" \ --inputbox "Examples 56 - encode 56 sec 01:30:01 - encode 1h30min1sec 40mb - encode 40mb 1024kb - encode 1024kb" 0 0 $TEND ;; esac } dlg_display_params() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --stdout --title "display parameters so far" --msgbox "\n action : $ACTION\n in : $INPUT\n out : $OUTPUT\n codec : $VCODEC\n bitrate : $VBITRATE\n beginpos : $TBEGIN\n endpos : $TEND\n " 0 0 ;; esac } dlg_action() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --title "encodemodes" --stdout --radiolist " " 0 0 0 \ "good" "good settings, 1 pass" on \ "2pass" "2pass encoding, high quality" off \ "quick" "preview settings" off ;; esac } dlg_identify() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --title "identify inputfile" \ --stdout --msgbox "`mplay_identify $INPUT`" 0 0 ;; esac } dlg_mainmenu() { case "$DLG" in dialog ) $DLG --backtitle "$DLGT" --title "mainmenu" --stdout --menu " " 0 0 0 \ "i" "inputfile" \ "o" "outputfile" \ "" "----------" \ "c" "outputformat" \ "b" "bitrate" \ "s" "skalierung" \ "B" "beginposition" \ "E" "endposition" \ "" "----------" \ "a" "encodemode" \ "" "----------" \ "I" "identify inputfile" \ "d" "display parameters" \ "" "----------" \ "R" "repair/reindex inputmovie" \ "e" "encode the movie" \ "" "----------" \ "p" "create rc-file" \ "q" "exit any2avi" ;; esac } gui_mainloop() { while true do ret=`dlg_mainmenu` [ ! $? = 0 ] && exit 0 case "$ret" in i ) ret=`dlg_inputfile` [ $? = 0 -a -f "$ret" ] && INPUT="$ret" ;; o ) while true do ret=`dlg_outputfile` if [ ! -f "$ret" ]; then OUTPUT="$ret" break else dlg_yesno "[ $ret ] exits ... overwrite?" [ $? = 0 ] && ( OUTPUT="$ret"; break ) fi done ;; c ) ret=`dlg_codec` [ $? = 0 ] && VCODEC="$ret" ;; b ) ret=`dlg_bitrate` [ $? = 0 ] && VBITRATE="$ret" ;; B ) ret=`dlg_beginpos` [ $? = 0 ] && TBEGIN="$ret" ;; E ) ret=`dlg_endpos` [ $? = 0 ] && TEND="$ret" ;; s ) ret=`dlg_scale` ;; a ) ret=`dlg_action` [ $? = 0 ] && ACTION="$ret" ;; d ) ret=`dlg_display_params` ;; I ) ret=`dlg_identify` ;; R ) if [ -z "$INPUT" -o ! -f "$INPUT" ]; then dlg_error "no inputfile specified" else "$0" -o "$INPUT"_tmp -V "$MENCODER" -a repair "$INPUT" if [ $? = 0 ]; then dlg_success "successfully repaired." mv "$INPUT"_tmp "$INPUT" else ret=`dlg_yes "error while repairing... delete tmpfile?"` [ $? = 0 ] && rm -f "$INPUT"_tmp fi fi ;; e ) break; ;; p ) if [ ! -d "`dirname $RCFILE`" ]; then dlg_yesno "create new directory for rcfile?" if [ $? = 0 ]; then mkdir "`dirname $RCFILE`" else continue fi fi if [ -f "$RCFILE" ]; then dlg_yesno "rcfiles exists, overwrite?" [ ! $? = 0 ] && continue fi write_rcfile > $RCFILE dlg_success "successfully created $RCFILE" ;; q ) exit 1 ;; esac done TBEGIN="-ss $TBEGIN" TEND="-endpos $TEND" } gui_set_guisettings() { case "$DLG" in *dialog* ) DLG="dialog" DLGMODE="yes" DLGMAXH=`dialog --stdout --print-maxsize | awk '{ print $2 ; };' | cut -d ',' -f 1` DLGMAXW=`dialog --stdout --print-maxsize | awk '{ print $3; };'` (( $DLGMAXH < 10 )) && ( echo "error: too small terminal, exit."; exit 1) (( $DLGMAXW < 20 )) && ( echo "error: too small terminal, exit."; exit 1) DLGMAXH=$(( $DLGMAXH - 20 )) DLGMAXW=$(( $DLGMAXW - 5 )) (( $DLGMAXH < 10 )) && DLGMAXH=10 (( $DLGMAXW < 20 )) && DLGMAXW=20 ;; esac } ############################################################################## ############################################################################## # # main program # read_rcfile # get cmdline options while getopts ":c:V:W:hB:E:b:m:a:p:e:T:C:A:N:o:s:gGi" opts do case "$opts" in h) display_help "full"; exit 0;; G) if [ -n "$DLG" ] then gui_set_guisettings else echo "error, no gui-available here. exit." exit 1 fi ;; r) RCFILE="$OPTIONS";; o) OUTPUT="$OPTARG";; a) ACTION="$OPTARG";; m) MODE="$OPTARG";; g) GRAY=":gray";; v) SOUND=" -nosound ";; i) ACTION="ident";; b) VBITRATE="$OPTARG";; c) VCODEC="$OPTARG";; s) SCALE=`echo $OPTARG | sed -e 's/[\:x,\*]/\:/g'`;; B) TBEGIN="-ss $OPTARG";; E) TEND="-endpos $OPTARG";; N) INAME="$OPTARG" ;; S) ISUBJECT="$OPTARG";; A) IARTIST="$OPTARG";; C) ICOPYRIGHT="$OPTARG";; V) MENCODER="$OPTARG";; W) MPLAYER="$OPTARG";; U) MPEG2ENC="$OPTARG";; esac done shift $(($OPTIND - 1)) #print_parameters #exit # start gui if wanted if [ -n "$DLGMODE" -a "$DLGMODE" = "yes" ]; then [ -n "$@" ] && INPUT="$@" gui_mainloop else if [ $# = 0 ]; then echo "no inputfile specified" exit 1 fi INPUT="$@" fi # help actions ? if [ "$ACTION" == "h" -o "$ACTION" == "help" ]; then display_help "actions" exit 0 fi if [ "$MODE" == "h" -o "$MODE" == "help" ]; then display_help "modes" exit 0 fi # # main _loop_ :) # case "$ACTION" in # concenate some avis together and rebuild the index c | cat | catenate ) cat "$INPUT" | $MENCODER -o $OUTPUT `menc_add_info` `menc_add_scaling` -ovc copy -oac copy -noidx - ;; 1 | g | good ) $MENCODER "`menc_input`" -o $OUTPUT $TBEGIN $TEND `menc_vf scale_denoise` `menc_lavc good` `menc_add_info` ;; 2 | 2pass ) $MENCODER "`menc_input`" -o /dev/null -passlogfile ${OUTPUT%.*}.log \ $TBEGIN $TEND `menc_vf scale_denoise` \ `menc_lavc pass1` && \ $MENCODER "`menc_input`" -o $OUTPUT -passlogfile ${OUTPUT%.*}.log \ $TBEGIN $TEND `menc_vf scale_denoise` `menc_lavc pass2` `menc_add_info` && \ rm -fr ${OUTPUT%.*}.log ;; q2 | quick2pass | q2pass ) # 1st pass $MENCODER "`menc_input`" -o /dev/null -passlogfile ${OUTPUT%.*}.log \ $TBEGIN $TEND `menc_lavc qpass1` `menc_vf scale` && \ $MENCODER "`menc_input`" -o $OUTPUT -passlogfile ${OUTPUT%.*}.log \ $TBEGIN $TEND `menc_lavc qpass2` `menc_vf scale` `menc_add_info` && \ rm -fr ${OUTPUT%.*}.log ;; # quick and dirty mode, almost for sure no great result q | quick ) $MENCODER "`menc_input`" -o $OUTPUT \ $TBEGIN $TEND `menc_lavc quick` `menc_vf scale` `menc_add_info` ;; d | dummy ) $MENCODER "`menc_input`" -o $OUTPUT \ $TBEGIN $TEND `menc_lavc dummy` `menc_vf_settings scale` `menc_add_info` ;; repair ) $MENCODER "`menc_input`" -ovc copy -oac copy -o $OUTPUT -forceidx ;; addinfo ) $MENCODER "$INPUT" -o $OUTPUT -ovc copy -oac copy `menc_add_info` ;; identify ) mplay_identify "$INPUT" ;; mpeg2 ) $MPLAYER -vo yuv4mpeg -ao pcm "$INPUT" || exit 1 if [ -f stream.yuv ];then yuvscaler -M WIDE2STD -O DVD > tmp.$$ < stream.yuv || exit 1 mpeg2enc -f 9 -o "$OUTPUT" tmp.$$ || exit 1 rm tmp.$$ fi ;; * ) echo "[$MODE] is an unknown mode" exit 1 ;; esac