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