Streaming DVB with VLS on Debian
Installing Debian
Boot server from Debian 3.1 Sarge NetInst CD, specifiying these boot options:
linux netcfg/disable_dhcp=true
Select the appropriate language, country and keymap.
Enter the IP address, netmask, router and DNS server as prompted. Set the server's hostname and domain name when prompted.
Select the "Erase entire disk" option when prompted for partitioning. Accept the new partition layout and the disk will be formatted.
The base system is installed automatically, when prompted, accept the default "Yes" to installing GRUB on the MBR.
Remove the CD when prompted and select OK when done to reboot the server.
Select "Yes" to the prompt asking if the hardware clock is set to GMT. Select the appropriate timezone.
Enter the root password and confirm when requested. Setup a normal user account following the on screen instructions.
When prompted, choose to source the installation from an HTTP server and choose an appropriate local mirror.
At the package selection screen, do not select any of the available options, just choose "OK".
At the Exim4 configuration screen, select "No configuration at this time" and accept "Yes" when prompted if you're sure you don't want to configure a mail system. Accept the default root mail recipient when prompted.
Finally, select OK to confirm Debian has been installed!
Optional for Debian Sarge
If you've installed Debian Sarge as suggested above and you're using the Hauppauge Nova-t card based on the Conxent chipset, your card won't be detected by the stock Debian 2.6 kernel. You can build the latest kernel version to solve this, or optionally, use my kernel for Pentium 4 or K7 processors:
Edit /etc/apt/sources.list and add:
deb http://packages.neuron1.com/ stable main
Reload the package list and install the most recent available dvbsn kernel for your architecture:
apt-get update apt-get install kernel-image-2.6.12.4-dvbsn-p4
Once installed, reboot.
Preparing for VLS
Install some necessary packages:
apt-get install dvb-utils libdvbpsi3 libdvbpsi3-dev
Change directory to /usr/local/src and download the VLS and libdvb source tarballs:
cd /usr/local/src wget http://downloads.videolan.org/pub/videolan/vls/0.5.6/vls-0.5.6.tar.gz wget http://downloads.videolan.org/pub/videolan/vls/0.5.6/contrib/libdvb-0.2.2.tar.gz
Configure, compile and install libdvb and VLS as follows (changing version numbers if they're different):
tar zxvf libdvb-0.2.2.tar.gz cd libdvb-0.2.2 make make install install satscan /usr/local/bin cd .. tar zxvf vls-0.5.6.tar.gz cd vls-0.5.6 ./configure --enable-dvb --disable-dvd \ --with-libdvb=/usr/local/src/libdvb-0.2.2 \ --with-dvbpsi=/usr make make install
If you're doing this with a Debian version that's based on GCC 4 (Ubuntu's Breezy Badger for example), you might have a bit of trouble compiling VLS, install GCC v3.3 and use that instead, like this:
apt-get install gcc-3.3 g++-3.3 CC=gcc-3.3 CXX=g++-3.3 ./configure --enable-dvb --disable-dvd \ --with-libdvb=/usr/local/src/libdvb-0.2.2 \ --with-dvbpsi=/usr
Finding Channels
This next bit is rather tricky I'm afraid. We need to create a skeleton dvbrc file listing all the transponder details where we'll find channels to stream. If you're lucky, you'll be able to find one for your area (for DVB-T) or satellite. I'll provide the files for Sandy Heath and Crystal Palace below.
We need to use the satscan program from libdvb to generate the full dvbrc. Unfortunately it's rather out of date now, so it's starting point files aren't amazingly useful. The more up-to-date scan program from the dvb-utils will probably help you more. You can run that like this:
scan /usr/share/doc/dvb-utils/examples/scan/dvb-t/uk-SandyHeathThe starting files it provides only list one transponder, but from that it seems able to work out where to look next. It's output will be enough to help you piece together the skeleton file as I've done below. If anyone knows a better way to do this, I'd love to hear from you.
Skeleton dvbrc for Crystal Palace
LNB ID 1 TYPE 0
SAT ID 1 NAME "CrystalPalace" LNBID 1 FMIN 1 FMAX 2
TRANSPONDER ID 0001 SATID 0001 TYPE 2 FREQ 505833333 BANDWIDTH 0 HP_RATE 3 LP_RATE 0 MODULATION 1 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0002 SATID 0001 TYPE 2 FREQ 481833000 BANDWIDTH 0 HP_RATE 2 LP_RATE 1 MODULATION 3 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0003 SATID 0001 TYPE 2 FREQ 561833000 BANDWIDTH 0 HP_RATE 2 LP_RATE 1 MODULATION 3 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0004 SATID 0001 TYPE 2 FREQ 529833333 BANDWIDTH 0 HP_RATE 3 LP_RATE 0 MODULATION 1 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0005 SATID 0001 TYPE 2 FREQ 578167000 BANDWIDTH 0 HP_RATE 3 LP_RATE 0 MODULATION 1 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0006 SATID 0001 TYPE 2 FREQ 537833333 BANDWIDTH 0 HP_RATE 3 LP_RATE 0 MODULATION 1 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
Skeleton dvbrc for Sandy Heath
LNB ID 1 TYPE 0
SAT ID 1 NAME "SandyHeath" LNBID 1 FMIN 1 FMAX 2
TRANSPONDER ID 0001 SATID 0001 TYPE 2 FREQ 641833334 BANDWIDTH 0 HP_RATE 3 LP_RATE 0 MODULATION 1 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0002 SATID 0001 TYPE 2 FREQ 665833330 BANDWIDTH 0 HP_RATE 2 LP_RATE 1 MODULATION 3 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0003 SATID 0001 TYPE 2 FREQ 650166670 BANDWIDTH 0 HP_RATE 2 LP_RATE 1 MODULATION 1 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0004 SATID 0001 TYPE 2 FREQ 842000000 BANDWIDTH 0 HP_RATE 3 LP_RATE 0 MODULATION 1 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0005 SATID 0001 TYPE 2 FREQ 626166670 BANDWIDTH 0 HP_RATE 2 LP_RATE 1 MODULATION 3 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
TRANSPONDER ID 0006 SATID 0001 TYPE 2 FREQ 674166670 BANDWIDTH 0 HP_RATE 2 LP_RATE 1 MODULATION 3 TRANSMISSION_MODE 0 GUARD_INTERVAL 0 HIERARCHY 0
Create a directory /etc/dvb and save the skeleton file there as dvbrc.template or similar.
Next, we need to use satscan to find out what channels are available on the transponders we've configured, and save the output to our system-wide dvbrc file:
satscan /etc/dvb/dvbrc.template > /etc/dvb/dvbrcBe sure to answer 'y' to clearing the channel list and scanning the named satellite. After a short while you should be returned to the command prompt and if you look in /etc/dvb/dvbrc you'll hopefully find a list of the channels available. This information will come in useful later, so make note of it somewhere.
If you're running more than one source card then you'll need multiple copies of the dvbrc file available. If each card is of the same type (e.g. all terrestrial or all pointing at the same satellite), then simply symlink for as many cards as you have:
ln -s /etc/dvb/dvbrc /etc/dvb/dvbrc.1 ln -s /etc/dvb/dvbrc /etc/dvb/dvbrc.2
Configuring VLS
The next job is to create a configuration file for VLS so it knows what to do. A short, documented sample is shown below. The configuration is kept in /usr/local/etc/videolan/vls/vls.cfg by default, but you can keep elsewhere if you want.
# Sample configuration for streaming DVB with VLS # application wide settings BEGIN "Global" LogFile = "/var/log/vls.log" # log file ScreenLog = "enable" # log to the console SystemLog = "disable" END # define available input devices BEGIN "Inputs" dtt0 = "dvb" END BEGIN "dtt0" Type = "Mpeg2-TS" # Stream type (default is "Mpeg2-PS") DeviceNumber = "0" # /dev/dvb/adapter(x) SendMethod = "0" # 0 - Send All Pids IgnoreTimeout = "1" # lets us take out the aerial or get a bad signal END # define output channels BEGIN "Channels" channel_01 = "network" channel_02 = "network" channel_03 = "network" channel_04 = "network" channel_05 = "network" END BEGIN "channel_01" Type = "multicast" TTL = "5" DstHost = "239.192.254.1" DstPort = "5004" Interface = "eth0" END BEGIN "channel_02" Type = "multicast" TTL = "5" DstHost = "239.192.254.2" DstPort = "5004" Interface = "eth0" END BEGIN "channel_03" Type = "multicast" TTL = "5" DstHost = "239.192.254.3" DstPort = "5004" Interface = "eth0" END BEGIN "channel_04" Type = "multicast" TTL = "5" DstHost = "239.192.254.4" DstPort = "5004" Interface = "eth0" END BEGIN "channel_05" Type = "multicast" TTL = "5" DstHost = "239.192.254.5" DstPort = "5004" Interface = "eth0" END # what to do on startup # channel names are sourced from the dvbrc file # (with spaces replaced by underscores) BEGIN "LaunchOnStartup" # Freeview Multiplex 1 command_101 = "start BBC_ONE channel_01 dtt0" command_102 = "start BBC_TWO channel_02 dtt0" command_103 = "start BBC_THREE channel_03 dtt0" command_104 = "start CBBC_Channel channel_04 dtt0" command_105 = "start BBC_NEWS_24 channel_05 dtt0" END
OK, a little explanation of some of that stuff. After the global settings we define a list of available inputs, then describe each input within it's own section.
Next, we define a set of output channels, then describe each output channel. In this case we're going to be multicasting our transmissions. A quick note, we've chosen 239.192.254.x based on a little research. 239.192.x.x is for multicast what 192.168.x.x is for regular IP allocations, it's stuff that'll stay in our network. And for some reason IPs are traditionally allocated backwards, hence we chose 239.192.254.x (we couldn't bring ourselves to use 255 for superstitious reasons). We decided to work up on the final number to make them a little logical, 1 for BBC 1, etc.
The important to take away from this is not to make the mistake we did, and use numbers like 224.0.x.x because they're the first multicast addresses available. These are especially allocated for various configuration and network chatter things and your traffic will leak all over the place. It's not good.
Finally, we select which channels to stream, where they come from and where to send them. Remember, a single card can only tune to one transponder, so you must only use channels from the same transponder for each card you start streams from. I don't know what'll happen if you disregard this!
Test It
Get VLS started, hopefully without any error messages popping up:
vls -f /usr/local/etc/videolan/vls/vls.cfg
Using VLC on another machine you should be able to open a network stream and tune to something like 239.254.192.1 port 5004 and find a working TV channel. If not, something's gone wrong. Good luck fixing it!
Getting it running at bootup
If it's all working, you'll probably want to have VLS running every time you reboot the server. Below is a simple init script (taken from the Debian skeleton script). I'm using vls and backgrounding it rather than vlsd as I've had some problems with the daemonised version. Save a copy of the below to /etc/init.d/vls or similar.
#! /bin/sh # # vls vls initscript # # Author: Stephen Newey. # # Version: @(#)vls 1.0 5-Oct-2005 spam@freakymousemats.com # set -e PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DESC="vls" NAME=vls DAEMON=/usr/local/bin/$NAME PIDFILE=/var/run/$NAME.pid SCRIPTNAME=/etc/init.d/vls # Gracefully exit if the package has been removed. test -x $DAEMON || exit 0 # Read config file if it is present. if [ -r /etc/default/vls ] then . /etc/default/vls fi test "$RUN_DAEMON" = "yes" || exit 0 # # Function that starts the daemon/service. # d_start() { start-stop-daemon --start --quiet -b --exec $DAEMON -- $OPTIONS } # # Function that stops the daemon/service. # d_stop() { start-stop-daemon --stop --quiet --name $NAME } # # Function that sends a SIGHUP to the daemon/service. # d_reload() { start-stop-daemon --stop --quieti --name $NAME --signal 1 } case "$1" in start) echo -n "Starting $DESC: $NAME" d_start echo "." ;; stop) echo -n "Stopping $DESC: $NAME" d_stop echo "." ;; #reload) # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # # If the daemon responds to changes in its config file # directly anyway, make this an "exit 0". # # echo -n "Reloading $DESC configuration..." # d_reload # echo "done." #;; restart|force-reload) # # If the "reload" option is implemented, move the "force-reload" # option to the "reload" entry above. If not, "force-reload" is # just the same as "restart". # echo -n "Restarting $DESC: $NAME" d_stop sleep 1 d_start echo "." ;; *) # echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit 0
To support the init script you'll need the configuration file below so that VLS knows where it's configuration file is. Call it /etc/default/vls.
#Defaults for vls RUN_DAEMON="yes" OPTIONS="-f /usr/local/etc/videolan/vls/vls.cfg"
Finally link it into the default runlevels so it starts automatically, and make sure it's executable:
chmod 755 /etc/init.d/vls update-rc.d vls defaults
And that's it, you should have a DVB streaming server!
Stephen Newey - 5th October 2005
