Eventually I get into producing something I think is useful for others. You'll find random technical knowledge in this Blog so please be patient and use the search function. Some of these software are rather lame and old, the list is ordered by the approximate age (newest first). Unfortunately my older stuff are lost or scattered around my old CDs, not readable anymore 8(.
An XSLT that converts VYM mindmaps to the Freemind format.
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- by Erno Rigo [mcree_AT_tricon_DOT_hu], 2006-11-14 --> <xsl:template match="/"> <xsl:apply-templates select="/vymmap/mapcenter" /> </xsl:template> <xsl:template match="/vymmap/mapcenter"> <map version="0.8.0"> <node ID="_" TEXT="map imported from VYM"> <xsl:apply-templates select="branch" /> </node> </map> </xsl:template> <xsl:template match="branch"> <node CREATED="0" MODIFIED="0"> <xsl:attribute name="TEXT"> <xsl:value-of select="heading" /> </xsl:attribute> <xsl:attribute name="COLOR"> <xsl:value-of select="heading/@textColor" /> </xsl:attribute> <xsl:if test="@url != ''"> <xsl:attribute name="LINK"> <xsl:value-of select="@url" /> </xsl:attribute> </xsl:if> <xsl:attribute name="ID">VYM_<xsl:value-of select="@x1" />_<xsl:value-of select="@y1" /></xsl:attribute> <xsl:apply-templates select="standardflag" /> <xsl:apply-templates select="branch" /> </node> </xsl:template> <xsl:template match="standardflag"> <xsl:choose> <xsl:when test=". = 'lifebelt'"><icon BUILTIN="flag"/></xsl:when> <xsl:when test=". = 'flash'"><icon BUILTIN="clanbomber"/></xsl:when> <xsl:when test=". = 'heart'"><icon BUILTIN="bookmark"/></xsl:when> <xsl:when test=". = 'thumb-down'"><icon BUILTIN="button_cancel"/></xsl:when> <xsl:when test=". = 'thumb-up'"><icon BUILTIN="button_ok"/></xsl:when> <xsl:when test=". = 'arrow-down'"><icon BUILTIN="full-7"/></xsl:when> <xsl:when test=". = 'arrow-up'"><icon BUILTIN="full-1"/></xsl:when> <xsl:when test=". = 'lamp'"><icon BUILTIN="idea"/></xsl:when> <xsl:when test=". = 'clock'"><icon BUILTIN="bell"/></xsl:when> <xsl:when test=". = 'smiley-sad'"><icon BUILTIN="button_cancel"/></xsl:when> <xsl:when test=". = 'smiley-good'"><icon BUILTIN="ksmiletris"/></xsl:when> <xsl:when test=". = 'stopsign'"><icon BUILTIN="stop"/></xsl:when> <xsl:when test=". = 'cross-red'"><icon BUILTIN="button_cancel"/></xsl:when> <xsl:when test=". = 'hook-green'"><icon BUILTIN="button_ok"/></xsl:when> <xsl:when test=". = 'questionmark'"><icon BUILTIN="help"/></xsl:when> <xsl:when test=". = 'exclamationmark'"><icon BUILTIN="messagebox_warning"/></xsl:when> </xsl:choose> </xsl:template> </xsl:transform>
This is a recode and enhancement of my first vob2avi shell script. Pretty much does the same.
#!/bin/bash function init() { if [ "$INIT_DONE" ]; then echo "+ init: done already" >&2; return; fi key="$IN $OPTS" echo "::: init: initializing with key '$key'" >&2 ; # hash=`echo "$key" | md5sum | cut -f1 -d' '` hash=`echo "OPTS $OPTS" | sed 's/[^[:alnum:]]/_/g' ` echo "+ init: hash is '$hash'" >&2 ; basedir=`dirname "$IN"` basename=`basename "$IN"` export TMPDIR="$basedir/$basename.$hash.vob2avi" echo "+ init: TMPDIR is '$TMPDIR'" >&2 ; mkdir -p "$TMPDIR" INIT_DONE="yes" echo "+ init: done" >&2 ; } function setupaudio() { if [ "$DUMMYMODE" ]; then whiptail --title "ERROR" --msgbox "audio setup can not be done in DUMMY MODE!" 7 75 ; return fi init demux echo "::: setupaudio: setting up audio track configuration for '$IN'" >&2 ; pushd "$TMPDIR" > /dev/null find "." | egrep "audio_0x[a-f0-9]+.vob" | while read track; do track=`basename $track` while true; do tagfile=`mktemp` if \ whiptail --title "choose action for track $track" --menu "" 24 75 17\ listen "Listen to this track" \ remove "Do not include this track in final avi" \ include "Include this track in final avi" \ first "Make this the first audio track" \ 2>$tagfile then \ tag=`cat $tagfile` rm -f $tagfile echo "+ setupaudio: user voted for menu item $tag with $track" >&2 ; case "$tag" in listen) kaffeine $track ;; remove) newaids=`cat aids | grep -v $track` echo -e "$newaids" > aids break ;; include) echo $track >> aids break ;; first) newaids=`cat aids | grep -v $track` echo $track > aids echo -e "$newaids" >> aids break ;; esac else rm -f $tagfile break; fi done done popd >/dev/null } function demux() { if [ "$DUMMYMODE" ]; then whiptail --title "ERROR" --msgbox "demuxing can not be done in DUMMY MODE!" 7 75 ; return fi init if [ -f "$TMPDIR/demux_done" ]; then echo "+ demux: done already" >&2 ; return fi echo "::: demux: demultiplexing '$IN'" >&2 ; info=`info` videoids=`echo -e "$info" | egrep "^ID_VIDEO_ID=" | sort | uniq | cut -f2 -d"="` audioids=`echo -e "$info" | egrep "^ID_AUDIO_ID=" | sort | uniq | cut -f2 -d"="` subtitleids=`echo -e "$info" | egrep "^ID_SUBTITLE_ID=" | sort | uniq | cut -f2 -d"="` #echo -e "$info";return pushd "$TMPDIR" > /dev/null flagfile="demux_lock" rm -f "$flagfile" fifos="" for id in $videoids; do id=`printf "0x%02x" $(($id + 224))` echo "+ demux: found video ID#$id" >&2 ; fifo="video_$id.fifo" mkfifo "$fifo" fifos="$fifos $fifo" ( #wait for flagfile while [ ! -f "$flagfile" ]; do sleep 1; done ; tcdemux -i "$fifo" -A $id > "video_$id.vob" ) & done for id in $audioids; do id=`printf "0x%02x" $id` echo "+ demux: found audio ID#$id" >&2 ; fifo="audio_$id.fifo" mkfifo "$fifo" fifos="$fifos $fifo" ( #wait for flagfile while [ ! -f "$flagfile" ]; do sleep 1; done ; tcdemux -i "$fifo" -A $id > "audio_$id.vob" ) & done for id in $subtitleids; do id=`printf "0x%02x" $(($id + 32))` echo "+ demux: found subtitle ID#$id" >&2 ; fifo="subtitle_$id.fifo" mkfifo "$fifo" fifos="$fifos $fifo" ( #wait for flagfile while [ ! -f "$flagfile" ]; do sleep 1; done ; tcdemux -i "$fifo" -A $id > "subtitle_$id.vob" ) & done touch "$flagfile" pv -N "demuxing" "$IN" | tee $fifos >/dev/null rm -f "$flagfile" rm -f $fifos popd > /dev/null touch "$TMPDIR/demux_done" echo "+ demux: done" >&2 ; exit 0 } function info() { if [ "$DUMMYMODE" ]; then echo "ERROR: info called in DUMMY MODE" >&2 exit -1 fi init if [ -f "$TMPDIR/info" ]; then echo "+ info: done already" >&2 cat "$TMPDIR/info" return fi echo "::: info: initializing" >&2 echo "+ info: identifying $IN with mplayer" >&2 res=`mplayer -ao null -vo null -frames 1 -identify "$IN" 2>&1` echo "+ info: identifying $IN with tcprobe" >&2 res="$res"`tcprobe -H 100 -i "$IN" 2>&1` echo "+ info: saving info" >&2 echo -e "$res" > "$TMPDIR/info" echo "+ info: done" >&2 } function testencode() { echo "::: test-encoding '$1'" >&2 ; vob="$1" #-ss 10:00 ripaudio "$vob" "-frames 2500" encode "$vob" "-frames 2500" audiomerge "$vob" mplayer -vo xv -fs "$vob.avi" } function ripaudio() { echo "::: ripping audio from '$1'" >&2 ; vob="$1" opts="$2" info "$vob" | grep "ID_AUDIO_ID" | cut -f2 -d"=" > "${vob}.aids" cat "${vob}.aids" | while read aid; do mencoder "$vob" $opts -oac copy -aid $aid -ovc frameno -o "${vob}_audio_${aid}.avi" done } function audiomerge() { echo "::: encoding '$1'" >&2 ; vob="$1" aids=`cat "${vob}.aids"` cp -f "${vob}.avi" "${vob}_merged.avi" for aid in $aids; do track=0 if [ -f "${vob}_audio_${aid}.avi" ]; then echo "::: merging lang ${vob}_audio_${aid}.avi as track $track" >&2 ; aviindex -i "${vob}_audio_${aid}.avi" -f -o "${vob}_merged.avi.idx" avimerge -i "${vob}_merged.avi" -o "${vob}.avi.tmp" -p "${vob}_audio_${aid}.avi" -A $aid -x "${vob}_merged.avi.idx" mv -f "${vob}.avi.tmp" "${vob}_merged.avi" track=$(($track + 1)) rm -f "${vob}_merged.avi.idx" fi done } function encode() { echo "::: encoding '$1'" >&2 ; # unlink frameno.avi 2> /dev/null vob="$1" opts="$2" crop=`cropdetect "$vob"` scale=`scaledetect "$vob"` vfopts=pp=de,crop=$crop,scale=$scale lavcopts=vcodec=mpeg4:vhq:vqmin=2:vbitrate=2000 # mencoder "$vob" $opts -oac copy -alang English -ovc frameno -o "${vob}_audio_en.avi" # mencoder "$vob" $opts -oac copy -alang Hungarian -ovc frameno -o "${vob}_audio_hu.avi" mencoder "$vob" $opts -oac copy -ovc lavc -lavcopts $lavcopts:vpass=1 -vf $vfopts -o "/dev/null" mencoder "$vob" $opts -oac copy -ovc lavc -lavcopts $lavcopts:vpass=2 -vf $vfopts -o "$vob.avi" # unlink frameno.avi 2> /dev/null unlink divx2pass.log 2> /dev/null } function scaledetect() { echo "::: scale-detecting '$1'" >&2 ; vob="$1" scalecache="$vob.scale" if [ -f "$scalecache" ]; then echo "+ reading scale data from $scalecache" >&2 scale=`cat "$scalecache"` echo "+ final scale parameters: $scale" >&2 echo "$scale" return fi info=`info "$vob"` #echo -e "$info" #exit 0 res=`echo -e "$info" | egrep "^VIDEO:" | egrep -o "[0-9]+x[0-9]+"` case "$res" in 720x576) echo "+ video has PAL resolution, this is good" >&2 aspect=`echo -e "$info" | egrep "^Movie-Aspect" | egrep -o "[0-9.]+:[0-9.]+" | tr ':' '/'` #aspect="4/3" ow="720" oh="576" ;; *) echo "+ video has $res resolution, this is BAD - UNIMPLEMENTED" >&2 exit -1 ;; esac echo "+ video has $aspect aspect with $res resolution" >&2 crop=`cropdetect "$vob"` w=`echo $crop | cut -f1 -d":"` h=`echo $crop | cut -f2 -d":"` echo "+ cropped video has resolution ${w}x${h}" >&2 # original width: nw=$ow nh=`echo "scale=4;(1/($aspect))*($ow/$oh)*($w/$ow)*$h" | bc | cut -f1 -d'.'` # cropped width: #nw=$w #nh=`echo "scale=4;(1/($aspect))*($ow/$oh)*$h" | bc | cut -f1 -d'.'` scale="${nw}:${nh}" echo "+ storing final parameters to: $scalecache" >&2 echo $scale > "$scalecache" echo "+ final scale parameters: $scale" >&2 echo $scale echo "+ scale detect done." >&2 } function cropdetect() { echo "::: crop-detecting '$1'" >&2 ; vob="$1" cropcache="$vob.crop" if [ -f "$cropcache" ]; then echo "+ reading crop data from $cropcache" >&2 bestcrop=`cat "$cropcache"` echo "+ final parameters: $bestcrop" >&2 echo $bestcrop return fi # info "$vob" # exit 0 echo "+ crop detecting movie with mplayer..." >&2 crops=`mktemp` for x in 2 5 10 20 30 50 100; do mplayer -vo null -ao null -frames 5 -ss $x:00 -vf cropdetect "$vob" 2>/dev/null | grep "\[CROP\]" | egrep -o "[0-9]+:[0-9]+:[0-9]+:[0-9]+" done > $crops cropss=`mktemp` cat $crops | while read crop; do x=`echo $crop | cut -f3 -d":"` y=`echo $crop | cut -f4 -d":"` xl=`echo $crop | cut -f1 -d":"` yl=`echo $crop | cut -f2 -d":"` echo $(( xl*yl)) $crop done > $cropss rm -f $crops bestcrop=`cat $cropss | sort -n | tail -n1 | cut -f2 -d' '` rm -f $cropss echo "+ best crop guessed by mplayer: $bestcrop" >&2 inputconf=`mktemp` echo "W change_rectangle 0 1" >> $inputconf echo "w change_rectangle 0 -1" >> $inputconf echo "E change_rectangle 1 1" >> $inputconf echo "e change_rectangle 1 -1" >> $inputconf echo "S change_rectangle 2 1" >> $inputconf echo "s change_rectangle 2 -1" >> $inputconf echo "D change_rectangle 3 1" >> $inputconf echo "d change_rectangle 3 -1" >> $inputconf cropfile=`mktemp` echo "+ fine tuning with mplayer... (use keys: wWeEsSdD)" >&2 mplayer "$vob" -input conf=$inputconf -vf rectangle=$bestcrop 2>/dev/null | egrep -o "[0-9]+:[0-9]+:[0-9]+:[0-9]+" > $cropfile rm -f $inputconf bestcrop=`tail -n1 $cropfile` rm -f $cropfile echo "+ storing final parameters to: $cropcache" >&2 echo $bestcrop > "$cropcache" echo "+ final crop parameters: $bestcrop" >&2 echo $bestcrop echo "+ crop detect done." >&2 } #encode dvd.DVD_VIDEO.1216721459.01.vob 720:430:0:72 720:405 BANNER=`basename $0`" - GPLv3 - (c) 2008 by Erno Rigo <mcree_AT_tricon_DOT_hu>" # try to get to our input file if [ -z "$1" ]; then searchpath=`pwd` else if [ -d "$1" ]; then searchpath="$1" else IN="$1" fi fi if [ ! -z "$searchpath" ]; then echo "::: searching for INPUT candidates in $searchpath... " >&2 files=`find "$searchpath" -type f | egrep ".*[.](vob|mpeg|VOB|MPEG|Vob|Mpeg|mpg|MPG)$" 2>/dev/null` opts=`echo -e "$files" | while read file; do echo "$file" "."; done` menutag=`mktemp` if \ whiptail --noitem --backtitle "$BANNER" --title "select INPUT file" \ --menu "" 24 75 17 -- \ "[Dummy mode]" "dummy"\ $opts \ 2>"$menutag";\ then echo "::: selected tag: "`cat "$menutag"` >&2 IN=`cat "$menutag"` rm -f "$menutag" else echo "::: exiting on user request" >&2 rm -f "$menutag" exit 0; fi fi if [ ! -f "$IN" ]; then IN="Dummy mode!" DUMMYMODE="yes" else # calculate absolute path for IN pushd `dirname "$IN"` > /dev/null IN=`cd -`"/"`basename "$IN"` popd > /dev/null fi OPTS="$2" if [ ! -z "$3" ]; then $3 exit 0 fi # MAIN MENU LOOP while true; do menutag=`mktemp` echo "::: entering main menu" >&2 if \ whiptail --backtitle "IN: '$IN'" --title "main menu" \ --menu "OPTS: '$OPTS'" 24 75 16 -- \ "demux" "- Demultiplex INPUT" \ "setupaudio" "- Setup audio tracks to be included in OUTPUT" \ 2>"$menutag"; \ then tag=`cat "$menutag"` rm -f "$menutag" echo "::: selected tag: $tag" >&2 $tag else echo "::: exiting on user request" >&2 rm -f "$menutag" exit 0; fi done # END MAIN MENU LOOP exit 0 opts=`cat<<EOF in:#specify input file (typically vob or mpeg) encode:#specify action cropdetect:#try to detect crop parameters scaledetect:#try to detect scale parameters prepare:#setup and preview encoding ripaudio:#rip audio tracks audiomerge:#merge audio tracks demux:#demultiplex input EOF ` # prepare long opts for getopt optsf=`mktemp` echo -e "$opts" | while read opt; do echo -ne ","`echo "$opt" | cut -f1 -d'#'` done | cut -b 2- > $optsf longopts=`cat $optsf` rm -f $optsf TEMP=`getopt -o "" --long $longopts -n "$0" -- "$@"` if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" while true ; do case "$1" in --encode) echo "Option encode, argument $2" ; shift 2 ;; --cropdetect) cropdetect "$2" ; shift 2 ;; --scaledetect) scaledetect "$2" ; shift 2 ;; --prepare) testencode "$2" ; shift 2 ;; --ripaudio) ripaudio "$2" ; shift 2 ;; --audiomerge) audiomerge "$2" ; shift 2 ;; --demux) demux "$2" ; shift 2 ;; --) shift ; break ;; *) echo "Internal error!" ; exit 1 ;; esac done #echo "Remaining arguments:" #for arg do echo '--> '"\`$arg'" ; done
This is a quite complex bash shell script to recode DVD VOB files to AVI using MEncoder, Avidemux and other tools. Automates crop detection, aspect ratio calc, dual audio muxing and subtitle ripping. I'm not saying this is all perfect of course…
#!/bin/bash function gethash() { key="$IN $OPTS" echo "::: gethash: initializing with key '$key'" >&2 ; #ugly: hash=`echo "$key" | md5sum | cut -f1 -d' '` hash=`echo "OPTS $OPTS" | sed 's/[^[:alnum:]]/_/g' ` echo "$hash" } function init() { if [ "$INIT_DONE" ]; then echo "+ init: done already" >&2; return; fi echo "::: init: initializing" >&2 ; hash=`gethash` echo "+ init: hash is '$hash'" >&2 ; basedir=`dirname "$IN"` basename=`basename "$IN"` export TMPDIR="$basedir/$basename.$hash.vob2avi" echo "+ init: TMPDIR is '$TMPDIR'" >&2 ; mkdir -p "$TMPDIR" if [ ! -d "$TMPDIR" ]; then echo "FATAL: cannot create directory: $TMPDIR" >&2 ; exit -1 fi INIT_DONE="yes" echo "+ init: done" >&2 ; } function setupaudio() { if [ "$DUMMYMODE" ]; then whiptail --title "ERROR" --msgbox "audio setup can not be done in DUMMY MODE!" 7 75 ; return fi init demux echo "::: setupaudio: setting up audio track configuration for '$IN'" >&2 ; pushd "$TMPDIR" > /dev/null if [ -f aids ]; then echo "+ setupaudio: done already" >&2; return; fi touch aids tracks=`find "." | egrep "audio_[0-9]+.ac3" | sort -n` for track in $tracks; do track=`basename $track` echo "+ querying user for $track" >&2 while true; do tagfile=`mktemp` if whiptail --title "choose action for track $track" --menu "" 24 75 17\ listen "Listen to this track" \ remove "Do not include this track in final avi" \ include "Include this track in final avi" \ first "Make this the first audio track" \ 2>"$tagfile" then tag=`cat "$tagfile"` rm -f "$tagfile" echo "+ setupaudio: user voted for menu item $tag with $track" >&2 ; case "$tag" in listen) echo "+ playing $track" >&2 #kaffeine "$track" #mplayer -audiofile "$track" "$IN" vlc "$track" ;; remove) echo "+ removing $track" >&2 newaids=`cat aids | grep -v $track` echo -e "$newaids" > aids break; ;; include) echo "+ including $track" >&2 echo $track >> aids echo "+ included $track" >&2 break; ;; first) echo "+ including $track as first" >&2 newaids=`cat aids | grep -v $track` echo $track > aids echo -e "$newaids" >> aids break; ;; esac else rm -f $tagfile break; fi done done popd >/dev/null } function demux() { if [ "$DUMMYMODE" ]; then whiptail --title "ERROR" --msgbox "demuxing can not be done in DUMMY MODE!" 7 75 ; return fi init if [ -f "$TMPDIR/demux_done" ]; then echo "+ demux: done already" >&2 ; return fi echo "::: demux: demultiplexing '$IN'" >&2 ; info=`info` videoids=`echo -e "$info" | egrep "^ID_VIDEO_ID=" | sort | uniq | cut -f2 -d"="` audioids=`echo -e "$info" | egrep "^ID_AUDIO_ID=" | sort | uniq | cut -f2 -d"="` #mplayer is unreliable: subtitleids=`echo -e "$info" | egrep "^ID_SUBTITLE_ID=" | sort | uniq | cut -f2 -d"="` maxsubtitleid=`echo -e "$info" | egrep "^detected \([0-9]+\) subtitle" | egrep -o "[0-9]+"` subtitleids=`seq 0 $(($maxsubtitleid - 1))` # debug #echo -e "$videoids" #echo -e "$audioids" #echo -e "$subtitleids" #echo -e "$info"; #return # /debug pushd "$TMPDIR" > /dev/null flagfile="demux_lock" rm -f "$flagfile" fifos="" #for id in $videoids; do # id=`printf "0x%02x" $(($id + 224))` # echo "+ demux: found video ID#$id" >&2 ; # fifo="video_$id.fifo" # mkfifo "$fifo" # fifos="$fifos $fifo" # ( # #wait for flagfile # while [ ! -f "$flagfile" ]; do sleep 1; done ; # tcdemux -i "$fifo" -A $id > "video_$id.vob" # ) & #done for id in $audioids; do #id=`printf "0x%02x" $id` id=`printf "%d" $(($id - 128))` echo "+ demux: found audio ID#$id" >&2 ; #cat "$fifo" | mplayer -quiet -vo null -ao null -aid $id -dumpaudio -dumpfile "audio_$id.ac3" - #tcextract -i "$IN" -x ac3 -a $id > "audio_$id.ac3" #mplayer -vo null -ao null -aid $id -dumpaudio -dumpfile "audio_$id.ac3" "$IN" #continue fifo="audio_$id.fifo" mkfifo "$fifo" fifos="$fifos $fifo" ( #wait for flagfile while [ ! -f "$flagfile" ]; do sleep 1; done ; #tcdemux -i "$fifo" -A $id > "audio_$id.vob" #mencoder "$fifo" -quiet -oac copy -aid $id -ovc frameno -o "$TMPDIR/audio_${id}.avi" #cat "$fifo" | tcextract -x ac3 -a $id > "audio_$id.ac3" cat "$fifo" | tcextract -t vob -x ac3 -a $id > "audio_$id.ac3" #cat "$fifo" | mplayer -quiet -vo null -ao null -aid $id -dumpaudio -dumpfile "audio_$id.ac3" - ) & done #return for id in $subtitleids; do id=`printf "0x%02x" $(($id + 32))` echo "+ demux: found subtitle ID#$id" >&2 ; #tcextract -i "$IN" -x ps1 -a $id > "subtitle_$id.ps1" #continue fifo="subtitle_$id.fifo" mkfifo "$fifo" fifos="$fifos $fifo" ( #wait for flagfile while [ ! -f "$flagfile" ]; do sleep 1; done ; #tcdemux -i "$fifo" -A $id > "subtitle_$id.vob" cat "$fifo" | tcextract -t vob -x ps1 -a $id > "subtitle_$id.ps1" ) & done touch "$flagfile" pv -N "demuxing" "$IN" | tee $fifos >/dev/null rm -f "$flagfile" rm -f $fifos popd > /dev/null touch "$TMPDIR/demux_done" echo "+ demux: done" >&2 ; } function doall() { allcmd encode } function encodeall() { allcmd encode } function allcmd() { cmd="$1" echo "::: executing command $cmd for all in "`pwd` >&2 ; find -type f\ | egrep -i '[.](vob|mpeg|mpg)$'\ | xargs -I"FILE" -n1 vob2avi.sh FILE "$OPTS" $cmd } function demuxall() { allcmd "demux" } function prepareall() { allcmd "prepare" } function info() { if [ "$DUMMYMODE" ]; then echo "ERROR: info called in DUMMY MODE" >&2 exit -1 fi init if [ -f "$TMPDIR/info" ]; then echo "+ info: done already" >&2 cat "$TMPDIR/info" return fi echo "::: info: initializing" >&2 echo "+ info: identifying $IN with mplayer" >&2 res=`mplayer -ao null -vo null -frames 500 -identify "$IN"` echo "+ info: identifying $IN with tcprobe" >&2 res="$res"`tcprobe -H 500 -i "$IN"` echo "+ info: saving info" >&2 echo -e "$res" > "$TMPDIR/info" echo "+ info: done" >&2 cat "$TMPDIR/info" } function prepare() { init if [ -f "$TMPDIR/prepared" ]; then echo "+ prepare: done already" >&2 return fi if [ "$DUMMYMODE" ]; then echo "ERROR: prepare called in DUMMY MODE" >&2 exit -1 fi echo "::: preparing '$IN'" >&2 ; demux setupaudio encode_real "-frames 500" audiomerge mplayer -vo xv -fs "$IN.avi" echo "prepared" > "$TMPDIR/prepared" } function encode() { init if [ -f "$TMPDIR/done" ]; then echo "+ encode: done already" >&2 return fi if [ "$DUMMYMODE" ]; then echo "ERROR: encode called in DUMMY MODE" >&2 exit -1 fi echo "::: encoding '$IN'" >&2 ; encode_real audiomerge echo "done" > "$TMPDIR/done" echo "::: DONE encoding '$IN'" >&2 ; } function audiosync() { echo "::: syncing audio for '$IN'" >&2 ; init setupaudio if [ -f "$TMPDIR/synced" ]; then echo "+ audiosync: done already" >&2 return fi aids=`cat "$TMPDIR/aids" | xargs -I"##" -n1 basename "##" .ac3 | cut -f2 -d"_" ` naids=`echo -e "$aids" | wc -l` info=`info` for x in `seq 0 $(($naids -1))`; do newaid=`echo $x` frametime=`echo -e "$info" | egrep -o 'frame_time=[+-]?[0-9]+' | cut -f2 -d'='` oldaid=`echo -e "$aids" | tail -n $(($naids - $x)) | head -n1` echo "+ oldaid:$oldaid newaid:$newaid" >&2 syncms=`echo -e "$info" | grep "audio track.*-a $oldaid" -A2 | egrep -o 'av_fine_ms [+-]?[0-9]+' | cut -f2 -d' '` syncfr=`echo -e "$info" | grep "audio track.*-a $oldaid" -A2 | egrep -o '\-D [+-]?[0-9]+' | cut -f2 -d' ' | tr -d " \t\n\r"` echo "+ syncfr: $syncfr" >&2 #sign=$(($syncfr < 0)) if [ $(( 1 + $syncfr )) -lt 1 ]; then sign="1" else sign="0" fi sync=`echo "scale=2 ; (($syncms ^ 2 / $frametime ^ 2)+0.5 >= 1) * (-1 * $sign) + $syncfr" | bc` echo "+ oldaid:$oldaid newaid:$newaid sync:$sync ($syncfr frames + $syncms ms [frametime:$frametime])" >&2 if [ ! "$sync" -eq "0" ]; then echo "+ track needs syncing. Doing it as $TMPDIR/synced.avi" >&2 avisync -i "$IN.avi" -o "$TMPDIR/synced.avi" -n $sync -a $newaid mv -f "$TMPDIR/synced.avi" "$IN.avi" fi done echo "done" > "$TMPDIR/synced" #echo -e "$aids\nn:$naids" #exit 0 } function audiomerge() { echo "::: merging audio for '$IN'" >&2 ; init vob="$IN" aids=`cat "$TMPDIR/aids"` echo "+ creating $TMPDIR/merged.avi with no sound" >&2 ; #cp -f "${vob}.avi" "$TMPDIR/merged.avi" mencoder -ovc copy -nosound "$vob.avi" -o "$TMPDIR/merged.avi" #return track=0 for aid in $aids; do if [ -f "$TMPDIR/$aid" ]; then echo "+ merging lang $TMPDIR/$aid as track $track" >&2 ; if avimerge -i "$TMPDIR/merged.avi" -o "$TMPDIR/merged_tmp.avi" -p "$TMPDIR/$aid" then mv -f "$TMPDIR/merged_tmp.avi" "$TMPDIR/merged.avi" else echo "+ ERROR merging lang $TMPDIR/$aid as track $track" >&2 ; fi track=$(($track + 1)) fi done mv -f "$TMPDIR/merged.avi" "${vob}.avi" audiosync } function encode_real() { echo "::: encoding '$IN'" >&2 ; addopts="$1" init crop=`cropdetect` scale=`scaledetect` vfopts=pp=de,crop=$crop,scale=$scale lavcopts=vcodec=mpeg4:vhq:vqmin=2:vbitrate=1800:threads=4:turbo opts="$addopts -vf-add kerndeint -oac copy -ovc lavc -vf-add $vfopts" # mencoder "$vob" $opts -oac copy -alang English -ovc frameno -o "${vob}_audio_en.avi" # mencoder "$vob" $opts -oac copy -alang Hungarian -ovc frameno -o "${vob}_audio_hu.avi" set -e pushd "$TMPDIR" > /dev/null echo "+ executing mencoder with args: $opts -lavcopts $lavcopts:vpass=1" >&2 mencoder "$IN" $opts -lavcopts $lavcopts:vpass=1 -o '/dev/null' echo "+ executing mencoder with args: $opts -lavcopts $lavcopts:vpass=2" >&2 mencoder "$IN" $opts -lavcopts $lavcopts:vpass=2 -o "$TMPDIR/final.avi" popd "$TMPDIR" set +e mv -f "$TMPDIR/final.avi" "$IN.avi" # unlink frameno.avi 2> /dev/null unlink $TMPDIR/divx2pass.log 2> /dev/null } function scaledetect() { echo "::: scale-detecting '$IN'" >&2 ; vob="$IN" init scalecache="$TMPDIR/scale" if [ -f "$scalecache" ]; then echo "+ reading scale data from $scalecache" >&2 scale=`cat "$scalecache"` echo "+ final scale parameters: $scale" >&2 echo "$scale" return fi info=`info` #echo -e "$info" #exit 0 res=`echo -e "$info" | egrep "^VIDEO:" | egrep -o "[0-9]+x[0-9]+"` case "$res" in 720x576) echo "+ video has PAL resolution, this is good" >&2 aspect=`echo -e "$info" | egrep "^Movie-Aspect" | egrep -o "[0-9.]+:[0-9.]+" | tr ':' '/'` #aspect="4/3" ow="720" oh="576" ;; *) echo "+ video has $res resolution, this is BAD - UNIMPLEMENTED" >&2 exit -1 ;; esac echo "+ video has $aspect aspect with $res resolution" >&2 crop=`cropdetect "$vob"` w=`echo $crop | cut -f1 -d":"` h=`echo $crop | cut -f2 -d":"` echo "+ cropped video has resolution ${w}x${h}" >&2 # original width: nw=$ow nh=`echo "scale=4;(1/($aspect))*($ow/$oh)*($w/$ow)*$h" | bc | cut -f1 -d'.'` # cropped width: #nw=$w #nh=`echo "scale=4;(1/($aspect))*($ow/$oh)*$h" | bc | cut -f1 -d'.'` scale="${nw}:${nh}" echo "+ storing final parameters to: $scalecache" >&2 echo $scale > "$scalecache" echo "+ final scale parameters: $scale" >&2 echo $scale echo "+ scale detect done." >&2 } function cropdetect() { echo "::: crop-detecting '$IN'" >&2 ; vob="$IN" init cropcache="$TMPDIR/crop" if [ -f "$cropcache" ]; then echo "+ reading crop data from $cropcache" >&2 bestcrop=`cat "$cropcache"` echo "+ final parameters: $bestcrop" >&2 echo $bestcrop return fi # info "$vob" # exit 0 echo "+ crop detecting movie with mplayer..." >&2 crops=`mktemp` for x in 2 5 10 20 30 50 100; do mplayer -vo null -ao null -frames 5 -ss $x:00 -vf cropdetect "$vob" 2>/dev/null | grep "\[CROP\]" | egrep -o "[0-9]+:[0-9]+:[0-9]+:[0-9]+" done > "$crops" cropss=`mktemp` cat "$crops" | while read crop; do x=`echo $crop | cut -f3 -d":"` y=`echo $crop | cut -f4 -d":"` xl=`echo $crop | cut -f1 -d":"` yl=`echo $crop | cut -f2 -d":"` echo $(( xl*yl)) $crop done > "$cropss" rm -f "$crops" bestcrop=`cat "$cropss" | sort -n | tail -n1 | cut -f2 -d' '` rm -f "$cropss" echo "+ best crop guessed by mplayer: $bestcrop" >&2 inputconf=`mktemp` echo "W change_rectangle 0 1" >> "$inputconf" echo "w change_rectangle 0 -1" >> "$inputconf" echo "E change_rectangle 1 1" >> "$inputconf" echo "e change_rectangle 1 -1" >> "$inputconf" echo "S change_rectangle 2 1" >> "$inputconf" echo "s change_rectangle 2 -1" >> "$inputconf" echo "D change_rectangle 3 1" >> "$inputconf" echo "d change_rectangle 3 -1" >> "$inputconf" cropfile=`mktemp` echo "+ fine tuning with mplayer... (use keys: wWeEsSdD)" >&2 mplayer "$vob" -input conf="$inputconf" -vf rectangle=$bestcrop 2>/dev/null | egrep -o "[0-9]+:[0-9]+:[0-9]+:[0-9]+" > "$cropfile" rm -f "$inputconf" bestcrop=`tail -n1 "$cropfile"` rm -f "$cropfile" echo "+ storing final parameters to: $cropcache" >&2 echo $bestcrop > "$cropcache" echo "+ final crop parameters: $bestcrop" >&2 echo $bestcrop echo "+ crop detect done." >&2 } #encode dvd.DVD_VIDEO.1216721459.01.vob 720:430:0:72 720:405 BANNER=`basename $0`" - GPLv3 - (c) 2008 by Erno Rigo <mcree_AT_tricon_DOT_hu>" # try to get to our input file if [ -z "$1" ]; then searchpath=`pwd` else if [ -d "$1" ]; then searchpath="$1" else IN="$1" fi fi if [ ! -z "$searchpath" ]; then echo "::: searching for INPUT candidates in $searchpath... " >&2 files=`find "$searchpath" -type f | egrep ".*[.](vob|mpeg|VOB|MPEG|Vob|Mpeg|mpg|MPG)$" 2>/dev/null` opts=`echo -e "$files" | while read file; do echo "'$file'" "'.'"; done` menutag=`mktemp` if echo whiptail --noitem --backtitle "$BANNER" --title "select INPUT file" \ --menu "" 24 75 17 -- \ "[Dummy mode]" "dummy"\ $opts \ 2>"$menutag"; then echo "::: selected tag: "`cat "$menutag"` >&2 IN=`cat "$menutag"` rm -f "$menutag" else echo "::: exiting on user request" >&2 rm -f "$menutag" exit 0; fi fi if [ ! -f "$IN" ]; then IN="Dummy mode!" DUMMYMODE="yes" else # calculate absolute path for IN wd=`dirname "$IN"` pushd "$wd" > /dev/null IN=`pwd`"/"`basename "$IN"` popd > /dev/null fi echo "WORKDIR: $wd, IN: $IN" OPTS="$2" if [ ! -z "$3" ]; then $3 exit 0 fi # MAIN MENU LOOP while true; do menutag=`mktemp` echo "::: entering main menu" >&2 if \ whiptail --backtitle "IN: '$IN'" --title "main menu" \ --menu "OPTS: '$OPTS'" 24 75 16 -- \ "demux" "- Demultiplex INPUT" \ "setupaudio" "- Setup audio tracks to be included in OUTPUT" \ 2>"$menutag"; \ then tag=`cat "$menutag"` rm -f "$menutag" echo "::: selected tag: $tag" >&2 $tag else echo "::: exiting on user request" >&2 rm -f "$menutag" exit 0; fi done # END MAIN MENU LOOP exit 0 opts=`cat<<EOF encode:#encode vob cropdetect:#try to detect crop parameters scaledetect:#try to detect scale parameters prepare:#prepare and preview encoding ripaudio:#rip audio tracks audiomerge:#rip audio tracks help#print this help deint#turn on deinterlacing [OBSOLETE - using kernel deint by default] ripsubs:#rip subtitles from the vob doall#search for prepared vobs in CWD (with the --test option) and do real encoding EOF ` # prepare long opts for getopt optsf=`mktemp` echo -e "$opts" | while read opt; do echo -ne ","`echo "$opt" | cut -f1 -d'#'` done | cut -b 2- > $optsf longopts=`cat $optsf` rm -f $optsf TEMP=`getopt -o "" --long $longopts -n "$0" -- "$@"` if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" showhelp="" iopts="" while true ; do case "$1" in --deint) iopts="-vf-add kerndeint" ; shift; ;; --encode) encode "$2" "$iopts"; shift 2 ; showhelp="false" ;; --cropdetect) cropdetect "$2" "$iopts" ; shift 2 ; showhelp="false" ;; --scaledetect) scaledetect "$2" "$iopts" ; shift 2 ; showhelp="false" ;; --prepare) testencode "$2" "$iopts"; shift 2 ; showhelp="false" ;; --ripaudio) ripaudio "$2" "$iopts" ; shift 2 ; showhelp="false" ;; --audiomerge) audiomerge "$2" "$iopts" ; shift 2 ; showhelp="false" ;; --ripsubs) ripsubs "$2" "$iopts" ; shift 2 ; showhelp="false" ;; --doall) doall; shift; showhelp="false" ;; --c-long) # c has an optional argument. As we are in quoted mode, # an empty parameter will be generated if its optional # argument is not found. case "$2" in "") echo "Option c, no argument"; shift 2 ;; *) echo "Option c, argument \`$2'" ; shift 2 ;; esac ;; --) shift ; break ;; *) echo "Internal error!" ; exit 1 ;; esac done #echo "Remaining arguments:" #for arg do echo '--> '"\`$arg'" ; done if [ -z "$showhelp" ]; then echo "usage: "`basename $0`" <OPT> <.VOB file>" echo "GPLv2 by Erno Rigo <mcree_AT_tricon.hu>" echo "" echo "OPT can be:" echo -e "$opts" | while read line; do opt=`echo "$line" | cut -f1 -d# | tr -d ':'` desc=`echo "$line" | cut -f2 -d#` helpline=`printf "%20s %s" "--$opt" "$desc"` echo -e "$helpline" done fi
Short shell script to monitor an URL for change. Sends notification and differences in e-mail.
#!/bin/bash # Short shell script to monitor an URL for change. # Sends notification and differences in e-mail. # # by Erno Rigo <mcree@tricon.hu> # # Licensed under the GPL ;-) FILE="kzblog" OLDFILE="$FILE.old" SENDER="devnull@example.com" RECIPIENT="somebody@somewhere.com" URL="http://kz71.freeblog.hu/" if [ ! -r $OLDFILE ]; then wget -q -O - "$URL" | html2text -nobs > $OLDFILE; fi wget -q -O - "$URL" | html2text -nobs > $FILE diff=`diff $OLDFILE $FILE` if [ "$diff" ]; then echo -e "To: $RECIPIENT\nSubject: $URL changed\nContent-Type: text/plain;\n charset=iso-8859-1\n\n$diff" | sendmail -F "$SENDER" -f "$SENDER" -r "$SENDER" -i "$RECIPIENT" mv -f $FILE $OLDFILE fi
I use the following shell script to unpack all RAR files in a directory and all subdirectories. The script supports both the old and new RAR naming conventions (both .rar, .r00, .r01, … AND .partXX.rar styles).
#!/bin/bash set -e archives="rar partrar" unpack_rar() { name=`echo "$1" | egrep '^.*[.]rar$' | egrep -v "[.]part[0-9]+[.]"` if [ ! -z "$name" ]; then basename=`echo "$name" | sed 's/\.rar$//g'` basetrunc=`basename "$basename"` dirname=`dirname "$name"` rar x -vy "$name" "$dirname" && find "$dirname" -regextype posix-egrep -regex ".*$basetrunc.*.r(ar|[0-9]+)\$" -print0 | xargs -0 -n1 rm -f else return 1 fi return 0 } unpack_partrar() { name=`echo "$1" | egrep '^.*[.]part0+1[.]rar$'` if [ ! -z "$name" ]; then basename=`echo "$name" | sed 's/\.part0\+1\.rar$//g'` basetrunc=`basename "$basename"` dirname=`dirname "$name"` rar x -vy "$name" "$dirname" && find "$dirname" -regextype posix-egrep -regex ".*$basetrunc.*.rar\$" -print0 | xargs -0 -n1 rm -f else return 1 fi return 0 } find . | while read file; do for arc in $archives; do unpack="unpack_$arc" $unpack "$file" && break done done
<< Newer entries | Older entries >>