OpenWrt: UPnP (DLNA) Server über WLAN

Update 7. Dezember 2015: Bugs / Multicast
Update 27. November 2014: Bugs

Es gibt immer mehr DNLA-fähige Geräte (Android BubbleUPnP). Viele Fernseher und Blueray-Player spielen Mediendateien ab. Der OpenWrt-Router eignet sich sehr gut als DLNA(=UPnP)-Server. Es gibt dafür 2 Pakete (die sich auch parallel betreiben lassen). Für die Konfiguration werden die entsprechenden Pakete für Luci gleich mitinstalliert:

opkg update
opkg install minidlna luci-app-minidlna

oder

opkg install ushare luci-app-ushare

minidlna hat den Vorteil, dass es eine Datenbank anlegt und darin die ausgelesenen Tags (mp3-Tags) ablegt. Man kann so nach Alben und Künstler suchen. Der Nachteil davon ist, dass es bei umfangreichen Musiksammlungen recht lange geht, bis die Datenbank erstellt ist. Ausserdem wird die Datenbank im volatilen RAM (schnell, in /tmp) abgelegt und füllt so schnell den wertvollen Speicher. Man kann das auf eine Harddisk oder einen Stick umlegen, aber dann ist es recht langsam.
ushare benötigt keine Datenbank, ist so schnell einsatzbereit, bietet aber nicht die Auswahl nach Alben oder Künstlern. Man kann nur in den Verzeichnissen suchen.

minidnla (UPnP)

Für grosse Medienarchive reicht das auf solchen Routern knappe RAM nicht aus, da die Datenbank standardmässig in /var/run abgelegt wird.

Man ändert also den Speicherort in /etc/config/minidlna oder via Webinterface von

option db_dir '/var/run/.minidlna'

zu:

option db_dir '/root/.minidlna'

oder man legt die Datenbank auf die angeschlossene Harddisk mit den Musikdaten:

option db_dir '/mnt/sdb1/minidlna'

Dieses Verzeichnis (oder gleich die gesamte Harddisk) kann man mit Samba als Windows share freigeben.

Rescan der Mediendaten

minidlna benutzt ab Version 'Attitude Adjustment' oder den trunk-Versionen ('Barrier Breaker') inotify. Damit erübrigt sich nach einer Veränderung der Medien-Bibliothek (neue Daten, Verschieben oder Löschen) das erneute mitunter mühsame Scannen aller Dateien. inotify funktioniert in der Regel sehr gut.

inotify funktioniert nicht: Neue Mediendaten werden nicht erkannt

Um inotify zum Laufen zu bringen, reicht ein Befehl:

mknod /dev/inotify c 10 63

Siehe auch: https://dev.openwrt.org/ticket/10711

Bugs

DLNA-Renderer aus dem WLAN nicht sichtbar im LAN oder anderem WLAN

OpenWrt leitet keine Unicast oder Multicast-Pakete zwischen WLAN und LAN oder WLAN und WLAN weiter. Dadurch "sieht" man die Empfänger nicht oder nur manchmal, auf denen (bspw via Tablet oder Smartphone) Mediendaten vom Medienserver wieder gegeben werden sollen.

Via igmproxy und udpxy lasse sich das Problem lösen (siehe auch ganz unten auf dieser Seite). Einfacher geht es aber so:

Angenommen, die Standardinstallation mit einem LAN (keinen virtuellen LANs, funktioniert dort aber genau gleich) bridged (brückt) ein LAN und zwei WLANs. Der Medienserver ist am LAN, der Fernseher und der Streamingverstärker sind per Geräte-WLAN angebunden. Die persönlichen Clients (also Tablets, Smartphones, Laptops) sind im eigentlichen User-WLAN (oder Gäste-WLAN).

mit

echo "0" > /sys/devices/virtual/net/br-an/bridge/multicast_snooping

werden unicast und multicast-Packete zwischen LAN/WLAN, resp. WLAN/WLAN weiter geleitet.

Minidlna 1.1.4-2 bricht bei der Datenbankerstellung ab

Seit der Version 1.1.4-2 (unter OpenWrt 15.05 Chaos Calmer) bricht minidlna die Erstellung der Datenbank wegen Speicherproblemen ab. Man erkennt das an unvollständigen Verzeichnissen beim Browsen der Mediendaten. Es fehlen (meist) viele Mediendaten ab einem bestimmten Punkt in der alphabetischen Reihenfolge, die der Scanner abarbeitet. Der Grund liegt in der Erstellung der Albumvorschauen (Thumbnails), die minidlna aus den Albumcovers generiert. Dafür wird Speicher reserviert, der unmittelbar mit der Auflösung in 24bit zusammen hängt. Kann er nicht zur Verfügung gestellt werden, wird kein Thumbnail generiert. Irgendwo hat die aktuelle Version ein Speicherleck, so dass das Programm nach einigen Fehlversuchen das Scannen der Mediendaten komplett abbricht.

Das Problem kann man umgehen, in dem man minidlna kleinere Vorlagen für die Generierung der Thumbnails (160x160 Pixel) zur Verfügung stellt (oder den Code fixt).

Minidlna lässt sich nicht stoppen.

Seit späteren trunk-Versionen inkl. der aktuellen Barrier-Breaker lässt sich minidlna nicht mehr "regulär" stoppen. Der Grund dafür liegt am falsch erwarteten Speicherort des pid-files. Der Datei, die die Prozessnummer beinhaltet. Diese Files liegen in der Regel in /var/run. minidlna legt sie aber standardmässig nach /var/run/minidlna/. Die OpenWrt-Skripte erwarten es aber in /var/run. Das ist leicht zu beheben. Man editiert /etc/init.d/minidlna und fügt am Anfang eine Zeile zu und ändert weiter unten den eigentlichen Befehl zum Starten:

#!/bin/sh /etc/rc.common
# Copyright (C) 2010 OpenWrt.org

START=50

SERVICE_USE_PID=1
PID=/var/run/minidlna.pid

start() {                                                 

….

service_start /usr/bin/minidlna -P $PID -f "$MINIDLNA_CONFIG_FILE"

Nun funktioniert auch wieder bspw. /etc/init.d/minidlna stop

Ein zweiter Bug betrifft die Statusanzeige, die nur 0-Werte anzeigt:

The miniDLNA service is active, serving 0 audio, 0 video and 0 image files.

Dazu gibt es einen Hinweis, der aber keine Lösung des Problems brachte: https://dev.openwrt.org/ticket/17222

Manuelles Rescanning

Es kann aber gelegentlich sein, dass neue Daten nicht im Medien-Verzeichnis erscheinen, was einen Rescan nötig machen kann.

Einen kleinen Vorteil hat das Ablegen der DB im RAM. Wird der Router neu gestartet, wird die Datenbank neu initialisiert. Das ist praktisch für nicht allzu grosse Medienbestände. Ab vielen Hundert Audiodateien dauert das Scannen aber recht lange. Legt man die Datenbank in ein für Windows (iOS und Linux) freigegebenes Verzeichnis (mit Samba als Windows share), kann man sie einfach löschen und via Webinterface unter System>Startup den Dienst minidlna "restarten".

In der Shell geht das einfach mit:

/etc/init.d/minidlna restart; /etc/init.d/minidlna stop
minidlna -d -R -f /tmp/minidnla.conf

(Der vorgänge 'restart' stellt sicher, dass die Konfigurationsdatei im /tmp-Verzeichnis liegen. Sie wird wie für alle Dienste unter OpenWrt beim Starten aus der Konfigurationsdatei (/etc/config/minidlna) generiert.)

Für Versionen vor "attitude adjustment" und "barrier breaker" (April 2013): Problem Multicast über WLAN: Die Lösung!

Es gibt jedoch ein Problem mit den multicast udp über das WLAN, so dass der Server selten erscheint, wenn nach ihm gesucht wird. Über das WLAN werden udp broadcasts nicht verschickt (oder gehen einfach unter). Siehe dazu auch: http://wiki.openwrt.org/doc/howto/udp_multicast.

Mit einem Trick gelingt dies jedoch hervorragend. Dafür benötigt man tcpdump

opkg update; opkg install tcpdump

Dann wird das Programm gestartet und die Netzwerkschnittstelle und localhost auf Port 1900 abgefragt.

tcpdump -ni br-lan port 1900 and host localhost

Man kann das leicht testen: BuppleUPnP starten und versuchen den Server zu finden. Meist hat man keinen Erfolg, ausser nach einem Neustart. Nun startet man tcpdump wie oben angegeben. Mit einem neuen Scan (bei BubbleUPnP von "Devices" auf "Library" und wieder auf "Devices" erscheint sofort der DNLA-Server.

Der Trick benötigt kaum (<0.1%) Rechenzeit, die Ausgabe wird nach /dev/null umgeleitet-

Damit man nicht jedes Mal in die Shell einloggen muss und tcpdump starten muss hier ein kleines Startup-Skript (qu ick and dirty):

#!/bin/sh /etc/rc.common
# *** udpwl: A quick and dirty method to enable udp multicasts over
# *** wlan with OpenWrt and a DNLA-Server like minidnla or ushare
# Copyright (C) iNetCom/jh 2012-12-15 v0.1
IF="br-lan"
PORT="1900"
HOST="localhost"
START=97
start() {
        [ -x /usr/sbin/tcpdump ] || return 1
        #service_start
        /usr/sbin/tcpdump -ni br-lan port $PORT and host $HOST &>/dev/null &
}
stop() {
        #service_stop
        killall tcpdump
}

Das kopiert man nach /etc/init.d und chmod +x /etc/init.d/udpwl. Es fehlen noch die Links zum rc.d. (Den K… braucht man eigentlich nicht.)

cd /etc/rc.d
ln -s ../init.d/udpwl S97udpwl
ln -s ../init.d/udpwl K97udpwl

Bemerkung zum "Autodiscovery"-Problem

[Update 02.06.2013] Die Lösung, quick and dirty, für das Problem udp Multicasts über WLAN steht unten beschrieben. Es gibt Schwierigkeiten mit OpenWrt-Versionen vor "attitude adjustment" oder "barrier breaker" (April 2013) in Verbindung mit minidnla oder ushare beim Bekanntmachen der oder des Medienserver im lokalen Wifi-Netz. Die "Renderer" ("Darsteller")-Geräte sehen die Medienserver nicht. Die neueren Versionen ab April 2013 weisen das Problem nicht mehr auf.

Für die Englisch-Sprechenden, da keine Lösungsansätze im Web zu finden sind:
On this page you'll find a quick and dirty solution for the advertising problem of minidnla or ushare running under OpenWrt before "attitude adjustment" or "barrier breaker" (April 2013). The servers do a udp multicast. This works not very well if not at all over a wireless connection (WLAN). See below under section "Problem Multicast über WLAN: Die Lösung!"

Streaming über das Internet

Die Verwendung eines udp Proxys erlaubt das Streaming über das Internet. Ansatz:

opkg install udpxy

Der Dienst muss noch aktiviert und gestartet werden.

/etc/init.d/udpxy enable; /etc/init.d/udpxy start

Die Firewallregeln müssen noch angepasst werden. Siehe: http://wiki.openwrt.org/doc/howto/udp_multicast