Streaming

Aus VDR Wiki
Wechseln zu: Navigation, Suche

Wir unterscheiden (vorläufig) vier verschiedene Anforderungen an das Streaming-Profil des Servers: 1) Live-Streaming der Fernsehkanäle, 2) Live-Streaming der Radiokanäle, 3) Aufzeichnungen, 4) Live-Streaming der Fernseh- und Radiokanäle + Aufzeichnungen.

Je nachdem, ob 1), 2), 3) oder 4) gewünscht sind, gibt es unterschiedliche Ansätze, um den Anforderungen gerecht zu werden:

Inhaltsverzeichnis

Streaming von Fernsehkanälen

Zum Streaming von Fernsehkanälen mit dem VDR wird das Streamdev-plugin (Server) in der Praxis mit folgenden Client-Playern genutzt:

Software

  • MPlayer (Linux, Windows, Mac OSX) [1]
  • Xine-Player (Linux) [2]
  • VLC (Linux, Windows, Mac OSX) [3] (am Mac für ältere Rechner empfehlenswert, sonst eher nicht [4])
  • Winamp (Windows) [5]
  • VDRMediaClient (Windows)
  • Media Player Classic (Windows) [6]

Das Streamdev-plugin kann entweder direkt über den Client-Player angesprochen werden oder aber indirekt über praktische Tools wie z.B. den Vdradmin oder den Streamingcontrol (nur für Windows).

Mit dem MPlayer kann ein Stream z.B. mit folgendem Befehl gestartet werden:

Linux:    user@client> mplayer http://192.168.0.200:3000/PES/3
Windows:  C:\Programme\mplayer\mplayer http://192.168.0.200:3000/PES/3
Mac OSX im Terminal: "/Applications/Programme/MPlayer/MPlayer OS X 2.app/Contents/Resources/mplayer.app/Contents/MacOS/mplayer" http://192.168.0.200:3000/PES/3

Die Stream URL Der Client spricht jedes einzelne Programm am VDR-Server per Netzwerk über eine einzigartige Adresse an (genau wie Internetseiten). Diese Adresse setzt sich wie folgt zusammen:


  • 192.168.0.200 = IP des VDR-Servers
  • 3000 = Port über den das Streamdev per default streamt (s. OSD|Einstellungen)
  • PES = Packetized Elementary Stream (PES) - neben MPEG-2 Transport Stream (TS), MPEG-2 Program Stream (PS) und Elementary Stream (ES)
  • 3 = Kanal-Nummer (entsprechend der Reihenfolge der Kanäle in channels.conf)
Also zusammen:
192.168.0.200:3000/PES/3

Alternativ zur Kanalnummer (die sich ja hin und wieder ändern kann) kann dem Server auch eine programmplatzunabhängige eindeutige ID übergeben werden. Diese ist identisch mit der ID, die z.B. auch tvmovie2vdr benutzt und setzt sich zusammen aus den channels.conf- Einträgen Quelle NID TID SID, jeweils durch "-" getrennt.

In diesem Fall z.B. :
http://192.168.1.100:3000/ES/C-1-1073-28214

Mit diesem Einzeiler lässt sich nach anpassen der VDR-IP usw. eine Liste der Stream-URLs für die eigene Channels.conf ausgeben:

VDRADRESS="192.168.1.190" && CHANNELSCONF="/var/lib/vdrdevel/channels.conf" && VDRPORT="3000" && STREAMTYP="PS" && cat $CHANNELSCONF | sed 's/^\([^\;]*\)[^:]*\:\([^:]*\:[^:]*\)\:\([^:]*\)\:\([^:]*\:[^:]*\:[^:]*\:[^:]*\:[^:]*\:\)\([^:]*\)\:\([^:]*\)\:\([^:]*\)\:\(.*\)$/http:\/\/'$VDRADRESS':'$VDRPORT'\/'$STREAMTYP'\/\3-\6-\7-\5\ #\ \ \1/g'

Es ist auch möglich, Senderdateien für die jeweiligen Stream-Clients zu erstellen, auf Skripte hierzu wird bei der Software verwiesen

Um einen Stream aus dem VDRAdmin direkt zu starten kann der Mplayerstarter verwendet werden. Nützliche Tools, um sich die etwas kryptische Eingabe dieser Daten im Alltag zu ersparen, sind die bereits genannten Vdradmin und Streamingcontrol, wobei der erstere plattformunabhängig über den Browser funktioniert bzw. funktionieren sollte (es aber oft nicht tut) und der letztere lediglich unter Windows (idealerweise mit dem mitgelieferten MPlayer im Verzeichnis ...\vdrtools, der aber laut Handbuch im Zipfile kein DivX streamen kann).

Linux

Eventuell muss unter Linux noch die Option -vo /dev/... zur Angabe des Geräts für Video-Output ergänzt werden (vgl. mplayer --help).

Windows

Anscheinend funktioniert das Streaming bislang unter Windows nur ansatzweise (obschon von Mal zu Mal besser) und scheint extrem davon abzuhängen, wie Plugin, Player und Tools aufeinander abgestimmt sind (vgl. [7]).

MacOSX

Wenn MPlayer nicht aus dem Programm heraus streamt gibt es noch die Moeglichkeit, ihn direkt aus dem Terminal zu starten. Ueber die Optionen ist es z.B. auch moeglich, auf einem vergleichsweise langsamen G3 ab ca. 500MHz Streams darzustellen (hierzu helfen Optionen wie: "-cache 8192 -framedrop", skaliert werden kann da Bild um 50% z.B. "-xy 0.5"). Es ist zu beachten, dass ggf. der etwas kryptische Pfad in die Resourcen des Programms angegeben werden muss. Das kann jedoch durch einen Symlink vereinfacht werden - je nach Version z.B. als Admin über

sudo ln -s /Applications/Programm/MPlayer/MPlayer\ OS\ X\ 2.app/Contents/Resources/mplayer.app/Contents/MacOS/mplayer /usr/bin/mplayer

Die Ausgabe erfolgt dann aus dem Terminal unter:

mplayer http://192.168.1.200:3000/PS/1

Eine Alternative v.a. für ältere Rechner stellt ein aktueller VideoLanClient (VLC) dar. Die Version 0.8.4 spielt bspw. bereits an einem G3 333MHz unter leichtem Ruckeln aber artefaktfrei ab - deutlich besser als mit einem aktuellen MPlayer. Im Netzwerkpfad muss für Fernsehsender der Program Stream (PS)abgefragt werden, für Radiosender der Elementary Stream (ES). Die URL in VLC lautet also für Fernsehbilder:

http://192.168.1.200:3000/PS/1

Radio:

http://192.168.1.200:3000/ES/56

Streaming von Radiokanälen

DVB-Radio Playlist per mt-daapd
DVB-Radio Playlist lokal per XML


Für das Streaming von Radiokanälen muss man die URL (s.o.) in ein Streaming-Programm eingeben. Leider funktioniert das nicht mit allen Programmen, da viele wohl Video-Daten erwarten. Anders als bei TV-Streams sollte man den ES-Streamtyp verwendensonst tritt oft Knacken auf oder es bleibt ganz still.

In der URL kann man entweder direkt ein Programm über die Kanalnummer ansprechen (hier Kanal "45")

http://192.168.1.100:3000/ES/45

oder aber anhand einiger Werte aus der channels.conf (Format: Quelle-NID-TID-SID):

http://192.168.1.100:3000/ES/C-1-1073-28214

Die Kanalnummer ändert sich gegebenenfalls, weswegen die sicherere aber weniger intuitive Variante die IDs aus der channels.conf sind. Um das etwas handlicher zu gestalten anbei zwei Skripte, die einem die Arbeit für alle Radiokanäle abnehmen und automatisch Playlisten aller Radiosender erstellen. Eine schnelle übersicht der jeweiligen Adressen aller Radiosender bringt im Terminal ein:

cat /etc/vdr/channels.conf | egrep '^[^:]*\:[^:]*\:[^:]*\:[^:]*\:[^:]*\:0.*' | sed 's/^\([^\;]*\)[^:]*\:\([^:]*\:[^:]*\)\:\([^:]*\)\:\([^:]*\:[^:]*\:[^:]*\:[^:]*\:[^:]*\:\)\([^:]*\)\:\([^:]*\)\:\([^:]*\)\:\(.*\)$/ http:\/\/TYPE_YOUR_IP_HERE:3000\/ES\/\3-\6-\7-\5 #\1/g' 

Leider werden Sendernamen mit Umlauten bislang nicht korrekt dargestellt.

Programme für Audio-Streams

  • VLC (getestet unter MacOSX)
  • MPlayer (getestet unter MacOSX)
  • iTunes (getestet unter MacOSX)
  • RealPlayer (getestet unter MacOSX)

ggf. ist eine Aktualisierung erforderlich da das Streamen von Audiodaten mit alten Versionen nicht sauber lief

Streamen zu iTunes über mt-daapd-Server

MT-Daapd, der Linux-iTunes-Server, akzeptiert auch URLs von MPEG-Streams als Tracks. Hierzu wird für jeden Sender eine eigene Datei mit der Endung ".url" benutzt, in der sich v.a. die URL des Streams befindet (Einzelheiten auf der Entwicklerseite, s.u.). Die Bitrate (erste Bereich vor dem Komma) kann man weglassen, dann sieht so eine Datei in etwa so aus:

Datei
swr2.url
,SWR2, http://192.168.1.190:3000/ES/C-1-1073-28214


Das folgende Skript erstellt automatisch aus der vorhandenen channels.conf die *.url-Dateien für den mt-daap Server - damit ist das iTunes Streamen von jedem Rechner im Netz möglich. Allerdings hat dies bisher nur mit iTunes >4 geklappt, wobei man berücksichtigen sollte, dass mt-daapd 0.2.1 noch inkompatibel zu iTunes5 ist - das wurde endgültig mit mt-daapd 0.2.3 behoben.

Es werden in dem angegebenen Verzeichnis Dateien 1.url, 2.url usw. erzeugt - in iTunes selbst erscheinen aber die Sendernamen.

Datei
build_mtdaap_radio.pl
#!/usr/bin/perl -w
use strict;

# ------------------------------------------------
# initial vars: configure here !
# ------------------------------------------------
my $channels="/etc/vdr/channels.conf";
my $baseurl="192.168.1.100";
my $port="3000";
my $musicbaseurl="/musik/radiochannels";    # DIRECTORY MUST ALREADY EXIST!



# ------------------------------------------------
# no need to configure below (hope so...)
# ------------------------------------------------
my $stationnr=0;
my $shellcommand='';
my $shelloutput='';
my @radiostation=();
my @output_row=();

$shellcommand ='cat '.$channels.' | ';
$shellcommand .= 'egrep \'^[^:]*\:[^:]*\:[^:]*\:[^:]*\:[^:]*\:0.*\' |';
$shellcommand .= 'sed \'s/^\([^\;]*\)[^:]*\:\([^:]*\:[^:]*\)\:\([^:]*\)\:\([^:]*\:[^:]*\:[^:]*\:[^:]*\:[^:]*\:\)\([^:]*\)\:\([^:]*\)\:\([^:]*\)\:\(.*\)$/ http:\/\/'.$
baseurl.':'.$port.'\/ES\/\3-\6-\7-\5 #\1/g\' ';
$shelloutput=`$shellcommand`;
printf $shellcommand;
if ($shelloutput) {
        @output_row=split ( /\n/, $shelloutput);
        foreach (@output_row) {
                $stationnr++;
                @radiostation=split ( /#/, $_);
                open(DATEI, ">".$musicbaseurl."/".$stationnr.".url") || die "Datei nicht gefunden";
                print DATEI ','.$radiostation[1].','.$radiostation[0];
                close(DATEI);
        }
}


Es muss jetzt nur noch in der mt-daapd.conf ".url" als gültige Dateierweiterung eingetragen werden und - so gewünscht - in die Smartplaylist alle DVB-Radiosender eingefügt werden (in der mt-daapd.playlist):

"Streaming Audio" {
           type includes "URL"
}


Erstellen einer iTunes Playlist mit den VDR-Radiokanälen

Wer keinen mt-daap-Server laufen hat, aber trotzdem von allen Clients im Netz per iTunes auf DVB-Radio zugreifen will, der kann sich auch eine statische Playlist mit der URL bauen. Das funktioniert auch schon mit iTunes4.

Mit diesem Skript wird eine iTunes-kompatible XML-Playlist erstellt, die nur noch in iTunes importiert werden muss:

Datei
build_itunes_dvb_playlist.pl
#!/usr/bin/perl -w
use strict;

# ------------------------------------------------
# initial vars: configure here !
# ------------------------------------------------
my $channels="/etc/vdr/channels.conf";
my $baseurl="192.168.1.100";
my $port="3000";
my $playlistpath="/musik/";    # MUST ALREADY EXIST!
my $playlistfile="dvbstreams.xml";
my $playlistname="DVB Radio-Streams";

# ------------------------------------------------
# no need to configure below (hope so...)
# ------------------------------------------------
my $stationnr=time();
my $shellcommand='';
my $shelloutput='';
my @radiostation=();
my @output_row=();
my $playlistheader='';
my $playliststation='';
my $playlistfooter='';
my $playlistsum='';

$shellcommand ='cat '.$channels.' | ';
$shellcommand .= 'egrep \'^[^:]*\:[^:]*\:[^:]*\:[^:]*\:[^:]*\:0.*\' |';
$shellcommand .= 'sed \'s/^\([^\;]*\)[^:]*\:\([^:]*\:[^:]*\)\:\([^:]*\)\:\([^:]*\:[^:]*\:[^:]*\:[^:]*\:[^:]*\:\)\([^:]*\)\:\([^:]*\)\:\([^:]*\)\:\(.*\)$/'.$baseu
rl.':'.$port.'\/ES\/\3-\6-\7-\5#\1/g\' ';
$shelloutput=`$shellcommand`;
open(DATEI, ">".$playlistpath."/".$playlistfile) || die "Datei nicht gefunden";

$playlistheader.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
$playlistheader.='<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'."\n";
$playlistheader.='<plist version="1.0">'."\n";
$playlistheader.='<dict>'."\n";
$playlistheader.='<key>Major Version</key><integer>1</integer>'."\n";
$playlistheader.='<key>Minor Version</key><integer>1</integer>'."\n";
$playlistheader.='<key>Application Version</key><string>4.7.1</string>'."\n";
$playlistheader.='<key>Music Folder</key><string></string>'."\n";
$playlistheader.='<key>Library Persistent ID</key><string></string>'."\n";
$playlistheader.='<key>Tracks</key>'."\n";
$playlistheader.='<dict>'."\n";

print DATEI $playlistheader;
if ($shelloutput) {
        @output_row=split ( /\n/, $shelloutput);
        foreach (@output_row) {
                $stationnr++;
                @radiostation=split ( /#/, $_);
                $playliststation.='<key>'.$stationnr.'</key>'."\n";
                $playliststation=' <dict>'."\n";
                $playliststation.='<key>Track ID</key><integer>'.$stationnr.'</integer>'."\n";
                $playliststation.='<key>Name</key><string>'.$radiostation[1].'</string>'."\n";
                $playliststation.='<key>Kind</key><string>MPEG-Audio-Stream</string>'."\n";
                $playliststation.='<key>Date Added</key><date>2005-09-24T15:02:16Z</date>'."\n";
                $playliststation.='<key>Bit Rate</key><integer>320</integer>'."\n";
                $playliststation.='<key>Sample Rate</key><integer>48000</integer>'."\n";
                $playliststation.='<key>Play Count</key><integer>4</integer>'."\n";
                $playliststation.='<key>Play Date</key><integer>-1084540920</integer>'."\n";
                $playliststation.='<key>Play Date UTC</key><date>2005-09-24T15:06:16Z</date>'."\n";
                $playliststation.='<key>Track Type</key><string>URL</string>'."\n";
                $playliststation.='<key>Location</key><string>'.$radiostation[0].'</string>'."\n";
                $playliststation.='</dict>'."\n";
                $playlistsum.='<dict>'."\n";
                $playlistsum.='<key>Track ID</key><integer>'.$stationnr.'</integer>'."\n";
                $playlistsum.='</dict>'."\n";
        print DATEI $playliststation;
        }
        $playlistfooter.= '</dict>'."\n";
        $playlistfooter.= '<key>Playlists</key>'."\n";
        $playlistfooter.= '<array>'."\n";
        $playlistfooter.= '<dict>'."\n";
        $playlistfooter.= '<key>Name</key><string>'.$playlistname.'</string>'."\n";
        $playlistfooter.= '<key>Playlist ID</key><integer>100258'.$stationnr.'</integer>'."\n";
        $playlistfooter.= '<key>Playlist Persistent ID</key><string>98E7F981487EBA3C</string>'."\n";
        $playlistfooter.= '<key>All Items</key><true/>'."\n";
        $playlistfooter.= '<key>Playlist Items</key>'."\n";
        $playlistfooter.= '<array>'."\n";
        $playlistfooter.= $playlistsum;
        $playlistfooter.= '</array>'."\n";
        $playlistfooter.= '</dict>'."\n";
        $playlistfooter.= '</array>'."\n";
        $playlistfooter.= '</dict>'."\n";
        $playlistfooter.= '</plist>'."\n";
        print DATEI $playlistfooter;
        close(DATEI);
}


Links zu iTunes DVB-Stream

[1] http://wiki.mt-daapd.org/wiki/Streaming_Audio mt-daapd Seite über MPG-Streaming
[2] http://www.vdr-portal.de/board/thread.php?postid=379755#post362530 Diskussionsfaden hierzu im vdr-portal

Streaming von Aufzeichnungen

Anscheinend kann man über das streamdev-plugin keine Aufzeichnungen streamen, aber der Aufruf dürfte wegen des Pfades ohnehin ziemlich umständlich sein. Die einfachsten Lösungen beruhen daher auf Freigaben. Wenn man den Film als Ganzes ansehen möchte, legt man zuvor im entsprechenden Verzeichnis des VDR-Servers mit folgendem Befehl ganz einfach eine Gesamtdatei an:

cat 001.vdr 002.vdr 003.vdr > all.vdr

Ein klein wenig Geduld ist (je nach Rechner) allerdings erforderlich, denn es geht in der Regel um mehrere Gigabytes, die da zusammenkopiert werden müssen.

Unter Linux

Einfacher als der umständliche Aufruf des langen Pfades einer Aufzeichnung dürfte es sein, auf dem Linux-Client einen VDR als Client aufzusetzen und über diesen die Aufgabe zu erledigen (vgl. Streamdev-plugin). Ein schön illustriertes Beispiel hierfür gibt peter_weber69 auf seiner VDR-Homepage (vgl. auch weiter unten). Als Grundlage kann Kanotix - VDR Live CD verwendet werden. Selbstverständlich würde es auch eine NFS-Freigabe tun - nur hat obige Lösung den Vorteil, dass (fast?) die komplette Funktionalität des VDRs zu Verfügung steht.

Unter Windows

Der einfachste Weg unter Windows geht über eine Samba-Freigabe. Sodann bietet es sich an, die Extension .vdr dem MPlayer zuzuordnen - und schon genügt ein Doppelklick auf die Datei, um die Wiedergabe per MPlayer zu starten.

Selbe Vorgehensweise für den VDRMediaClient (Windows).

Streaming von Fernsehen und Aufzeichnungen

Zur klassischen VDR-to-VDR-Lösung mit dem Streamdev-plugin gibt es eine interessante Alternative, bei der das Xine-plugin zum Einsatz kommt.

Datei:VDR2Xine.jpg
Thanks to Peter Weber

Konzeption

Diese Server-Client-Lösung basiert auf folgender Konzeption:

VDR-Server

  • VDR
  • xine-plugin
  • xine-lib

Client

  • Xine-Player (= xine-lib + xine-ui)

Vor- und Nachteile

+ auf dem Client braucht kein VDR zu laufen; es genügt lediglich ein speziell gepatchter Xine-Player

+ auf dem Client steht die volle Funktionalität des VDRs zu Verfügung (inkl. OSD)

- die Installation der Xine-Komponenten (xine-lib und xine-ui) ist wegen diverser Abhängigkeiten alles andere als trivial

Installationsanleitung

Eine detaillierte Anleitung, wie diese Streaming-Lösung erfolgreich installiert werden kann, findet sich hier bzw. unter den Links.

Links