Synology Surveillance Station Videostream in MJPEG wandeln

eingetragen in: Synology 54

Gerade die günstigen Webcams bieten häufig keinen MJPEG Stream an. Da kann man sich glücklich schätzen, wenn man Besitzer eine Synology NAS ist. Als erstes sind die Pakete  „Surveillance Station“, „Web Station“ und „PHP 5.6 oder höher“ auf der NAS zu installieren. Anschließend ist die Webcam in der Surveillance Station einzubinden.

Bevor es aber los geht, hier kurz erklärt was MJPEG ist:

Bei Motion JPEG (MJPEG) handelt es sich um ein Videocodec, bei dem jedes Einzelbild des Videostreams separat als JPEG-Bild komprimiert im MJPEG gespeichert wird. Mann kann sich das als aneinander gereihte JPEGs in einer nicht endenden Datei vorstellen.

Sobald man die Webcam in der Surveillance Station konfiguriert hat, ist das PHP Skript auf der Webstation in dem Verzeichnis /volume1/web/ mit dem Namen webcam.php zu kopieren. Alternativ kann das PHP Script auch auf jedem anderen Webserver im Internet bzw. Intranet liegen, vorausgesetzt es besteht eine Internetverbindung zur NAS.

Nur die ersten Zeilen im Skript sind anzupassen, unter $ip ist die IP-Adresse oder der Hostname sowie unter $port der Port der NAS einzutragen. Diese Informationen werden aus Sicherheitsgründen nicht beim Aufruf des Skriptes mitgeben.

Das PHP Skript greift über die Surveillance Station WebAPI v2.0 auf den Webcam Stream der Surveillance Station zu und wandelt diesen in das MJPEG Format um und zeigt dann das MJPEG im Webbrowser. Das Bild erneuert sich alle paar Sekunden.

Das Skript folgendermaßen aufrufen:

http://webserver/webcam.php?usr=<benutzername>&pwd=<passwort>&cam=<1|2|…>&format=<mjpeg|jpeg>

 

 

Die Variablen sind wie folgt zu füllen:

Variable Wert
usr Benutzername
(am besten einen Benutzer in der Surveillance Station mit wenig Berechtigungen anlegen)
pwd Passwort (Passwort des Benutzers)
cam 1,2,3,4 oder … (die ersten konfigurierte Webam ist 1 die zweite 2 usw.)
format jpeg für eine einzelnes Bild oder mjpeg für einen jpeg Stream

 

Beispiel:

http://nas-stueben.goip.de/webcam.php?usr=thorsti&pwd=geheim&cam=2&format=mjpeg

Wer möchte kann aber auch den Variablen $user, $pass und $cameraID im Skript direkt Werte zuweisen. Dann ist das Passwort in der URL nicht sichtbar! Download

<?php

// **********************************************************************************
// Diese Beiden Werte sind ggf. anzupassen. Sonst ist nichts zu tun!
// **********************************************************************************
$ip   = "localhost"; // IP-Adresse eures Synology-NAS
$port = "5000";      // default Port der Surveillance Station
                    
// **********************************************************************************
// Anmelden an der Surveillance Station und sid zurückgeben
// **********************************************************************************
function getSid($user, $pass, $ip, $port) {
	$link_login = 'http://' . $ip . ':' . $port . '/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=3&account=' . $user . '&passwd=' . $pass . '&session=SurveillanceStation&format=sid';
	
	// Eventuell müsst ihr die URLs von HTTP auf HTTPS anpassen, sofern ihr HTTPS aktiviert habt!
	// Authentifizierung an Synology Surveillance Station WebAPI und auslesen der SID
	$json = file_get_contents ( $link_login );
	$obj = json_decode ( $json, true );
	@$sid = $obj ["data"] ["sid"];
	return $sid;
}

// **********************************************************************************
// Link für MJPEG von Surveillance Station lesen
// **********************************************************************************
function getStreamLink($user, $pass, $ip, $port, $cameraID) {
	$sid = getSid ( $user, $pass, $ip, $port );
	$link_stream = 'http://' . $ip . ':' . $port . '/webapi/SurveillanceStation/videoStreaming.cgi?api=SYNO.SurveillanceStation.VideoStream&version=1&method=Stream&cameraId=' . $cameraID . '&format=mjpeg&_sid=' . $sid;
	
	return $link_stream;
}

// **********************************************************************************
// Link für JPEG von Surveillance Station lesen
// **********************************************************************************
function getImageLink($user, $pass, $ip, $port, $cameraID) {
	$sid = getSid ( $user, $pass, $ip, $port );
	$link_image = 'http://' . $ip . ':' . $port . '/webapi/entry.cgi?camStm=1&version=8&cameraId=' . $cameraID . '&api="SYNO.SurveillanceStation.Camera"&preview=true&method=GetSnapshot&_sid=' . $sid;

	return $link_image;
}

// **********************************************************************************
// MJPEG Stream von Surveillance Station ausgeben
// **********************************************************************************
function printStream($user, $pass, $ip, $port, $cameraID) {
	$link_stream = getStreamLink ( $user, $pass, $ip, $port, $cameraID );
	
	set_time_limit ( 60 );
	
	$r = "";
	$i = 0;
	$boundary = "\n--myboundary";
	$new_boundary = "newboundary";
	
	$f = fopen ( $link_stream, "r" );
	
	if (! $f) {
		// **** cannot open
		print "error";
	} else {
		// **** URL OK
		header ( "Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0" );
		header ( "Cache-Control: private" );
		header ( "Pragma: no-cache" );
		header ( "Expires: -1" );
		header ( "Content-type: multipart/x-mixed-replace;boundary={$new_boundary}" );
		
		while ( true ) {
			
			while ( substr_count ( $r, "Content-Length:" ) != 2 ) {
				$r .= fread ( $f, 32 );
			}
			
			$pattern = "/Content-Length\:\s([0-9]+)\s\n(.+)/i";
			preg_match ( $pattern, $r, $matches, PREG_OFFSET_CAPTURE );
			$start = $matches [2] [1];
			$len = $matches [1] [0];
			$end = strpos ( $r, $boundary, $start ) - 1;
			$frame = substr ( "$r", $start + 2, $len );
			
			print "--{$new_boundary}\n";
			print "Content-type: image/jpeg\n";
			print "Content-Length: ${len}\n\n";
			print $frame;
			usleep ( 40 * 1000 );
			$r = substr ( "$r", $start + 2 + $len );
		}
	}
	
	fclose ( $f );
}

// **********************************************************************************
// JPEG Image von Surveillance Station ausgeben
// **********************************************************************************
function printImage($user, $pass, $ip, $port, $cameraID) {
	$link_image = getImageLink ( $user, $pass, $ip, $port, $cameraID );
	$image = file_get_contents ( $link_image );
	
	header ( "Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0" );
	header ( "Cache-Control: private" );
	header ( "Pragma: no-cache" );
	header ( "Expires: -1" );
	header ( "Content-type: image/jpeg" );
	header ( "Content-Length: " . ( string ) (filesize ( $image )) );
	print $image;
}

// **********************************************************************************
// Stream als MJPEG ausgeben
// http://nas-stueben.goip.de/webcam.php?usr=<benutzername>&pwd=<passwort>&cam=<1|2|...>&format=<mjpeg|jpeg>
// **********************************************************************************
$user     = $_GET ["usr"]; // Synology Benutzer mit Berechtigung die Kamera anzuzeigen
$pass     = $_GET ["pwd"]; // Passwort zu eben eingegebenem Benutzer
$cameraID = $_GET ["cam"]; // ID der Kamera, welche angezeigt werden soll
$format   = $_GET ["format"]; // format = jpeg für Image oder mjpeg für Stream

if (strtolower ( $format ) == "jpeg") {
	
	printImage ( $user, $pass, $ip, $port, $cameraID );
} else {
	
	printStream ( $user, $pass, $ip, $port, $cameraID );
}

?>

Jetzt kann man noch in dem Webstation Verzeichnis /volume1/web/ ein Unterverzeichnis webcam anlegen (/volume1/web/webcam) und dort die Datei .httaccess anlegen. Da das Passwort für den Webam Benutzer in der Datei hinterlegt ist, sollten die entsprechenden Berechtigungen für die Datei .httaccess gesetzt sein.

bis Apache 2.2:

# ********************************************************
# .htaccess bis Apache 2.2
# ********************************************************

# Nur im lokalem Netz gilt die Regel
order deny,allow 
deny from all
allow from 192.168.20.0/24 

# Regel jpg -> php bzw. mjpg -> php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^cam(.*)\.jpg$ /webcam.php?usr=<user>&pwd=<password>&cam=$1&format=jpeg [L,NC]
RewriteRule ^cam(.*)\.mjpg$ /webcam.php?usr=<user>&pwd=<password>&cam=$1&format=mjpeg [L,NC]

ab Apache 2.4:

# ********************************************************
# .htaccess ab Apache 2.4 
# ********************************************************

# Nur im lokalem Netz gilt die Regel
Require ip 192.168.20.0/24 

# Regel jpg -> php bzw. mjpg -> php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^cam(.*)\.jpg$ /webcam.php?usr=<user>&pwd=<password>&cam=$1&format=jpeg [L,NC]
RewriteRule ^cam(.*)\.mjpg$ /webcam.php?usr=<user>&pwd=<password>&cam=$1&format=mjpeg [L,NC]

 

Jetzt könnt Ihr die Webcam wie folgt aufrufen:

# Webcam 1 / Einzelbild
http://webserver/webcam/cam1.jpg
 
# Webcam 2 / Einzelbild
http://webserver/webcam/cam2.jpg 

# Webcam 1 / MJPEG Stream 
http://webserver/webcam/cam1.mjpg 

# Webcam 2 / MJPEG Stream
http://webserver/webcam/cam2.mjpg

Telefongespräche über FRITZ!Box mit SIP Client auf iPhone führen

eingetragen in: FritzBox 4

Mit der FRITZ!App Fon für das iPhone und Android kann ich mit meiner Festnetznummer auf dem Smartphone telefonieren. Auch bin ich über die Telefonnumer auf dem Smartphone erreichbar. Aus Sicherheitsgründen meldet sich die App aber nur im lokalen Netzwerk oder per VPN an der FRITZ!Box an. Die VPN Verbindung baut sich wenn das iPhone nicht genutzt wird gerne ab. Damit ist die FRITZ!App Fon keine echte Alternativer außerhalb der eigenen vier Wände.

Alternativ dazu gibt es aber die Möglichkeit, die FRITZ!Box so zu konfigurieren, das man auch über einen (VoIP) SIP-Client darauf zugreift. Ich nutze dafür die App SessionTalk die es sowohl für das iPhone als auch für Android gibt. Möglich sind aber auch ein (VoIP) SIP-Telefon oder jeder x-beliebige SIP-Client.

In der IP-Telefonie ist das SIP ein häufig angewandtes Protokoll. Es ist ein Netzprotokoll zum Aufbau, zur Steuerung und zum Abbau einer Kommunikationssitzung zwischen zwei und mehr Teilnehmern. Das Protokoll wird u. a. im RFC 3261 spezifiziert.

Konfiguration SIP Server

Die FRITZ!Box steht uns als SIP Server zur Verfügung. Die Konfiguration ist ziemlich übersichtlich. Über den Menüpunkt Telefonie -> Telefoniegerät ist ein neues Gerät anzulegen. Hier ist festzulegen welche Rufnummern bei ein- und ausgehenden Anrufen zu berücksichtigen sind. Wichtig, das ihr „Verbindung aus dem Internet“ unter Anschusseinstellungen zulässt. Damit ist die SIP Server Konfiguration auf der FRITZ!Box abgeschlossen.

sip_fritzbox1         sip_fritzbox2

Konfiguration SIP Client

Die Konfiguration der SIP Clients ist anspruchsvoller. Viele Clients verlangen eine unendliche Anzahl von Parametern. Bei einem neuen Client fülle ich im ersten Schritt nur die notwendigsten Felder aus und hangele mich langsam vor unter dem Motto „try by error“!

SIP Client Einstellungen
Name, Beschreibung oder Account Name: Fritzbox (irgendeinen Namen oder Festnetznummer hier eintragen)
Benutzername: 622 (Benutzername Telefoniegerät aus FRITZ!Box)
Passwort: geheim (Passwort Telefoniegerät aus FRITZ!Box)
Domain: fritz.box
SIP-Adresse: 622@fritz.box (<Benutzername aus FRITZ!Box>@fritz.box)
Proxy-Server / Proxy-Adresse: voip-stueben.goip.de (Deine DDNS Adresse der FRITZ!Box)
Proxy-Server Port: 5060
Outbound Proxy: – (nicht zu füllen)
Registrar / Registrierungsserver: voip-stueben.goip.de (Deine DDNS Adresse der FRITZ!Box)
STUN aktiviert: X (an)
STUN Server: stun.sipgate.net
STUN Server Port: 3478

 

SIP Client SessionTalk auf dem iPhone

Ich nutze die App SessionTalk, den es für das iPhone und das Android Smartphone gibt. Unter Einstellungen -> SIP-Konten erstellt man ein neues Konto. Hierfür wählt man „Generic SIP“ aus dem Menü aus.

Nun vergibt man bei „Account Name“ und „Name anzeigen“ irgendeinen Namen wie z.B. VoIP Home oder die eigene Telefonnummer. Unter Benutzername und Passwort gibt man den Benutzernamen und das Passwort aus der FRITZ!Box von oben ein (siehe Abschnitt Konfiguration SIP Server). Die Domain lautet fritz.box. Jetzt wechselt man in das Menü für erweiterte Einstellungen. Die Voicemail-Nr. für die FRITZ!Box  **600 (erster Anrufbeantworter). Unter Proxy-Adresse trägt man den DDNS Namen der FRITZ!Box wie z.B. voip-stueben.go-ip.de ein. Nun noch STUN und STUN 3G aktivieren und den STUN-Server den stun.sipgate.net hinterlegen.

SIP Client Zoiper auf dem iPhone

Den SIP Client Zoiper gibt es für Android, Windows Phone, Windows 10, iMac und für das iPhone. Die Konfiguration ist fast identisch zu der obigen.

Die App Zoiper öffnen, dann unter Settings -> Accounts mit dem +  Zeichen einen neuen Account hinzufügen. Die Frage „Do you already have an account (username and password)?“ mit Yes bestätigen und anschließend „Manual configuration“ auswählen.

 

SIP Client Telephone auf dem iMac

Der iMac SIP Client Telephone gibt es im Apple App Store kostenlos. Unter Accounts ist ein neuer Zugang anzulegen. Dafür unter Beschreibung und Vollständiger Name einen sprechenden Namen wie z.B. die Telefonnummer eingeben. In meinem Fall steht in beiden Feldern FritzBox. In dem Feld Domain steht fritz.box und unter Benutzername und Passwort, der Benutzername und das Passwort der FRITZ!Box von oben (siehe Abschnitt SIP Server Konfiguration). Bei den erweiterten Einstellungen, tragt ihr unter Registrierungsserver den DDNS Namen der FRITZ!Box wie z.B. voip-stueben.goip.de ein. Die SIP-Adresse kann leer bleiben oder man gibt <Benutzername>@fritz.box dort ein. Die Proxy Verbindung aktivieren und als Proxyserver den DDNS Namen der FRITZ!Box mit Port 5060 eintragen.Jetzt noch auf dem Reiter „Netzwerk“ den STUN-Server stun.sipgate.net auf Port 3478 hinterlegen und auf dem Reiter „Ton“, nur G.711 Codec verwenden aktivieren.

 

 

Telekom Entertain mit Multicast IGMPv3 Switch

eingetragen in: Allgemein 5

Telekom Entertain und IPTV

Bei Telekom Entertain (vormals T-Home Entertainment) wird das Fernsehbild nicht wie bisher üblich über Kabel übertragen sondern per IPTV. Voraussetzung zum Empfang ist eine Internetverbindung der Telekom mit entsprechender Bandbreite, da die HD Kanäle mit ca. 6 – 16 MBit/s und die SD Kanäle mit 2 – 6 MBit/s übertragen werden.

Unicast und Multicast

IPTV nutzt zwei Übertragungsvefahren, dabei werden die Datenpackete (Stream) entweder per Unicast oder Multicast übertragen. Beim Unicast wird jedem Empfänger (TV Receiver) ein individueller Datenstrom zur Verfügung gestellt. Bei Multicast werden den Empfängern (TV-Receivern) die den gleichen TV Sender empfangen, derselbe Datenstrom zur Verfügung gestellt. Telekom Entertain nutzt das Multicast Verfahren! Gegenüber Unicast hat Multicast den Vorteil, dass die Netzlast nicht proportional mit der Anzahl der Teilnehmer steigt. Vorausgesetzt nicht alle Teilnehmer schauen unterschiedliche TV Kanäle.

muliunibroadcast

Hier ein Beispiel zum verdeutlichen der Unterschiede zwischen Unicast und Multicast. Angenommen wir haben 2 TV-Receiver und es läuft auf beiden Receivern ARD HD mit 10 MBit/s. Bei Unicast benötigen wir dann eine Internet Bandbreite von 20 MBit/s, da jeder der zwei TV Receiver einen individuellen ARD HD Stream von 10 MBit/s direkt vom „TV Sender“ empfängt. Beim Multicast-Verfahren wie es die Telekom anbietet, erhalten alle TV Receiver die den gleichen TV Kanal empfangen, die selben Datenpackete und keine individuellen vom Sender. D.h. es wird eine Bandbreite von 10 MBit/s statt 20 MBit/s in unserem Beispiel benötigt.

Multicast IGMPv3 Protokoll

Telekom Entertain setzt DSL/VDSL Router und Switches voraus, die das Mulicast Protokol IGMP in Version 3 unterstützen (IGMPv3), so dass zwischen Server (TV Sender) und TV Receiver ein zielgerichtete Datenübertragung stattfindet.

Die mitgelieferten DSL/VDSL Router der Telekom unterstützen IGMPv3 natürlich, sowie die FRITZ!Box 7490. Nutzt man DSL/VDSL Router oder Switches die das Multicast Protocoll IGMPv3 nicht unterstützen geschieht folgendes. Der Multicast Stream wird in einen Broadcast Stream an dem Rourter / Switch umgewandelt. D.h. nun erhalten nicht nur die Empfänger des angeforderten Multicast  Stream die Datenpackete sondern alle Empfänger (z.B. PC, NAS, Drucker, WLAN Router) an dem Router / Switch . Früher oder Später ist dann das Netz (LAN) verstopft (überflutet) und es geht nichts mehr! Sollte noch ein WLAN Router direkt an dem nicht Multicast IGMPv3 fähigem Router / Switch hängen, beschleunigt sich das ganze noch. Nach wenigen Minuten wird das WLAN so mit Datenpacketen geflutet, das man nicht mehr im LAN arbeiten und im Internet surfen kann. Der Unmut der Familie ist vorprogrammiert 🙂

Daher ist bei der Netzwerkplanung darauf zu achten, dass die eingesetzten Router und Switches IGMPv3 fähig sind. Normalerweise schließt man den oder die TV Receiver direkt an dem von der Telekom mitgelieferten DSL/VDSL Router an. Da dieser IGMPv3 fähig ist, muss man sich keine weiteren Gedanken machen. Sollte man aber das Netz durch einen weiteren Router oder Switch erweitern, dann umbedingt ein IGMPv3 fähiges Gerät anschaffen. Leider sind die IGMPv3 Switches nicht gerade kostengünstig! Eines der wenigen erschwinglichen Geräte mit IGMPv3  ist der Netgear GS108Ev3 den man z.B. bei Amazon für ca. EUR 42 (Stand 2016) erhalten kann.

Netzwerkarchitektur zu Hause

Mein Netzwerk zu Hause sieht wie folgt aus. Der VDSL Router (FRITZ!Box 7490) steht im Keller. In jedem Zimmer ist eine Netwerkdose und ich habe 3 Telekom Entertain Receiver im Einsatz. Da nicht genug Anschüsse an der FRITZ!Box zur Verfügung stehen habe ich das Netz um zwei IGMPv3 fähige Netgear GS108Ev3 mit jeweils 8 Ports und einen „normalen“ Switch mit 16 Ports erweitert. In der Abbuldung unten sind die Multicast Verbindungen blau und die Netzwerkverbindungen die kein Multicast beherrschen rot eingezeichnet.

2015_09_28_Netzwerk_Thorsten_v2

Konfiguration Netgear GS108Ev3

Ich habe mehrere Konfigurationen am Netgear GS108Ev3 ausprobiert, wie z.B. mit Anlage eines VLANs usw. Aber am besten lief es mit einer minimal angepaßten Grundkonfiguration des Switches. Anfänglich hatte ich Artefakte oder stehende Bilder. Aber dieses war glücklicherweise mit der  Netgear Firmware Version ab 2.00.06 behoben.
Wichtig: Führt das Firmware Update nicht aus dem WLAN heraus aus! Ich durfte mir danach ein neues Gerät kaufen.

Ich gehe im folgendem nur auf die Konfiguration ein, die für IPTV mit Telekom Entertain mit IGMPv3 Mulsticasting entscheidend ist.

Ruft im Internetbrowser den Management Oberfläche des Netgear GS108Ev3 Switches auf und führt die Schritte 1 bis 3 durch.

Schritt 1

Rufe im Menü System -> Multicast -> IGMP Snooping Configuration auf. Hier sind folgende Einstellungen vorzunehmen:

 

netgear_gs108e_1

Schritt 2

Anschließend unter QoS -> Quality of Service folgende Einstellungen vornehmen:

netgear_gs108e_2

Schritt 3

Nun nur noch unter System -> Management -> Port Staus Flow Control bei mindestens allen Multicast Ports, also da wo ein TV Receiver angeschlossen ist, disablen. Ich habe es grundsätzlich bei allen Ports ausgestellt.

netgear_gs108e_3

Mit dieser Konfiguration lief es bisher am besten. Das Einzige, nach ein paar Tagen Betrieb kann ich die Netgear Management Oberfläche über den Browser nicht mehr aufrufen. Diese ist sehr langsam. Im Notfall hilft kurz den Stecker am Netgear ziehen.

Ich habe noch eine Alternativkonfiguration in einem  Blog gefunden. Da wurde folgende Einstellung empfohlen wenn z.B. an Port 1 und 2 ein Entertain Receiver hängt:

Im Reiter VLAN -> Port Based das Basic Port-based VLAN Status auf „Enable“ stellen und auf Port 1 und 2 die VLAN Group „8“ eintragen. Dann unter dem Reiter System -> Multicast eine „8“ bei „VLAN ID Enabled for IGMP Snooping“ eintragen. Bei den anderen 6 Ports unter VLAN -> VLAN Groups eine „1“ eintragen. 

Übrigens an der FRITZ!Box 7490 musste ich keine Änderungen vornehmen. Wenn Ihr zwei TV Receiver besitzt, könnt Ihr an der FRITZ!Box Eure Multicast Einstellungen überprüfen. Dafür meldet Ihr Euch an der FRITZ!Box an und geht auf Internet -> Online-Monitor. Nun stellt Ihr beide TV Receiver auf den gleichen TV Kanal und anschließend auf zwei unterschiedliche TV Kanäle ein. Ihr könnt in der Abbildung unten gut sehen wie sich auf einmal die Bandbreite verdoppelt.

fritzboxonlinemonitor

1 2 3 4 5