Quozl's streaming server for ABC TV via DVB-T |
| quozl@us.netrek.org
| up |
|
Looks like there are simpler ways to do it, but this way got me the underlying components individually tested. I also learned how it works, rather than treat it as a black box.
Next time I do this, I'll ask for an OEM card. The rest of the package is an annoying waste.
A Digital Video Broadcast (DVB) is a transport stream (TS) consisting of multiple audio and video streams. DVB-T is terrestrial, meaning transmitted from an antenna nearby. A "channel" as understood by a consumer is whatever streams are required to show a television programme.
# cat /dev/dvb/adaptor0/dvr0 > test.mp2 ^C # mplayer test.mp2
http { port 8000; }; adapter 0 { dvb-t { frequency 226500000; bandwidth 7; transmission-mode auto; guard-interval auto; hierarchy none; modulation auto; }; stream { name "ABC TV"; input { pid 512; pid 650; }; output-rtp { remote-address 224.0.0.1; remote-port 5000; }; }; stream { name "ABC2"; input { pid 513; pid 651; }; output-rtp { remote-address 224.0.0.2; remote-port 5000; }; }; stream { name "ABC HDTV"; input { pid 516; pid 654; }; output-rtp { remote-address 224.0.0.3; remote-port 5000; }; }; stream { name "ABC DiG Jazz"; input { pid 700; }; output-rtp { remote-address 224.0.0.4; remote-port 5000; }; }; stream { name "ABC DiG Radio"; input { pid 690; }; output-rtp { remote-address 224.0.0.5; remote-port 5000; }; }; };
mplayer -cache 2048 -vo xv -ao sdl -quiet \ -panscan 1.0 -zoom -fs rtp://224.0.0.1:5000/
#!/bin/sh set -e CHANNEL="${1}" if test -z "${CHANNEL}"; then CHANNEL='abc-1-and-2' echo "fe: defaulting to ${CHANNEL}" else echo "fe: channel ${CHANNEL}" fi if test -f /tmp/fe.channel; then read CHANNEL_OLD < /tmp/fe.channel if test "${CHANNEL}" != "${CHANNEL_OLD}"; then echo "fe: is running on wrong channel" fe-stop else echo "fe: already running fine" exit 0 fi fi cd LD_LIBRARY_PATH=/usr/local/lib \ nice --adjustment=-20 /usr/local/bin/getstream -c ${CHANNEL}.conf & FE_PID=$! echo ${FE_PID} > /tmp/fe.pid echo ${CHANNEL} > /tmp/fe.channel echo "fe: started, pid is ${FE_PID}"
#!/bin/sh set -e if [ ! -f /tmp/fe.pid ]; then if pkill getstream; then echo "fe: was running without pidfile" else echo "fe: was not running" fi exit fi read FE_PID < /tmp/fe.pid if kill ${FE_PID}; then echo "fe: stopped, pid was ${FE_PID}" rm -f /tmp/fe.pid /tmp/fe.channel else echo "fe: pid ${FE_PID} was not found" rm -f /tmp/fe.pid /tmp/fe.channel if pkill getstream; then echo "fe: was running with different pid" fi fi
#!/bin/bash set -e STREAM=1 NAME=noname if test -n "$1"; then STREAM=$1 shift if test -n "$1"; then NAME=$1 fi fi FREE=`df --block-size=1k /tv|tail -1|awk '{print $4}'` FILE=/tv/`date +%Y-%m-%d`-${NAME}.ts if test -f ${FILE}; then FILE=`date +%Y-%m-%d-%s`-${NAME}.ts while test -f ${FILE}; do sleep 0.5 FILE=`date +%Y-%m-%d-%s`-${NAME}.ts done fi echo "ts: recording stream ${STREAM} into ${FILE}" ( nice --adjustment=-19 dumprtp 224.0.0.${STREAM} 5000 2> /tmp/ts.${STREAM}.log | \ pv --interval=1 --size=${FREE}k > ${FILE} ) & TS_PID=$! echo ${TS_PID} > /tmp/ts.${STREAM}.pid wait ${TS_PID} echo "ts: stopped stream ${STREAM} at `date +%H:%M:%S` file ${FILE}" echo -en '\007' > /dev/tty1
#!/bin/bash set -e STREAM=1 if test -n "$1"; then STREAM=$1 fi if [ ! -f /tmp/ts.${STREAM}.pid ]; then if pkill -f "dumprtp 224.0.0.${STREAM}"; then echo "ts: was running without pidfile" else echo "ts: was not running" fi exit fi read TS_PID < /tmp/ts.${STREAM}.pid if pkill -U ${TS_PID}; then echo "ts: stopped, pid was ${TS_PID}" rm -f /tmp/ts.${STREAM}.pid else echo "ts: pid ${TS_PID} was not found" rm -f /tmp/ts.${STREAM}.pid if pkill -f "dumprtp 224.0.0.${STREAM}"; then echo "ts: was running with different pid" fi fi
#!/bin/sh # $1 start time # $2 end time # $3 stream # $4 title # FIXME: workaround to cope with tomorrow is to schedule the call to # pick for tomorrow, e.g. echo 'pick arg arg arg arg' | at tomorrow at "${1}" <<EOF exec > "/tmp/pick-${1}-${2}-${3}.log" fe ${3} echo ts-stop ${3} | at "${2}" ts ${3} ${4} EOF