Hallo,
da der Stream meiner IP-Kamera nicht direkt (ohne Browser Plugins etc.) dargestellt werden kann
und mir eine Lösung via Interval-Snapshots nicht gefiel,
und mir der Umweg mit iSpy oder Xeoma zu Resourcen-Hungrig war,
habe ich mittels ffserver und ffmpeg eine anderen Weg gefunden.
Folgend eine Kurzanleitung für Debian 8, für Ubuntu oder Raspberry sollte es ähnlich funktionieren.
- ffmpeg installieren:
Downloadquelle für ffmpeg in /etc/apt/sources.list hinzufügen (ggf. Mirror anpassen):
deb http://ftp.at.debian.org/debian jessie-backports main
Anschließend installieren:
apt-get update
apt-get install ffmpeg
- ffserver konfigurieren:
Die Originaldatei /etc/ffserver.conf bei Bedarf sichern
und eine neue Datei /etc/ffserver.conf mit folgendem Inhalt anlegen:
HTTPPort 8090
HTTPBindAddress 0.0.0.0
MaxHTTPConnections 200
MaxClients 100
MaxBandwidth 4096
CustomLog -
########################################
# IP camera feed...
<feed ipcam1.ffm>
File /tmp/ipcam1.ffm
FileMaxSize 1M
ACL allow 127.0.0.1
</feed>
########################################
# Streams...
<stream ipcam1.mjpg>
Feed ipcam1.ffm
Format mpjpeg
VideoQMin 1
VideoQMax 4
VideoFrameRate 10
VideoSize 480x390
VideoBufferSize 1024
VideoBitRate 1024
NoAudio
Strict -1</stream>
<stream ipcam1.jpg>
Feed ipcam1.ffm
Format jpeg
Qscale 2
VideoFrameRate 2
VideoSize 704x576
VideoIntraOnly
NoAudio
NoDefaults
Strict -1</stream>
<stream status.html>
# Server status URL
Format status
# Only allow local people to get the status
ACL allow 192.168.1.0 192.168.1.255</stream>
<redirect index.html>
# Just an URL redirect for index
# Redirect index.html to the appropriate site
URL http://www.ffmpeg.org/
</redirect>
Damit wird ein mpjpeg-Stream (für Live Video) und ein einfacher jpg-Stream (für Snapshots) vorbereitet.
Diese können bei laufendem ffserver mit folgenden URL's angezeigt werden:
http://192.168.1.xxx:8090/ipcam1.mjpg
http://192.168.1.xxx:8090/ipcam1.jpg
Die IP Adresse ist Exemplarisch und muss natürlich angepasst werden!
Hier können je nach Bedarf Anpassungen vorgenommen werden, weitere Infos auf der ffmpeg Homepage.
Der ffserver status ist über folgende URL verfügbar:
http://192.168.1.xxx:8090/status.html
- ioBroker Script zum Starten/Stoppen von ffmpeg:
Ich verwende ein Javascript womit ich ffserver einmalig starte und
ffmpeg nur bei Bedarf einfach über einen State starte und stoppe um keine unnötige CPU Last zu erzeugen.
Außerdem wird ffmpeg automatisch neu gestartet wenn es unerwartet beendet wird (z.B. Stream Abbruch).
Alternativ kann man natürlich auch ffserver und ffmpeg über das Betriebssystem automatisch starten lassen.
Ich habe in meiner Kamera einen Sub-Stream als MJPEG mit einer Auflösung von 704x576 und FPS=10 konfiguriert.
Prinzipiell sollte jeder Stream funktionieren, die Performance ist jedoch mit einer niedrigen Auflösung und FPS besser.
Im folgenden Script muss nur die IP-Kamera Stream Adresse (rtsp://user:user@192.168.1.yyy:554/cam/realmonitor?channel=1&subtype=2) angepasst werden.
// **********************************************************************
// Settings
var ffserverStartCmd = "/usr/bin/ffserver &";
var ffserverStopCmd = "killall ffserver";
var ffmpegStartCmd = "ffmpeg -i \"rtsp://user:user@192.168.1.yyy:554/cam/realmonitor?channel=1&subtype=2\" http://localhost:8090/ipcam1.ffm";
var ffmpegStopCmd = "killall ffmpeg";
// **********************************************************************
// States
var path = "ffmpegCam.";
var idRun = path + "run";
createState(idRun, false, {
name: "Control ffmpeg start/stop for IP camera",
type: "boolean",
});
var idCntRestart = path + "statistics.cntRestart";
createState(idCntRestart, 0, {
name: "Count of restarts",
type: "number",
});
var idLastRestart = path + "statistics.lastRestart";
createState(idLastRestart, 0, {
name: "Last restart",
type: "string",
role: "value.datetime",
});
// **********************************************************************
// Variables
var idTimeout = null;
// **********************************************************************
// Functions
function ffserverStop() {
console.log("ffserver stop...");
exec(ffserverStopCmd, function(err, stdout, stderr) {
if (err) {
console.log("ffserver stop failed: " + stderr);
} else {
console.log("ffserver stopped: " + stdout);
}
});
}
function ffserverStart() {
console.log("ffserver start...");
exec(ffserverStartCmd, function(err, stdout, stderr) {
if (err) {
console.log("ffserver error: " + stderr);
}
});
}
function ffmpegStop() {
if (idTimeout) {
// clear existing timeout
clearTimeout(idTimeout);
idTimeout = null;
}
console.log("ffmpeg stop...");
exec(ffmpegStopCmd, function(err, stdout, stderr) {
if (err) {
console.log("ffmpeg stop failed: " + stderr);
} else {
console.log("ffmpeg stopped: " + stdout);
}
});
}
function ffmpegStart() {
if (idTimeout) {
// clear existing timeout
clearTimeout(idTimeout);
idTimeout = null;
}
console.log("ffmpeg start...");
exec(ffmpegStartCmd, function(err, stdout, stderr) {
if (err) {
console.log("ffmpeg error: " + stderr);
} else {
console.log("ffmpeg returned: " + stdout);
}
// Automatic restart if run state is set
if (getState(idRun).val === true) {
console.log("ffmpeg has exited unexpected! Restart in 30s!");
idTimeout = setTimeout(ffmpegRestart, 30000);
}
});
}
function ffmpegRestart() {
// current date and time
var dateTime = new Date().toLocaleString();
setState(idLastRestart, dateTime);
// update counter
var count = getState(idCntRestart).val;
count = count + 1;
setState(idCntRestart, count);
// ffmpeg
ffmpegStop();
ffmpegStart();
}
on({id: "javascript.0." + idRun}, function(obj) {
console.log("Run state changed from " + obj.oldState.val + " to " + obj.state.val);
if (obj.state.val === true) {
if (obj.oldState.val ===false) {
console.log("Start ffmpeg...");
ffmpegStart();
}
}
else {
console.log("Stop ffmpeg...");
ffmpegStop();
}
});
// stop
onStop(function() {
console.log("Script stopped!");
ffmpegStop();
ffserverStop();
}, 1000);
// initial start
setTimeout(start, 500);
function start() {
ffserverStart();
}
- Darstellung in vis:
Zum Anzeigen des neuen Streams einfach ein iFrame Widget einfügen,
unter den Widget-Einstellungen Allgemein/Quelle die ffserver Stream Adresse eintragen (http://192.168.1.xxx:8090/ipcam1.mjpg)
und unter CSS/Allgemein die Größe entsprechend der ffserver.conf eintragen (hier im Beispiel width=480px, height=390px).
- ffmpeg starten:
Für Testzwecke kann ffmpeg mit dem neuen State ffmpegCam.run=true gestartet und mit ffmpgeCam.run=false gestoppt werden.
Dies kann natürlich auch manuell über ioBroker.admin/Objekte/javascript.0/fffmpegCam/run erfolgen.
Ich starte/stoppe ffmpeg nur bei Bedarf über ein anderes Script welches einfach prüft, ob mein Kamera-View aktiv ist und den State entsprechend setzt.
Außerdem schalte ich beim Klingeln an der Tür automatisch auf den Kamera-View (dieser startet ffmpeg) und
erstelle von dem ffserver jpg-Stream (http://192.168.1.xxx:8090/ipcam1.jpg) drei Snapshots welche ich per E-Mail versende.
Viel Spaß damit