Mediaserver

Im Keller verrichtet ein DELL Server mit VDR und PLEX auf Basis Ubuntu seinen Dienst als zentraler Mediaserver. Das funktioniert gut, wenn man ein paar Dinge berücksichtigt, über die ich in diesem Post berichten werde. Meine Anfänge mit VDR liegen schon über mehr als 15 Jahre zurück und über die Zeit habe ich die Robustheit von VDR schätzen gelernt.

Es gab deshalb bisher keinen Grund für einen Wechsel und in Anbetracht der wachsenden Verfügbarkeit von Online-Festplatten, Sender-Mediatheken und Streaming-Anbietern wie Netflix, stellt sich für mich eher die Frage, ob ich einen eigenen Videorecorder und Mediaserver im Keller zukünftig überhaupt noch brauche. Manch einer von euch wird das heute schon verneinen.

PLEX Web Frontend

PLEX kam etwas später hinzu, nachdem ich XBMC/KODI den Rücken gekehrt hatte. Die Software basiert auf dem Client-Server Prinzip und glänzte mit einem sehr guten Transcoding. Die Zeit der ruckelnden Video-Streams war vorbei. Alle hier beschriebenen Funktionen sind mit der kostenfreien Version von PLEX möglich.

Einen Schwachpunkt hatte (und hat wahrscheinlich immer noch) diese Kombination aus VDR und PLEX. Es gibt keine schöne Integration. Dafür habe ich eine Lösung auf Basis der VDR hooks gefunden, die ich euch hier vorstelle.

Wenn ihr das auch umsetzen möchtet, benötigt ihr einen minimalen Ubuntu-Server oder auch Debian + eine DVR-Karte oder -Box für die Aufnahmen, die vom VDR unterstützt wird.

https://wiki.ubuntuusers.de/Minimalinstallation/

Alternativ geht auch jede Standardinstallation, je nach präferierter Hardware. Bei mir ist es ein DELL Power Edge T20 Minitower Server Xeon E3-1225V3 mit 4 GB RAM, TWIN-SAT Karte für die VDR Aufnahmen und ein paar Festplatten. Im Betrieb verbraucht er ca. 60W.

VDR

Vor der Installation prüft ihr, ob die DVR-Hardware durch Linux erkannt wurde. Wenn es eine Karte ist:

sudo lspci

Dann erfolgt die Basisinstallation von VDR recht simpel mit

sudo apt-get install vdr

Weiterführende Informationen findet ihr im Internet z.B. im Wiki von ubuntuusers

https://wiki.ubuntuusers.de/Archiv/VDR/

Server schlafen legen und wieder aufwecken

Die Serververbrauch summiert sich im 7/24 Betrieb auf einen Betrag, der vermeidbar ist. Meine Empfehlung: Verwendet rtcwake, um den Server schlafen zu legen, solange er nicht gebraucht wird. Infos findet ihr z.B. bei ubuntuusers

https://wiki.ubuntuusers.de/rtcwake/

Ob eure Hardware ACPI unterstützt, findet ihr mit folgendem Befehl heraus. Ggfl. müsst ihr BIOS Einstellungen ändern. Jede neuere Hardware sollte ACPI unterstützen.

sudo dmesg | grep ACPI

Zwei Auslöser starten den Server wieder

  • Der ins BIOS geschriebene Timer des VDR für die nächste Aufnahme
  • Der manuelle Start über ein Dashboard in Home Assistant – siehe Post im Blog

So geht’s:

  • VDR Parameter für automatischen Shutdown konfigurieren, je nach VDR Version kann das unterschiedlich sein
  • shutdown-hook verwenden, um vor dem Shutdown den Timer ins BIOS zu schreiben

Den shutdown-hook für das Setzen des Timers setzt ihr an das Ende der Liste (höchste Nummer im Namen verwenden) von Skripten, die vor dem Shutdown ausgeführt werden sollen. Mein Skript sieht so aus. Für PLEX kommen später noch weitere Skripte hinzu..

#! /bin/sh
#
# S80.RTC-wake         Shutdown-Hook fuer vdr
# Setzt den naechsten Zeitpunkt zum Neustart des Servers
# Verwendet rtcwake anstelle des älteren nvram-wakeup
#
sudo rtcwake -m no -t $(($1 - 300)) > /dev/null
if [ $? -eq 0 ]; then
	logger -i "Aufwachzeit für den VDR gesetzt"
else
	logger -i "Fehler beim setzen der Aufwachzeit"
fi
exit 0
#
# EOF

VDR-Live

Listenübersicht in VDR Live

VDR-Live nutze ich für die Programmierung des Videorecorders. Eine der leistungsfähigsten Funktionen des VDR ist der Suchtimer. Ihr gebt heute einen Suchbegriff ein und wenn der Suchtimer irgendwann in der Zukunft in den EPG-Daten der Sender was findet, nimmt er die Sendung automatisch auf. Selbst das Löschen alter Aufnahmen übernimmt VDR regelbasiert – ist schon cool. Ich verirre mich nur noch ca. 3x/Monat auf das VDR-Live Web Frontend, weil alles automatisch läuft.

Tipp: Wer ein iPad sein eigen nennt, kann die TV Primetime App nutzen, um VDR Aufnahmen direkt zu programmieren. Vor einiger Zeit hatte ich das ausprobiert – hat funktioniert. Sehr gute Lösung. Leider habe ich für Android nichts vergleichbares gefunden.

PLEX

Als eigentliches Frontend verwende ich PLEX, je nach Hardware per Browser oder App auf Fire TV und Co. Informationen zur Grundinstallation findet ihr im Web, z.B. bei ubuntuusers

https://wiki.ubuntuusers.de/Plex_Media_Server/

Die Konfiguration erledigt ihr sehr intuitiv per Browser.

Wenn ihr dann alle Filme, Serien, Urlaubsfotos und die komplette Musiksammlung in PLEX verfügbar gemacht habt, ist noch ein Link zu den VDR Aufnahmen des Videorecorders herzustellen. Leider packt der VDR alle Aufzeichnungen in Unterverzeichnisse und benennt die eigentlichen Aufnahmen immer gleich. Wenn ihr in PLEX das VDR-Aufnahmeverzeichnis hinzufügt, könnt ihr damit deshalb wenig anfangen.

Das Problem ist mittels der recording-hooks lösbar. Diese hooks werden für Aufnahmen ausgeführt

  • vor dem Start
  • nach dem Ende
  • wenn editiert
  • und wenn die Aufnahme gelöscht wurde

Die Idee: In einem Unterverzeichnis wird nach Aufnahmeende ein Link auf die VDR Aufnahme erzeugt, der den Titel und Untertitel der Aufnahme im Link-Namen hat. Das Unterverzeichnis wird in Plex eingebunden.

Links der VDR Aufnahmen in PLEX

Das verwendete Skript führt folgende Schritte aus

  • Aufnahmedatum ermitteln
  • Aufnahmetitel aus den VDR Informationen lesen
  • Prüfen ob auch ein Untertitel vorhanden ist und falls ja den Untertitel lesen
  • Link mit Datum und Titel/Untertitel im PLEX Verzeichnis erzeugen

Skript Recording-hook: Link-to-plex

#
# Custom VDR Recording Action Hook
# ----------------------------------
#
#
# R60.Link-to-plex>
# Da vdr als Namen der Aufzeichnung nur 00001.ts verwendet, wird der Name der Aufzeichnung in Plex nicht angezeigt. 
# Um eine doppelte Datenhaltung zu vermeiden, wird vom Plex-Verzeichnis aus ein symbolischer Link mit dem Namen und (falls vorhanden) Untertitel gesetzt.
#
#
# Two parameters are passed:
#
# Parameter 1 can have the values "before", "after" and "edited", depending
# on whether the recording hook is called before the recording starts,
# after the recording ends or after the recording has been edited.
#
# Parameter 2 is the directory of the recording. Be aware, that this directory 
# doesn't exist before the recording starts.
#

case $1 in
    before)
        # do here whatever you would like to do right BEFORE
        # the recording $2 STARTS
        ;;
    started)
        # do here whatever you would like to do right AFTER
        # the recording $2 STARTED
        ;;
    after)
        # do here whatever you would like to do right AFTER
        # the recording $2 ENDED
    # Verzeichnis, in dem der symbolische Link angelegt werden soll
    PLEXDIR=/mnt/media3/videorecorder
    # dann wird der Tag ermittelt
    DayRecording=$(date +'%Y-%m-%d')
    # Im Recording-Dir wird in der Datei info nach der 1. Zeile (-m 1), die mit T beginnt, gesucht
    # Danach wird der Anfang der Zeile (T mit einem Leerzeichen) ausgeschnitten
    # Danach werden alle Leerzeichen durch _ ersetzt
    # Danach werden alle Zeichen gelöscht, die nicht alphanumerisch sind oder _ -  entsprechen
    TITEL=$(grep -m 1 ^T $2/info | sed s/"T "//g | sed s/" "/"_"/g | tr -c -d '[:alnum:]_-')
    # Der Subtitel (S) wird ebenfalls gesucht, ist aber nicht immer vohanden
    grep ^S $2/info > /dev/null
    if [ $? -eq 0 ]; then
	# die Suche war erfolgreich
	logger -i "Füge den Untertitel zur Aufnahme hinzu"
	# der Subtitel wird ermittelt
	SUBTITEL=$(grep -m 1 ^S $2/info | sed s/"S "//g | sed s/" "/"_"/g | tr -c -d '[:alnum:]_-')
	# der Name der Videodatei - bestehend aus Datum + Titel + Subtitel wird zusammen gesetzt
	FILENAME=`echo $DayRecording-$TITEL-$SUBTITEL`
	# der Link vom Plexverzeichnis wird auf die Aufzeichnung gesetzt
	# Hinweis: Damit das funktioniert, sollte nur eine .ts Datei vorhanden sein - bitte den Parameter für die max File-Größe in der setup vdr setzen.
	ln -s $2/00001.ts $PLEXDIR/$FILENAME.ts
    else
	# es wurde kein Untertitel gefunden
	logger -i "für die Aufnahme ist kein Untertitel verfügbar"
	# der Name der Videodatei - bestehend aus Datum + Titel wird zusammen gesetzt
	FILENAME=`echo $DayRecording-$TITEL`
	ln -s $2/00001.ts $PLEXDIR/$FILENAME.ts
    fi
    if [ $? -eq 0 ]; then
	logger -i "Symbolischer Link für Plex angelegt"
    else
	logger -i "Beim Anlegen des symbolischen Link für Plex ist ein Fehler aufgetreten"
    fi
        ;;
    edited)
        # do here whatever you would like to do right AFTER
        # the recording $2 has been EDITED
        # $3 is the original recording
        ;;
    deleted)
        # do here whatever you would like to do right AFTER
        # the recording $2 has been DELETED
        ;;
esac

Das Löschen von Aufnahmen erfolgt, wie weiter oben beschrieben, automatisch oder per VDR-Live Web Frontend. Übrig bleibt ein verwaister Link in PLEX, was unschön ist. Ihr könnt das über ein recording-hook für jede einzelne Aufnahme lösen. Robuster hat sich für mich die Verwendung eines shutdown-hook erwiesen, der vor dem weiter oben genannten wakeup Skript eingefügt wird.

Skript shutdown-hook: symbolic-link-maintenance-plex

#! /bin/sh
#
# S10.symbolic-link-maintenance-plex         Shutdown-Hook fuer vdr
# entfernt alle toten symbolischen Links, die nach dem löschen der Aufnahmen noch im Videorecorder-Verzeichnis von Plex  vorhanden sind
#
#
find /mnt/media3/videorecorder/ -type l -follow -exec rm {} \;
# EOF

Damit wir immer vor dem Runterfahren des Servers das PLEX Verzeichnis auf verwaiste Links geprüft und diese gelöscht — schön aufgeräumt. 😉

Jetzt bleibt noch ein Problem zu lösen. Der VDR fährt automatisch runter, wenn er meint, dass er nix mehr zu tun hat und wacht automatisch für die nächste Aufnahme wieder auf. Das ist schon mal sehr gut. Allerdings stört es doch sehr, wenn er auf die Idee kommt den Server mitten im besten Filmabend herunterzufahren, nur weil er keine Info über laufende PLEX Streams hat. Deshalb sind noch eine paar shutdown-hooks notwendig, die wiederum vor dem wakeup-Skript ausgeführt werden.

Diese Skripts verhindern das Herunterfahren des Servers, wenn noch

  • Medieninhalte gestreamt werden
  • Medien umgewandelt werden (transcode)
  • TCP Verbindungen des Servers den Status „Verbunden“ haben

Shutdown-hooks

aktive PLEX Streams

#! /bin/sh
#
# S50.plex         Shutdown-Hook fuer vdr
# Prüft, ob Mediaserver Plex noch Inhalte streamt
#
#
curl -s http://127.0.0.1:32400/status/sessions | grep 'MediaContainer size="0"' > /dev/null
if [ $? -eq 0  ]; then
	logger -i "Shutdown ok - Plex Mediaserver aktuell nicht aktiv"
	exit 0
else
	logger -i "Shutdown abgebrochen - Plex Mediaserver streamt noch Inhalte - siehe auch Plex-Web-Client unter Status"
	exit 1
fi
# EOF

laufendes Transcoding

#! /bin/sh
#
# S51.plex         Shutdown-Hook fuer vdr
# Prüft, ob Mediaserver Plex noch Inhalte umwandelt (transcode)
#
#
curl -s http://127.0.0.1:32400 | grep 'transcoderActiveVideoSessions="0"' > /dev/null
if [ $? -eq 0  ]; then
	logger -i "Shutdown ok - Plex Mediaserver nicht aktiv"
	exit 0
else
	logger -i "Shutdown abgebrochen - Plex Mediaserver wandelt noch Inhalte um (transcode) - siehe auch im Plex-Web-Client unter Status"
	exit 1
fi
# EOF

aktive TCP Verbindungen

#! /bin/sh
#
# S70.test-netstat         Shutdown-Hook fuer vdr
# Prüft, ob es aktive Verbindungen zum Server gibt.
#
netstat | grep tcp | grep VERBUNDEN > /dev/null
if [ $? -eq 0  ]; then
	logger -i "Aktive Verbindungen (tcp - Status VERBUNDEN) zum Server gefunden - Shutdown wird abgebrochen!"
	exit 1
else
	logger -i "Keine aktiven Serververbindungen gefunden" 
fi
exit 0
#
# EO

Fazit: VDR und PLEX kann man im Team zusammenspielen lassen. Alternativ könnt ihr die DVR Funktion (kostenpflichtig) von PLEX nutzen oder euch mit Alternativen wie emby beschäftigen. Bei beiden habe ich noch nicht die wakeup Funktion zum Energiesparen gefunden – wobei emby wohl auch hooks unterstützt. KODI wäre nach vielen Jahren vielleich auch wieder einen Blick wert. Da wird sich hoffenlich was in Richtung Client-Server Ansatz verbessert haben.