RIGO.INFO TechBlog

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(.

VYM to Freemind

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>
2010-05-02 20:06 · 0 Linkbacks

VOB to AVI using Mencoder (Next Gen)

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
2010-05-02 20:06 · 0 Linkbacks

VOB to AVI using Mencoder

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… :-D

#!/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
2010-05-02 20:06 · 0 Linkbacks

URL Monitor

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
2010-05-02 20:06 · 0 Linkbacks

Unpack all RAR archive files in a directory tree

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
2010-05-02 20:06 · 0 Linkbacks

Linkbacks

Use the following URL for manually sending trackbacks: http://rigo.info/lib/plugins/linkback/exe/trackback.php/en:blog
en/blog.txt · Utolsó módosítás: 2009-05-15 00:00 (külső szerkesztés)
CC Attribution-Noncommercial-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0