DVB-Streaming mit VLC unter Linux

Ich möchte hier kurz aufzeigen, wie man auf ziemlich einfache Weise einen Streaming-Server mit Hilfe des bekannten VLC-Players aufsetzen kann. Ziel des kleinen Projektes ist es, mehrere Streams (in diesem Fall vier) mit Hilfe von mehreren VLC-Instanzen bereit zu stellen. Als Quelle dient eine DVB(-C)-Karte von Digital Devices, die es ermöglicht, bis zu acht Tuner in diversen Kombinationen über eine Karte (Bridge) zu betreiben. Als Stream wird ein Video mit 480 Zeilen (progressiv/16:9) in einem ts-Container (TransportStream) und mit H.264 Datenreduktion (Codec) aufbereitet. Das Audio wird als MP2 eingebettet.

Server-Hardware

stream1-rack

Als „Server“ verwende ich eine Dell Precision T1650 Workstation mit 8GB RAM.

Prozessor

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 58
Stepping:              9
CPU MHz:               1600.000
BogoMIPS:              6784.26
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU(s):     0-7

DVB-Hardware

Digital Devices DVB

Digital Devices
1x Bridge (Octopus PCIe Bridge)
2x DVB-C/T Tuner-Modul (DuoFlex C/T)

Module-Config (dmesg):

[    5.627998] DDBridge driver detected: Digital Devices Octopus DVB adapter
[    5.628018] HW 00010000 REG 00010004
[    5.628087] DDBridge 0000:03:00.0: irq 45 for MSI/MSI-X
[    5.628772] Port 0 (TAB 1): NO MODULE
[    5.630290] Port 1 (TAB 2): DUAL DVB-C/T
[    5.631808] Port 2 (TAB 3): DUAL DVB-C/T
[    5.632431] Port 3 (TAB 4): NO MODULE
[    5.632701] DVB: registering new adapter (DDBridge)
[    5.632703] DVB: registering new adapter (DDBridge)
[    5.632704] DVB: registering new adapter (DDBridge)
[    5.632705] DVB: registering new adapter (DDBridge)

Treiber/Module-Installation: http://www.linuxtv.org/wiki/index.php/Digital_Devices_DuoFlex_C%26T

Operating System

Der Streaming-Server läuft unter Debian7 (GNU/Linux) 64bit.

Dateisystem

RAM-Disk / tmpfs

Um für die Screenshots (Web-IF) nicht viele Harddisk-Zugriffe zu generieren, wird eine Ramdisk erstellt. Eine einfache Methode ist die Benutzung des „tmpfs“ Dateisystems. Es wird im RAM angelegt und lagert die Daten nur im Notfall (wenn das RAM knapp wird) auf die SWAP-Partition aus. Hierzu wird folgende Zeile in der „/etc/fstab“ angefügt:

tmpfs    /var/www/screenshot    tmpfs    defaults,size=10M      0       0

Partitionen / Mount

sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
udev on /dev type devtmpfs (rw,relatime,size=10240k,nr_inodes=1017437,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=815164k,mode=755)
/dev/disk/by-uuid/a928b728-7c8c-40a8-870b-df4e2296f679 on / type ext4 (rw,relatime,errors=remount-ro,user_xattr,barrier=1,data=ordered)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /run/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=3583300k)
/dev/sda7 on /tmp type ext4 (rw,relatime,user_xattr,barrier=1,data=ordered)
/dev/sda6 on /var type ext4 (rw,relatime,user_xattr,barrier=1,data=ordered)
rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /var/www/screenshot type tmpfs (rw,relatime,size=10240k)

Partitionen / Grösse

Dateisystem                                            Größe Benutzt Verf. Verw% Eingehängt auf
rootfs                                                  817G    5.7G  769G    1% /
udev                                                     10M       0   10M    0% /dev
tmpfs                                                   797M    808K  796M    1% /run
/dev/disk/by-uuid/a928b728-7c8c-40a8-870b-df4e2296f679  817G    5.7G  769G    1% /
tmpfs                                                   5.0M       0  5.0M    0% /run/lock
tmpfs                                                   3.5G    344K  3.5G    1% /run/shm
/dev/sda7                                                46G    182M   44G    1% /tmp
/dev/sda6                                                46G   1002M   43G    3% /var
tmpfs                                                    10M     16K   10M    1% /var/www/screenshot

Netzwerk

Ein funktionierendes Netzwerk mit konfigurierter, fixer IP wird vorausgesetzt. In diesem Artikel hat der Server die IP-Adresse 192.168.1.100.

Software

Um die Installation zu dokumentieren, kann eine Liste aller installierten Pakete mit folgendem Befehl erstellt werden:

sudo dpkg -l | grep ^ii | awk '{print $2}' > paket-liste-$HOSTNAME

Um alle Pakete in dieser Liste zu installieren (z.B. auf einem neu installierten PC) kann folgender Befehl verwendet werden:

for paket in $(cat paket-liste-$HOSTNAME); do
echo $paket;
sudo apt-get install $paket;
done

Sendersuchlauf

Um eine aktuelle Sendertabelle zu erzeugen, wird das Tool „w_scan“ verwendet. Es beherrscht das Erstellen von Sendertabellen für unterschiedlichste TV-Software. In unserem Fall ist dies der VLC-Player.

w_scan -fc -c CH -L > ~/channelsDVB_VLC.xspf

Mit diesem Befehl wird der Sendersuchlauf gestartet und die Sendertabelle wird im Home-Verzeichnis als VLC-Playlist geschrieben. Im Startscript des VLC wird diese Datei geladen.

Weitere Informationen zu w_scan: http://www.vdr-wiki.de/wiki/index.php/W_scan

VLC Script (Streaming starten)

Zum Starten des VLC (ohne GUI) wird folgendes Script (Shell-Script) verwendet (IP und Port muss angepasst werden):

cvlc -I http --http-src "/usr/share/vlc/lua/http" --http-host 192.168.1.100 \
--http-port 8080 -vvv "/home/stream/channelsDVB_VLC.xspf" --dvb-adapter=0 \
--loop --aspect-ratio 16x9 --sout "#gather:transcode{vcodec=h264,height=480,fps=25,\
vb=3500,acodec=mp2,ab=128,channels=2,samplerate=44100,deinterlace,\
venc=x264{preset=ultrafast}}:standard{mux=ts,dst=192.168.1.100:8080/stream,\
access=http}" --sout-keep
  • Beim Start lädt der VLC-Player die Playlist „/home/stream/channelsDVB_VLC.xspf“, die alle verfügbaren Sender auf dem DVB-C Netz beinhaltet.
  • Wenn der VLC neu über das Script gestartet wird, streamt er automatisch den ersten Eintrag in der Senderliste/Playlist.
  • Im Abschnitt „transcode“ werden die Informationen für Container (TS), Codec (H.264/MP2) und weitere Optionen übergeben.
  • Im Log erscheint immer wieder einmal die Warnung „main mux warning: late buffer for mux input“. Diese konnte mit der Transcoding-Option „venc=x264{preset=ultrafast}“ grösstensteils beseitigt werden.
  • Der Stream wird über http (access=http) zur Verfügung gestellt.
  • –sout-keep bewirkt, dass der Stream (z.B. beim Umschalten von Quellen) nicht abgebrochen wird und die Player die Wiedergabe abbrechen. Die entstehenden Fehler beim Umschalt-Prozess bewegen jedoch erfahrungsgemäss trotzdem diverse Player dazu, die Wiedergabe abzubrechen.

Die Scripte werden zur Zeit jeweils einzeln in einem Terminal gestartet. So sieht man auch direkt, was bei den einzelnen Stream’s abgeht.

VLC Script (Screenshots starten)

Um die Screenshots auf der Webseite des Streaming-Server anzuzeigen, wird eine weitere VLC-Instanz verwendet. Sie verbindet sich auf den Stream und macht alle 250Frames einen Screenshot, der im Verzeichnis des Webservers (in das erstellte tmpfs/RAM-Disk) abgelegt wird. Das Script dazu sieht so aus:

cvlc http://192.168.1.100:8080/stream --rate=1 --video-filter=scene --vout=dummy \
--aout=dummy --scene-format=png --scene-ratio=250 --scene-prefix=stream_8080 \
--scene-path=/var/www/screenshot --scene-width=150 --scene-replace vlc://quit

Auf das Webinterface gehe ich nicht näher ein. Dieses kann von ganz einfach bis komplex aufgebaut sein und ist somit individuell. Das Web-Interface der VLC-Instanzen ist über den jeweiligen Port (8080) erreichbar. Natürlich muss jede VLC-Instanz auf einem eigenen Port laufen. Am besten nutzt man unter Unix/Linux Ports ab 1024 aufwärts, da diese keine Root-Rechte auf dem System benötigen, sondern auch als normaler User verwendet werden können.

Beispiel für ein Info-Screen mit integriertem TV-Stream:

infoscreen-steaming

Flattr this!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*