26 Jan 2008

ivtv scanner and tuner

with my new pvr-150 from hauppauge i was wondering how to scan for channels.

it seems quiet simple:

echo "" > channels; 
c=0;
while [[ $c -lt 255 ]]; do
ivtv-tune -c $c | grep "Detected" | awk '{print $2"\t"'$c'}';
c=`expr $c + 1`;
done >> channels & \
tail -f channels

The above scanner scans by channel, this is not optimal if you are living in a not-so-well-known region and you have a brain dead tv provider which doesn't make the frequency table available online (like eblcom.ch a subsidary of cablecom).

the example below will scan by frequency rather than by channel:
#!/bin/bash

## begin config
start="170.000"; # float, must provide 3 decimal digits
end="1000.000"; # float, must provide 3 decimal digits
step="250"; # int, seps by thousands
file="channel.txt";
## end config

c=`echo $start \* 1000 | bc | sed -e 's/\.000//'`;
end=`echo $end \* 1000 | bc | sed -e 's/\.000//'`;
detected=0;
fstart=0;
fend=0;
last=0;

channel=0;

while [ $c -lt $end ]; do
freq=`echo "$c" | sed -e 's/\([0-9]\{3\}\)$/.\1/'`;
# echo "$c | $freq";
r=`ivtv-tune -f $freq | grep Detected`;
c=`echo "$c + 250" | bc`;

if [[ $detected == 0 ]]; then
if [[ -n "$r" ]]; then
fstart=$freq;
detected=1;
fi
else
if [[ -z "$r" ]]; then
fend=$last;
detected=0;

#echo "scale=3; ($fend - $fstart) / 2 + $fstart";
med=`echo "scale=3; ($fend - $fstart) / 2 + $fstart" | bc`;

echo "$channel $med";
echo "$channel $med" >> $file;

channel=`expr $channel + 1`;
fi
fi

last=$freq;

done


and here is a simple bash tuner
#!/bin/bash

# config
device=/dev/video0;
channels=~/.channels
lastchannel=~/.lastchannel
channel=1;
frequency=0;

if [[ -f "$lastchannel" ]]; then
channel=`cat $lastchannel`;
fi

# start mplayer
mplayer -vo xv /dev/video0 -ao sdl $device 2>&1 >/dev/null &
mplayerpid=$!;
echo "pid of mplayer: $mplayerpid";

# tun into other channel
function tune {
frequency=`cat $channels | awk '/^'$1'\t/ {print $2}'`;

if [[ -z "$frequency" ]]; then
echo "unknown channel $1" > /dev/stderr;
return 1;
fi

echo $1 > $lastchannel
channel=$1;
ivtv-tune -d $device -f $frequency 2>&1 >/dev/null&

return 0;
}

# tune default channel
tune $channel;

# main loop
while true; do

# read input
echo -en "Channel $channel/$frequency [or +/-] "; read c;

# validate input
c=`echo "$c" | sed -e 's/[^q0-9\+\-]//g '`;

# +/- change channel ?
if [[ "$c" == "+" ]]; then
tune `expr $channel + 1`;
continue;
fi

if [[ "$c" == "-" ]]; then
tune `expr $channel - 1`;
continue;
fi

# quit ?
if [[ "$c" == "q" ]]; then
kill -TERM $mplayerpid 2>/dev/null;
break;
fi

# numeric channel
if [[ -n "$c" ]]; then
tune $c;
continue;
fi

echo $c;
done

exit 0;