#!/bin/sh ## Copyright (C) 2004- Commonwealth Scientific and Industrial Research ## Organisation (CSIRO) Australia ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## ## - Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## ## - Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## - Neither the name of CSIRO Australia nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ## PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ## NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS="m2anx" THEORAENC='$HOME/src/xiph.org/theora/examples/encoder_example' VERBOSE="" DRYRUN="" CMMLIN="" video_codec="theora" audio_codec="vorbis" skip_anx="" AOPTS="" afopts="" VOPTS="" vfopts="" fps="" version () { echo >&2 "$THIS version "1 exit 1 } usage () { echo >&2 "$THIS, transcode media to Annodex format, using mplayer" echo >&2 echo >&2 "Usage: $THIS [options] input" echo >&2 echo >&2 "General options" echo >&2 " -n, --dry-run Don't actually run any commands; just print them." echo >&2 " -o, --output Specify output filename" echo >&2 echo >&2 "Audio options" echo >&2 " -A, --audio-codec codec Specify audio codec (null, speex, vorbis)" echo >&2 " (default: $audio_codec)" echo >&2 " -c, --channels channels Mix to given number of channels" echo >&2 " -r, --resample rate Resample audio to given rate" echo >&2 echo >&2 "Video options" echo >&2 " -V, --video-codec codec Specify video codec (null, theora)" echo >&2 " (default: $video_codec)" echo >&2 " -d, --decimate Drop frames that don't differ greatly from the" echo >&2 " previous frame" echo >&2 " -f, --fps framerate Re-encode to new framerate" echo >&2 " -x, --xy Scale video width" echo >&2 echo >&2 "Annodex options" echo >&2 " -C, --cmml filename Use given CMML input file" echo >&2 " -S, --skip-annodexing Skip annodexing step, output to Ogg" echo >&2 echo >&2 "Miscellaneous options" echo >&2 " -h, --help Display this help and exit" echo >&2 " -v, --verbose Print informative messages" echo >&2 " --version Output version information and exit" echo >&2 exit 1 } ############################################################ ## General functions ############################################################ verbose_echo () { if test "x$VERBOSE" != "x"; then echo $* fi } check_options () { case $video_codec in null|theora) # OK ;; *) echo "$THIS: Unknown video codec $video_codec" exit 1 ;; esac case $audio_codec in null|speex|vorbis) # OK ;; *) echo "$THIS: Unknown audio codec $audio_codec" exit 1 ;; esac } # # try_run desc cmd # try_run () { desc=$1 shift verbose_echo ========================================================================== verbose_echo $desc ... if test "x$DRYRUN" != "x" || test "x$VERBOSE" != "x"; then echo $* fi if test "x$DRYRUN" = "x" ; then eval $* if test "$?" != "0"; then echo "$THIS: Failed command:" echo $* exit 1 fi fi } if_audio () { if test "x$audio_codec" != "xnull" ; then eval $* fi } if_video () { if test "x$video_codec" != "xnull" ; then eval $* fi } if_fps () { if test "x$fps" != "x" ; then eval $* fi } append_afopt () { if test "x$afopts" = "x" ; then afopts=$1 else afopts="$afopts,$1" fi } append_vfopt () { if test "x$vfopts" = "x" ; then vfopts=$1 else vfopts="$vfopts,$1" fi } ############################################################ ## Initialize for clean up ############################################################ # exit status stat=1 cleanup () { try_run "Removing fifos" rm -f $AUDIO $VIDEO try_run "Removing temporary working directory" rm -rf $WORKDIR exit $stat } trap cleanup 0 trap 'echo $THIS: Interrupted, cleaning up ...' INT QUIT KILL ############################################################ ## BEGIN: Parse options ############################################################ GETOPTEST=`getopt --version` SHORTOPTS="no:hvA:r:c:V:df:x:C:S" case $GETOPTEST in getopt*) # GNU getopt TEMP=`getopt -l dry-run -l output:: -l verbose -l version -l help -l audio-codec:: -l resample:: -l channels:: -l video-codec:: -l decimate -l fps:: -l xy:: -l cmml:: -l skip-annodexing -- +$SHORTOPTS $@` ;; *) # POSIX getopt ? TEMP=`getopt $SHORTOPTS $@` ;; esac if test "$?" != "0"; then usage fi eval set -- "$TEMP" while test "X$1" != "X--"; do case "$1" in -n|--dry-run) DRYRUN="y" ;; -v|verbose) VERBOSE="y" ;; --version) version ;; -h|--help) usage ;; -A|--audio-codec) shift audio_codec=$1 ;; -c|--channels) shift append_afopt "channels=$1" ;; -r|--resample) shift append_afopt "resample=$1" ;; -V|--video-codec) shift video_codec=$1 ;; -d|--decimate) append_vfopt decimate ;; -f|--fps) shift fps=$1 ;; -x|--xy) shift #VOPTS="$VOPTS -zoom -vf scale -xy $1" VOPTS="$VOPTS -zoom -xy $1" append_vfopt scale ;; -S|--skip-annodexing) skip_anx="yes" ;; -C|--cmml) shift CMMLIN=$1 ;; esac shift done # Check that all options parsed ok if test "x$1" != "x--"; then usage fi shift #get rid of the '--' if test "x$1" = "x"; then usage fi check_options ############################################################ ## Setup ############################################################ BASE=`basename $1|sed -e "s/\\.[^.]*$//"` INPUT=$PWD/$1 OUTDIR=`dirname $1|sed -e "s#\(^[^/]\)#$PWD\/\1#"` if test "x$CMMLIN" = "x" ; then CMMLIN=`dirname $1`/$BASE.cmml fi WORKDIR="${TMPDIR-/tmp}/$BASE.$$" REENC="$WORKDIR/$BASE-$fps.avi" AUDIO="$WORKDIR/audiodump.wav" VIDEO="$WORKDIR/stream.yuv" if test "x$skip_anx" = "xyes" ; then OGGOUT=$OUTDIR/$BASE.ogg SPXOUT=$OUTDIR/$BASE.spx else OGGOUT=$WORKDIR/$BASE.ogg SPXOUT=$WORKDIR/$BASE.spx fi ANXOUT=$OUTDIR/$BASE.anx # turn audio filter options into a -af argument if test "x$afopts" != "x" ; then AOPTS="-af $afopts $AOPTS" fi # turn video filter options into a -vf argument if test "x$vfopts" != "x" ; then VOPTS="-vf $vfopts $VOPTS" fi if test "x$VERBOSE" != "x"; then echo "Input: $INPUT" echo "Output: $OGGOUT" echo "Audio: $audio_codec" if test "x$audio_codec" != "xnull" ; then echo " $AUDIO" echo " mplayer decode options: $AOPTS" fi echo "Video: $video_codec" if test "x$video_codec" != "xnull" ; then echo " $VIDEO" echo " mplayer decode options: $VOPTS" fi echo fi if test "x$audio_codec" = "xnull" && test "x$video_codec" = "xnull" ; then echo "$THIS: Nothing to do, exiting ..." exit 1 fi try_run "Creating temporary working directory" mkdir $WORKDIR if_audio "try_run \"Making audio fifo\" mkfifo $AUDIO" if_fps "try_run \"Making FPS re-encoding fifo\" mkfifo $REENC" if_video "try_run \"Making video fifo\" mkfifo $VIDEO" ############################################################ ## Decode ############################################################ # Video if test "x$video_codec" != "xnull" ; then VIDEO_INPUT=$INPUT if test "x$fps" != "x" ; then VIDEO_INPUT=$REENC try_run "Re-encoding to $fps fps" \ "mencoder -oac copy -ovc lavc -ofps $fps -o $REENC $INPUT" & fi try_run "Decoding video" \ "(cd $WORKDIR && mplayer -ao null $VOPTS -vo yuv4mpeg $VIDEO_INPUT)" & fi # Audio if test "x$audio_codec" != "xnull" ; then try_run "Decoding audio" \ "mplayer -format 128 $AOPTS -ao pcm -aofile $AUDIO -vc dummy -vo null $INPUT" & fi ############################################################ ## Encode ############################################################ # theora + vorbis if test "x$audio_codec" = "xvorbis" && test "x$video_codec" = "xtheora" ; then try_run "Encoding theora+vorbis" \ "$THEORAENC -o $OGGOUT $AUDIO $VIDEO" # theora only elif test "x$video_codec" = "xtheora" ; then try_run "Encoding theora" \ "$THEORAENC -o $OGGOUT $VIDEO" fi # speex only if test "x$audio_codec" = "xspeex" ; then try_run "Encoding speex" \ "speexenc $AUDIO $SPXOUT" # vorbis only elif test "x$audio_codec" = "xvorbis" && test "x$video_codec" = "xnull" ; then try_run "Encoding vorbis" \ "oggenc $AUDIO -o $OGGOUT" fi wait # dude! ############################################################ ## Annodex ############################################################ do_annodex () { anx_inputs="" if test -e $CMMLIN ; then if try_run "Validating CMML" cmml-validate $CMMLIN ; then anx_inputs="$anx_inputs -t text/x-cmml $CMMLIN" else verbose_echo "Ignoring invalid CMML file $CMMLIN" fi fi case $audio_codec in speex) anx_inputs="$anx_inputs -t audio/x-speex $SPXOUT" if test "x$video_codec" = "xtheora" ; then anx_inputs="$anx_inputs -t video/x-theora $OGGOUT" fi ;; vorbis) if test "x$video_codec" = "xtheora" ; then anx_inputs="$anx_inputs -t application/ogg $OGGOUT" else anx_inputs="$anx_inputs -t audio/x-vorbis $OGGOUT" fi ;; null) if test "x$video_codec" = "xtheora" ; then anx_inputs="$anx_inputs -t video/x-theora $OGGOUT" fi esac try_run "Annodexing" \ "anxenc $anx_inputs -o $ANXOUT" verbose_echo "Wrote $ANXOUT" } if test "x$skip_anx" = "x" ; then do_annodex; fi # Set exit status to 0 stat=0