Inhaltsverzeichnis

Bandbreitenbegrenzung in Richtung Mobotix Kamera

Hintergrundinfo

Eine Bildauflösung von 640×480 Bildpunkten benötigt pro Sendeaktion eine Bandbreite von ca. 307kBit. Werden nun von einem oder mehreren Usern Bilder der Webcam abgerufen, so kann dieses sehr schnell größere Datenmengen mit sich bringen, die sich bei Nutzung von aDSL sehr schnell negativ auf die vorhandene Upstreambandbreite auswirken. Besonders kritisch wäre dies noch dazu, wenn der böswillige Nutzer die Frameraten selbst einstellt.

Abhilfe kann hier zum Beispiel leisten, die Bilddaten nicht für das WWW, vom Webserver der „kleinen Kamera“ abzufackeln, sondern von einem Webserver, der eine entsprechend „dicke“ Upstreamleitung zum Internet besitzt. Freilich könnte man nun die Bilder von der Kamera via FTP auf einen Webserver schieben, dies ginge recht gut bei Standbildern - bei Echtzeitkommunikation wird es hier auch schon schwerer. Ganz zu schweigen von der andauernden Übertragung von Nutzer-/Logindaten beim Upload.

Unter Umständen, wie auch in der Konfigurationsumgebung im SOHO-LAN, steht auf dem Webserver gar kein FTP-Server zur Verfügung. Wir müssen also dies anders und auch eleganter lösen.

Lösung

Wir cashen den Traffic über einen zentralen Proxy, holen uns von dort die Kamerabilder direkt von der Mobotix-Kamera und gestatten über diesen Proxy den Zugriff für das gemeine Fußvolk.

Hierzu sind ein paar Vorarbeiten auszuführen.

RAM-DISK

Damit nun unser Caching nicht auf Lasten der Festplatten-Stapel geht (Datendurchsatz und Schreib-/Lesezugriffe) nutzen wir für unseren VHost eine RamDisk.
Diese legen wir wie folgt an:

 # vim /etc/fstab
 /dev/shm                /var/www/html/webcam    tmpfs   defaults,size=3m,mode=750,uid=69,gid=69 0 0

Die User- und Group-ID stellen wir dann auf den/die User/Gruppe apache ein.

Anschließend mounten wir unsere zusätzliche RAM-Disk:

 # mount /var/www/html/webcam

Da wir sowohl über das Verzeichnis record wie auch current unsere Bilder bzw. Liveimages weitergeben wollen, legen wir diese beiden Verzeichnisse an:

 # mkdir /var/www/html/webcam/control/
 # mkdir /var/www/html/webcam/record/

Anschließend passen wir noch die betreffenden Userrechte an:

 # chown apache:apache /var/www/html/webcam/control/
 # chown apache:apache /var/www/html/webcam/record/

DokumentRoot-Erweiterungen

Für unsere Webcam(s) legen wir nun einen VHost an:

# vim /etc/httpd/conf.d/vhosts.conf
vhosts.conf
#
# webcam.nausch.org
#
<VirtualHost *:80>
        ServerAdmin webmaster@nausch.org
        ServerName webcam.nausch.org:80
        ServerAlias webcam.nausch.org *.webcam.nausch.org
        ServerPath /
        DocumentRoot "/var/www/html/webcam"
        <Directory "/var/www/html/webcam">
                Options FollowSymLinks
                AllowOverride None
                Order allow,deny
                Allow from all
        </Directory>
        DirectoryIndex index.html index.php
        ErrorLog logs/webcam_error.log
        CustomLog logs/webcam_access.log combined
</VirtualHost>

Nach einem Restart unseres Apache-Webservers steht uns nun dieser VHost zur Verfügung.

Webseite an-/festlegen

Unseren Gastzugang lehnen wir dann an den originalen Zugang dere Mobotix-Kameras an. Von unserem Root-Server mit der fetten Internetanbindung lassen wir dann alle 5 Sekunden die Wettercam-Bilder automatisch nachladen.
Das ganze soll dann wie folgt aussehen:

Initiale Bildbefüllung

Für einen ersten Test holen wir uns jeweils ein aktuelles Webcambild und speichern dieses unter cd /var/www/html/webcam/record/ ab.

# cd /var/www/html/webcam/record/

# wget http://192.168.100.101/record/current.jpg
# mv current.jpg current_2.jpg
# wget http://192.168.100.100/record/current.jpg

# cp /var/www/html/webcam/record/current.jpg /var/www/html/webcam/control/cam1.jpg
# cp /var/www/html/webcam/record/current.jpg /var/www/html/webcam/control/cam2.jpg

HTML-Seite anlegen

Damit in der Überschrift die aktuellen Daten der Wetterstation eingefügt werden, nutzen wir die automatische Seitengenerierung durch software_-_wview. Wie legen uns also im Arbeitsverzeichnis von Wview ein Grundgerüst unserer HTML-Seite an.

# vim /usr/local/etc/wview/html/webcam.htx
webcam.htx
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
  <title>Private Wetterstation Pliening in Bayern</title>
</head>
 
 <script language="JavaScript">
  function openURL(urlname)
   {
    window.location=urlname;
   }
 </script>
 
 <body style="background-image: url(django_bg.jpg);">
 
<!-- nav-buttons_Plus.incx -->                                                                                                                                                      
<table align="center" border="0" cellpadding=2 cellspacing=2>
 <tr>                                                                                                                
  <td colspan="5" align="center" valign="top" height="30">
   <input type="button" value=" &Uuml;bersicht  " onclick="openURL('https://wetter.nausch.org/index.html')">
   <input type="button" value="    Almanach     " onClick="openURL('https://wetter.nausch.org/Almanac_Plus.htm')">
   <input type="button" value="  aktuelle Werte " onClick="openURL('https://wetter.nausch.org/Current_Plus.htm')">
   <input type="button" value="  Letzte 24 Std. " onClick="openURL('https://wetter.nausch.org/Daily_Plus.htm')">
   <input type="button" value="  Letzte 7 Tage  " onClick="openURL('https://wetter.nausch.org/Weekly_Plus.htm')">
   <input type="button" value="  Letzte 28 Tage " onClick="openURL('https://wetter.nausch.org/Monthly_Plus.htm')">
   <input type="button" value=" Letzte 365 Tage " onClick="openURL('https://wetter.nausch.org/Yearly_Plus.htm')">
   <input type="button" value="  Stationsdaten  " onClick="openURL('https://wetter.nausch.org/Station.htm')">
   <input type="button" value=" akt. Blitzkarte " onClick="openURL('https://wetter.nausch.org/stormforce.htm')">
   <input type="button" value="    Impressum    " onClick="openURL('https://wetter.nausch.org/Impressum.htm')">
  </td>
 </tr>
</table>
 
<!--include header.inc--> 
 
<!-- Aufforderung zum Aktivieren von JavaScript -->
<noscript>
 <center>
  <p>
   <a href="https://webcam.nausch.org/control/userimage.html"><font face="Helvetica,Arial" size="-1">Open Menu (cam1)</font></a>
  </p>
  <p>
   <font face="Helvetica,Arial" size="+3" color=red>Press Shift-Reload to refresh the image.<br>Enable JavaScript / Active Scripting to see more details.</font>
  </p>
 </center>
</noscript>
 
<!-- Seitenkorpus -->
 
<hr>
 
<font size="4" face="Arial, Helvetica, sans-serif" color="#000000">Wetterwebcams der Wetterstation</font>
<br>
<table cellpadding="2" cellspacing="0" border="0" width="100%" align="center">
 <tbody>
  <tr>
   <td>
    Kamera mit Blickrichtung Westen (M&uuml;nchen)<br>
    <font size="1" face="Arial, Helvetica, sans-serif" color="#000000">&nbsp;</font>
   </td>
   <td>
    Kamera mit Blickrichtung Osten (Markt Schwaben)<br>
    <font size="1" face="Arial, Helvetica, sans-serif" color="#000000">(tempor&auml;r 'gen Norden bis Au&szlig;enmontage m&ouml;glich)</font>
   </td>
  </tr>
  <br>
  <tr>
   <td>
    <img src="https://webcam.nausch.org/control/cam1.jpg" width="620" height="465" name="camimage1" alt="Kamera-Livebild - Aktualisierung einmal pro Minute">
   </td>
   <td>
    <img src="https://webcam.nausch.org/control/cam2.jpg" width="620" height="465" name="camimage2" alt="Kamera-Livebild - Aktualisierung einmal pro Minute">
   </td>
  </tr>
  <tr>
   <td>
    <a href="https://webcam.nausch.org/index.html"><font face="Helvetica,Arial" size="-1">Open Menu (cam1)</font></a>
   </td>
   <td>
    <a href="https://webcam.nausch.org/index.html"><font face="Helvetica,Arial" size="-1">Open Menu (cam2)</font></a>
   </td>
  </tr>
 </tbody>
</table>
 
<hr width="100%" size="4">
 <table cellpadding="2" cellspacing="2" border="0" width="100%">
  <tbody>
   <tr>
    <td width="40%" valign="bottom" align="left">
     <small>
      <font face="Arial, Helvetica, sans-serif" align="left" color="blue">
       <a href="https://wetter.nausch.org">wetter.nausch.org</a>
      </font>
     </small>
    </td>
    <td width="20%" valign="bottom" align="center">
     <small>
      <font face="Arial, Helvetica, sans-serif" align="center" color="blue">
       . 
      </font>
     </small>
    </td>
    <td width="40%" valign="bottom" align="right">
     <small>
      <font face="Arial, Helvetica, sans-serif" align="right" color="blue">
       <a href="https://wetterstation-pliening.info">wetterstation-pliening.info</a>
      </font>
     </small>
    </td>
   </tr>
  </tbody>
 </table>
 
<script language="JavaScript">
  var imageUrl1=document.camimage1.src;
  var imageUrl2=document.camimage2.src;
  var random=new Date().getTime();
  var delay=1; // Aktualisierung in Sekunden
  var counter=0;
  var buffer1=new Image;
  var buffer2=new Image;
  function DisplayImage1() {
    document.camimage1.src=buffer1.src;
    LoadNextImage();
  }
  function DisplayImage2() {
    document.camimage2.src=buffer2.src;
    LoadNextImage();
  }
  function LoadBuffer () {
    var trickname1=imageUrl1;
    var trickname2=imageUrl2;
    ++counter;
    trickname1+="?counter="+(random+counter);
    trickname2+="?counter="+(random+counter);
    buffer1.src=trickname1;
    buffer1.onload=DisplayImage1;
    buffer2.src=trickname2;
    buffer2.onload=DisplayImage2;
  }
  function LoadNextImage () {
    setTimeout("LoadBuffer()", 1000*delay);
    // Millisekunden*1000 -> Sekunden
  }
  LoadNextImage();
</script>
</body>
<html>

Da wir die, von wview generierte HTML-seite als index.HTML für unseren VHOST verwenden wollen, lassen wir die generierte Seite von Wview noch an die richtige stelle kopieren.

# cat /usr/local/etc/wview/post-generate.sh 
post-generate.sh
#/bin/sh
 
# Add any post template generation processing or utilities here. Keep in mind this 
# script runs in the htmlgend process's context so don't add anything that is overly
# time constrained.
 
/bin/cp /usr/share/wview/webcam.htm /var/www/html/webcam/index.html
/bin/cp /usr/share/wview/webcam.htm /var/www/html/webcam/control/userimage.html

Bild-Caching

Updatescript

Da wir natürlich immer auf das gerade aktuelle Kamerabild zugreifen wollen, müssen wir nun noch dafür sorgen, dass die Bilder auch fortlaufend gecached werden.

Hierzu behelfen wir uns eines kleinen Bash-Scriptes.

# vim /usr/local/bin/camcash.sh
camcash.sh
#!/bin/sh 
# Script zum Abholen und Abspeichern der Kamerabilder
# für den virtuellen Mobotix-Cambetrieb
# (c) Michael Nausch - 29.12.2008
 
WORKDIR_1="/var/www/html/webcam/control/"
WORKDIR_2="/var/www/html/webcam/record/"
CAMURL_1="http://192.168.100.100/record/current.jpg"
CAMURL_2="http://192.168.100.101/record/current.jpg"
SLEEP=1
 
cd $WORKDIR_1
while true
do
 wget $CAMURL_1
 rsync $WORKDIR_1"current.jpg" $WORKDIR_2"current.jpg"
 rsync -av current.jpg cam1.jpg
 rm current.jpg
 wget $CAMURL_2
 rsync $WORKDIR_1"current.jpg" $WORKDIR_2"current_2.jpg"
 rsync -av current.jpg cam2.jpg
 rm current.jpg
 # sleep $SLEEP
done

Über die Variable $SLEEP legen wir den Refreshzyclus fest, also einfach auskommentieren und den Verzögerungsfaktor festlegen.

Automatischer Start bei Systemstart

Damit nun nach einem Systemstart der Bildercashvorgang automatisch anläuft legen wir uns ein passendes Startscript an:

# vim /etc/init.d/weathercam
weathercam
#!/bin/sh
#
# chkconfig: 2345 79 31
# description: cyclic Weatherwebcam-Picture Update
#
# processname: weathercam
#
 
# Source function library.
. /etc/rc.d/init.d/functions
 
# Source networking configuration.
. /etc/sysconfig/network
 
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
 
prog=cam2pic.sh
cam_prg=/usr/local/bin/$prog
 
# Source an auxiliary options file if we have one, and pick up OPTIONS,                                                                                                     
if [ -r /etc/sysconfig/$prog ]; then
    . /etc/sysconfig/$prog
fi
 
start() {
    echo -n $"Starting $prog: "
    $cam_prg &
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
}
stop() {
    echo -n $"Stopping $prog: "
   /usr/bin/killall $prog
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
}
 
restart() {
    stop
    start
}
 
 
# See how we were called.
case "$1" in
    start)
        start
    ;;
    stop)
        stop
    ;;
    restart)
        restart
    ;;
    *)
        echo $"Usage: $0 {start|stop|restart|}"
        exit 1
esac
 
exit $RETVAL

Die Ausführungsrechte geben wir dann unserem script mittels:

# chmod +x /etc/init.d/weathercam

Damit der „service“ automatisch beim Systemstart anläuft, aktivieren wir diesen mit:

# chkconfig weathercam on

Die Überprüfung ob der Dienst (Daemon) stormforce wirklich bei jedem Systemstart automatisch mit gestartet werden, kann durch folgenden Befehle erreicht werden:

# chkconfig --list | grep weathercam

weathercam 0:Aus 1:Aus 2:Ein 3:Ein 4:Ein 5:Ein 6:Aus Den Daemon starten wir nun initial mit:

# service weathercam start

Zur Sicherheit sichern wir uns den Inhalt unseres VHostes/Ramdisk noch, damit wir diesen ggf. später zurückspielen können:

# tar cfvj /root/webcam_backup_090104.tar.bz2 /var/www/html/webcam
tar: Removing leading `/' from member names
/var/www/html/webcam/
/var/www/html/webcam/cgi-bin/
/var/www/html/webcam/cgi-bin/guestimage.html
/var/www/html/webcam/control/
/var/www/html/webcam/control/cam2.jpg
/var/www/html/webcam/control/cam1.jpg
/var/www/html/webcam/control/userimage.html
/var/www/html/webcam/record/
/var/www/html/webcam/record/current_2.jpg
/var/www/html/webcam/record/current.jpg
/var/www/html/webcam/record/stormforce_2.png
/var/www/html/webcam/record/stormforce.png
/var/www/html/webcam/record/current2.jpg
/var/www/html/webcam/index_old.html
/var/www/html/webcam/faviconx.ico
/var/www/html/webcam/favicon.ico
/var/www/html/webcam/django_bg.jpg
/var/www/html/webcam/current/
/var/www/html/webcam/current/cam2.jpg
/var/www/html/webcam/current/cam1.jpg
/var/www/html/webcam/index.html