Webcam Technik

Zu der Technik der Webcam.

Irgendwie wollte ich so was schon immer einmal machen. Nur was soll man da zeigen? Den Himmel, die Straße, den Garten? Überall die Gefahr das man jemanden mit aufnimmt dessen Persönlichkeitsrecht man dabei verletzt. Da kam mir das Projekt von Anja wie gerufen. 🙂 Die Garnelen werden sich nicht beschweren – will ich doch hoffen. 😀

Links seht ihr (wenn ihr keinen Adblocker (Werbefilter) aktiv habt) welche Webcam ich mir dafür ausgesucht habe. Gut fand ich an ihr, dass sie recht viele Möglichkeiten (Upload per FTP, HTTP (HTTP-PUT – nicht zu empfehlen ohne Webdav), eMail und Stream) bietet, das Bild zu veröffentlichen. Die Trigger kann man entweder durch Bewegung, einem externen Sensor oder einen Timer steuern. Ich habe einen Timer von 1 Minute gewählt der für den Zeitraum, in dem auch Licht im Cube eingeschaltet ist, läuft. Die so aufgenommenen Bilder werden per FTP auf einen FTP-Server geladen. Leider kann die Kamera kein SSL (FTPS), weshalb ich nicht direkt auf die Blog-Seite gehe. Der Weg ist so zwar etwas komplizierter aber ich möchte keine unnötigen unverschlüsselten Verbindungen zu dem Server zulassen. Daher lege ich die Bilder der Webcam auf einen offenen FTP-Server auf dem sonst auch nichts weiter liegt als das Bild. Von dort hole ich mir dann das Bild per SCP auf den Server, auf dem das Blog installiert ist. Da die Webcam immer zur vollen Minute ein Bild auf den FTP-Server lädt, hole ich es immer 10 Sekunden später wieder ab.

Um nun die Bilder auf der Seite automatisch neu zu laden, habe ich mir erst überlegt, mein Lieblings JavaScript-Framework „jQuery“ zu verwenden, mich dann aber dagegen entschieden. Zum einen wollte ich selber mal wieder mit dem DOM herum basteln und zum anderen muss man ja auch kein riesiges Framework mit schleppen, wenn es nur um 2-3 Funktionen daraus geht.

Hier also noch das Script für das aktualisieren des Bildes (rechts scrollen):

/***
Copyright 2011 Alexander Palm | http://www.alexander-palm.de/

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
***/
var timer1, timer2, timer3;
var errorcount=0;
var ReloadTimeout=60;
var HideTimeout=3;
var OnlineText  = '.... Bild wird aktualisiert ....';
var OfflineText = 'Das Licht im Cube ist gerade aus, daher findet keine Aktualisierung statt.';
var WebCamImage = document.images['WebCamGarnelen'];

var debug = 0;
var debugwindow;

var iebody    = (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body;
var docwidth  = (window.innerWidth)  ? window.innerWidth  : iebody.clientWidth;
var docheight = (window.innerHeight) ? window.innerHeight : iebody.clientHeight;

function compare_to_now(mytime) {
  //  1 = Uebergebene Zeit ist groesser als aktuelle Zeit
  //  0 = Zeiten sind gleich
  // -1 = Uebergebene Zeit ist kleiner als aktuelle Zeit
  
  var jetzt = new Date();
  var tocomp = new Date(jetzt.getFullYear(), jetzt.getMonth(), jetzt.getDate(), mytime.substr(0,2), mytime.substr(3,2), 0 );

  if (jetzt > tocomp)
  	return -1;
  if (jetzt < tocomp)
  	return 1;
  
  return 0;  
}

function writelog(txt){
	if(typeof window.console != 'undefined'
    && typeof window.console.log != 'undefined'){
		console.log('webcam.js:' + txt);
	} else if ( debug == 1 ) {
		if (!debugwindow) {
			debugwindow = window.open('', "Debug", "left="+(docwidth / 2)+",top="+(docheight/2)+",scrollbars=yes,resizable=yes");
			debugwindow.document.open();
			debugwindow.document.write('\\n\\n\\n\\n\\n

Debugausgaben

\\n'); } debugwindow.document.write('webcam.js:' + txt + "

\\n"); debugwindow.scrollTo(0,debugwindow.innerHeight); debugwindow.focus(); } } function showLoadImage(TextToShow) { var LoadText = document.getElementById('CamLoadInfo'); writelog('show the loadinfo....'); LoadText.firstChild.nodeValue = TextToShow; writelog('text is set to: ' + LoadText.firstChild.nodeValue); LoadText.setAttribute('style', 'visibility:visible;color:red;text-align:center;'); writelog('style-attribute of ' + LoadText.getAttribute('id') + ' is set to: ' + LoadText.getAttribute('style')); } function hideLoadImage() { var LoadText = document.getElementById('CamLoadInfo'); writelog('hide the loadinfo....'); LoadText.setAttribute('style', 'visibility:hidden;color:red;text-align:center;'); writelog('style-attribute of ' + LoadText.getAttribute('id') + ' is set to: ' + LoadText.getAttribute('style')); clearTimeout(timer3); } function checkImage() { writelog('checkImage called ' + ++errorcount + ' times'); if (!WebCamImage.complete) { timer1 = setTimeout('checkImage()', 1000); if (errorcount > 30){ writelog('page must be reloaded.....'); window.location.reload(); } return 0; } else { clearTimeout(timer1); writelog('set hiding timer to '+HideTimeout+' sec.'); timer3 = setTimeout('hideLoadImage()', 1000 * HideTimeout); } } function reloadImage(){ writelog('reloadImage called'); // Reload nur wenn in der onlinezeit clearTimeout(timer2); if ( (compare_to_now('07:00') <= 0 && compare_to_now('12:00') > 0 ) || (compare_to_now('15:00') <= 0 && compare_to_now('20:00') > 0 ) || (compare_to_now('21:30') <= 0 && compare_to_now('22:30') > 0 ) ){ writelog(new Date() + ' in online time, set new image'); showLoadImage(OnlineText); WebCamImage.src=WebCamImage.src.substring(0, WebCamImage.src.indexOf('?')) + '?' + Math.ceil(Math.random() * 1000000); writelog('new image name: '+ WebCamImage.src); errorcount=0; writelog('call checkImage in 1 sec'); timer1 = setTimeout('checkImage()', 1000); } else { writelog(new Date() + ' in offline time, nothing to do - save server requests'); showLoadImage(OfflineText); } writelog('set reload timer to '+ReloadTimeout+' sec.'); timer2 = setTimeout('reloadImage()', 1000 * ReloadTimeout); } reloadImage();

Was passiert?
Die Funktion „reloadImage“, die gleich als erstes aufgerufen wird, prüft ob der Aufruf im „Online-Zeitfenster“ der Webcam ist.
Sollte das der Fall sein, wird der Lade-Text gesetzt und sichtbar gemacht (Funktion showLoadImage).
Danach wird die src-Adresse des Bildes neu gesetzt. Da das Bild aber den selben Namen hat, gibt es noch eine Zufallszahl als Requestparameter hinter das Bild, um ein Reload zu „erzwingen“ bzw. den Browsercache „auszutricksen“.

Nun wird ein Timer gesetzt, der nach einer Sekunde die Funktion „checkImage“ aufruft. Diese Funktion prüft, ob das Bild erfolgreich geladen wurde oder ein Fehler passiert ist.
Sollte das Bild unvollständig oder fehlerhaft geladen sein, so ruft sich „checkImage“ im Sekundenintervall bis zu 30 Mal wieder auf. Führt das auch zu keinem Erfolg, wird die komplette Seite einmal neu geladen.
Wurde das Bild erfolgreich geladen, wird der timer von „checkImage“ gelöscht und nach einem timeout der Lade-Text durch die Funktion „hideLoadImage“ wieder versteckt.

Befinden wir uns nicht in dem „Online-Zeitfenster“ wird der Text über „showLoadImage“ mit einer Info über die Online-Zeiten gesetzt und dauerhaft angezeigt.

Am Ende wird noch ein Timer gesetzt, der die Hauptfunktion „reloadImage“ nach 60 Sekunden erneut aufruft.

Außerdem schreibt das Script auf die Konsole des Browsers, wenn es eine vorfindet (FireBug, Web-Konsole im Firefox oder die Konsole von Google-Chrome). Wird der debug-schalter auf 1 gesetzt und es gibt kein Plugin oder Konsolenuntersützung vom Browser (z.B. IE) wird ein Debugfenster geöffnet in das die Konsolenausgabe geschrieben wird.

Der Teil auf der Webseite um das ganze zu „aktivieren“ (rechts scrollen):

WebCam




Hier geht es nur darum die im JavaScript angesprochenen DOM-Elemente auf der Seite zu haben und den eigentlichen JavaScript zu laden. Sollte JavaScript deaktiviert sein, wird ein alternativer Text ausgegeben.

Hier sind die Kommentare offen für Fragen oder Anregungen – Danke, Alex.

7 Kommentare zu Webcam Technik

  1. Sascha sagt:

    Das war genau was ich gesucht hatte. Es ging leicht einzubinden und ist auch sehr übersichtlich. Vielen Dank dafür!

    • Alex sagt:

      Cool, freut mich, dass das Script für dich auch funktioniert. Bei Fragen oder evtl. Verbesserungsvorschlägen, immer gerne zu mir. 🙂

      Gruß, Alex

  2. Uli Baecker sagt:

    Hi Alex,
    deine Webcamlösung finde ich sehr gut. Sie ist das, was ich auf meiner WordPress-Seite http://www.sonnenhaus-zypern.de auch gerne hätte.
    Leider bin ich nicht sehr bewandert in der Programmierung, deshalb habe ich einige Fragen zu Deiner Lösung.
    Ich habe die Einstellungen so vorgenommen, wie in den (). Leider läuft es nicht so, wie bei dir. (keine Aktualisierung, keine Schrift etc.)
    Was hab ich falsch gemacht?
    Schau mal meine Seite: http://sonnenhaus-zypern.de/?page_id=1837

    1. Mit welchem Namen und Extension speicherst Du das Liebligsscript ab? -> (webcam.js ?)
    2. Wo legst du das Script auf dem Server ab? -> (Verzeichnis des Bildes auf dem Server ?)

    Für Deine Hilfe danke ich schon mal im Voraus.

    Gruß Uli

    • Alex sagt:

      Hallo Uli,

      nachdem ich mir den Link angesehen habe, musste ich feststellen, dass Du den Code zur Einbindung eins zu eins übernommen hast – da ist aber eine Stelle im Code, die Du anpassen musst

      Der Path zu der webcam.js:

      src="{PATH_ANPASSEN}/webcam.js"

      bei Dir scheint es schon in dem Ordner „cam“ zu liegen – also musst Du

      src="/cam/webcam.js"

      schreiben. Dann sollte es hoffentlich funktionieren.

      Zu den Fragen – wie das Script heißt und wo es liegt ist dir überlassen – wichtig ist nur, dass es zu dem src passt und am besten sollte es auf .js enden.

      Gruß, Alex

      • Uli Baecker sagt:

        Herzlichen Dank, Alex.
        Es funzt hervorragend!!!
        … mit Brille wär das nicht passiert! 🙂

        • Alex sagt:

          Hallo Uli,

          gerne, freut mich ja, dass dir das Script gefällt und nützlich ist. Ggf. musst du noch die Offlinezeiten am Ende anpassen, oder ist bei dir auch das Licht zwischen 12:00 und 15:00 aus?

          Gruß, Alex

        • Alex sagt:

          Hallo Uli,

          ich habe ja nichts dagegen, dass das Script genutzt wird, aber wieso steht auf deiner Webseite in der kopierten webcam.js jetzt ein Copyright von dir drin?

          Alex

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

eMail-Benachrichtigung bei weiteren Kommentaren.
Auch möglich: Abo ohne Kommentar.