« Over 1,000,000 Hits | Main | My Christmas without a Car »

February 03, 2006

Webcam

I had wanted to setup a unique geocache type, a webcam cache. I started with all the extra equipment that I had readily available. I had plenty of video capture cards that work on everything from Macs to Sparcs, but no video camera. Work had tons of surplus Quickcams, but they were just too old and couldn't produce a good outdoor image. So I found a cheap standalone IP based webcam on ebay. Its an Orite IC300. Out of the box, the webcam is only configurable with Internet Explorer (IE) and the live video is an ActiveX control that also only works in IE. Since I myself don't even use IE, I wanted to provide a much more universal interface as well as something that didn't look like a hacked together engrish page. I looked around for examples and couldn't find anything. Most of the webcams out there were broken or just the default webcam pages. So I spent a lot of time creating a site and thought I'd share some of the results. You can view the webcam at http://www2.ertyu.org/webcam/.

My first thought was to update the Orite camera to a newer firmware version. (If in doubt, update, cross fingers and see if that fixes anything without breaking anything else.) Unfortunately it seems I had an older version which couldn't do field upgrades. After a lengthy conversation with the Canadian rep, who seemed less than reliable at first, I shelled out a few bucks to upgrade to the newest hardware version. Finally after getting the unit back, I found nothing new :(
I did manage to dig up some technical information from the rep's website though. The camera provides JPEG still frame and MJPEG live stream interfaces.

See Update Below

Providing a live stream is obviously the most difficult, but its also the most rewarding. Netscape/Mozilla/Firefox based browsers support displaying an MJPEG stream natively. So now I had support for two major browser groups, the ActiveX control from the manufacturer for IE and the MJPEG stream for Netscape & Mozilla based browsers. I wanted universality though. It then boiled down to JAVA. I evaluated many many packages and they all sucked in some way or another. I settled on Cambozola (I'm still hoping Cortado will get updated and work better). There were still issues with permissions and functionality though. I didn't want to expose the IP camera itself too publicly, ideally I wanted it on the internal private network with the viewer on a public webserver. Unfortunately JAVA's security prevents an unsigned applet from accessing remote locations. I ended up setting up a proxy for the JPEG and MJPEG data from the camera on the webserver for the JAVA applet to use (webcamproxy.php). This prevents having to sign the applet with weak or unknown credentials. (At one point I remember having to click "I trust Andy." hehe) The proxy also inserts a timestamp into the JPEG data (timestamp.php). I went with an older version of the applet because it seemed to work better. The JAVA applet, although it works, doesn't work well enough to use exclusively. So with the ActiveX, MJPEG and JAVA live streaming versions I had enough to support any reasonable browser that could display a live stream, but I needed to select the optimal version for each browser. I used the Full Featured PHP Browser Detection & OS Detection code to do basic auto-select but allow a manual override (live.php). So thats the bells and whistles, a few basics to tidy up. The main page provides a basic JPEG image that is refreshed using javascript (index.html). It ended up after working on all this, that a borrowed ActiveX control from Axis (another webcam company) worked better than the one provided by Orite (The Orite control (WinWebPush.cab) is provided by the webcam chip manufacturer, Winbond).

Update
I wasn't quite satisfied with the performance of the webcam. Each viewer would end up running off a separate stream to the webcam (which lead to a few cam crashes) and they would run the live stream as fast as they could or until I ran out of bandwidth. Instead I inserted Motion between the webcam and the website. It grabs a single stream from the cam and distributes to the web. It adds the ability to produce an configured frame rate mjpeg stream, as well as to vary frame rate based on detected motion or idle state. It also adds its a timestamp and can generate periodic snapshots and many other image modification abilities. I also changed the live page to use mjpeg for Safari and Konquerer which now support mjpeg natively.

If you want to revert to the simpler method without motion, change webcamproxy.php as follows:
- motion server->webcam address and change the port too (8081->80 likely)


$urlstring = "GET /GetData.cgi?Status=1 HTTP/1.0\r\n\r\n

or if you want to use a password on the webcam

$urlstring = "GET /GetData.cgi?Status=1 HTTP/1.0\r\nAuthorization: BASIC ".base64_encode ("username:password')."\r\n\r\n";

JAVA applet: webcamViewer.jar

ActiveX control: AMC.cab

webcamproxy.php:

<?php
  set_time_limit(0);
  $fp = fsockopen ("motion server", 8081, $errno, $errstr, 30);
  if (!$fp) {
    echo "$errstr ($errno)<br>\n";
  } else {
    $urlstring = "GET / HTTP/1.0\r\n\r\n";
    fputs ($fp, $urlstring);
    while ($str = trim(fgets($fp, 4096)))
      header($str);
    fpassthru($fp);
    fclose($fp);
  }
?>

live.php:

<?php
//...Full Featured PHP Browser Detection & OS Detection code goes here
$style = (isset($_GET['style'])) ? $_GET['style'] : auto;
?>
<html>
<body>
<?php
if
(
  (
    ($style == 'auto')
    &&
    (browser_detection( 'browser' ) == 'ie')
    &&
    (
      (browser_detection( 'os' ) == 'win')
      ||
      (browser_detection( 'os' ) == 'nt')
    )
  )
  ||
  ($style == 'activex')
)
{
?>
<object id="Player" width="640" height="480" border="0"
classid="CLSID:745395C8-D0E1-4227-8586-624CA9A10A8D" codebase="AMC.cab">
  <param name="AutoStart" value="1">
  <param name="UIMode" value="none">
  <param name="MediaType" value="mjpeg-unicast">
  <param name="NetworkTimeout" value="5000">
  <param name="MediaUsername" value="webcam">
  <param name="MediaPassword" value="webcam">
  <param name="MediaURL"value="http://www2.ertyu.org/webcam/webcamproxy.php">
</object>
<a href="live.php?style=mjpeg" class="header">MJPEG</a>
<a href="live.php?style=activex" class="selected">ActiveX</a>
<a href="live.php?style=java" class="header">Java</a>
<?php
}
else if
(
  (
    ($style == 'auto')
    &&
    (
      (browser_detection( 'browser' ) == 'moz')
      ||
      (browser_detection( 'browser' ) == 'ns')
      ||
      (browser_detection( 'browser' ) == 'saf')
      ||
      (browser_detection( 'browser' ) == 'konq')
    )
  )
  ||
  ($style == 'mjpeg')
)
{
?>
<img src="webcamproxy.php">
<a href="live.php?style=mjpeg" class="selected">MJPEG</a>
<a href="live.php?style=activex" class="header">ActiveX</a>
<a href="live.php?style=java" class="header">Java</a>
<?php
}
else
{
?>
<applet code="com.charliemouse.cambozola.Viewer"' archive="webcamViewer.jar" width="640" height="480">
  <param name="url" value="webcamproxy.php">
  <param name="accessories" value="Info"/>
  <param name="accessorystyle" value="overlay">
</applet>
<a href="live.php?style=mjpeg" class="header">MJPEG</a>
<a href="live.php?style=activex" class="header">ActiveX</a>
<a href="live.php?style=java" class="selected">Java</a>
<?php
}
?>
</body>
</html>

index.html:

<html>
<head>
<script language="Javascript" type="text/javascript">
   <!-- hide
    var x = 30;
    var y = 1;
    var now;
  
    function startClock() {
     x = x-y;
     document.form1.clock.value = x;
     if (x <= 1) reload();
     timerID = setTimeout("startClock()", 1000);
    }
  
    function reload() {
     now = new Date();
     var camImg = "snapshot.jpg" + "?" + now.getTime();
     document.campicture.src = camImg;
     x = 30;
     document.form1.clock.value = x;
    }
   // end hide -->
</script>
</head>
<body onLoad="startClock()">
<img name="campicture" src="snapshot.jpg" border=0
alt="WebCam"></td>
<form NAME="form1">Auto Reload
in ~<input TYPE="text" NAME="clock" SIZE="2" VALUE> seconds.</form>
</body>
</html>

motion.conf excerpts:

netcam_url http://webcam.ertyu.org/Jpeg/CamImg.jpg
snapshot_interval 25
text_right
text_left %Y-%m-%d\n%T-%q %Z
target_dir /WEBSITE_LOCATION
snapshot_filename snapshot
webcam_port 8081
webcam_motion off
webcam_maxrate 2

Although Motion supports periodic output I already had it setup via script running with cron.
grab.sh:

#!/bin/csh

set DIRROOT='/DIR/webcam-archive'
set URL="http://webcam.ertyu.org/Jpeg/CamImg.jpg"

set YEAR=`date "+%Y"`
set MONTH=`date "+%m"`
set DAY=`date "+%d"`
set TIME=`date "+%R"`

if !(-d $DIRROOT/$YEAR/$MONTH/$DAY/) then
mkdir -p $DIRROOT/$YEAR/$MONTH/$DAY
endif

wget -O $DIRROOT/$YEAR/$MONTH/$DAY/$TIME.jpg $URL >& /dev/null

Comments

Goed bezig! (bad translation: 'good busy') This helped us a lot. WinWebPush.cab sucks.

Thnx

Posted by: Ruud at July 5, 2006 12:19 PM

Very glad to see someone else who owns this now-defunct camera! For the price at the time a couple of years back, it was a pretty good buy. Just wanted to drop by and say, as a fellow programmer, that this is some nice code you've whipped up to control access.

Posted by: Gary at March 26, 2007 09:14 PM

Nice work!

Good to find someone else using this camera. I have an Aviosys IPkamera 9000 which (I believe) has the same internal hardware as the camera you use. It's been running happily on my site for the past 3ish years

http://www.sydney-webcam.com/webcam.php

Cheers,

Warren

Posted by: Warren Frost at July 25, 2007 06:58 PM

tnx for the code, very useful

Posted by: dani at June 12, 2008 06:24 AM

I found that if you put <IMG SRC="http://ip-cam.address.here:1600/GetData.cgi?Status='1'"
WIDTH="640" HEIGHT="480" ALT="IP Cam #0" BORDER="0"> on a webpage you will get live video.

Just thought I would let you know!

Thank you for the Pages and such above!

Posted by: Dan Faulkner at July 16, 2008 02:34 AM

Thanks for the info! I've been messing around with my IP cam for years, and having much fun presenting it in various ways.
I've been tuning it up again. I've got another a second cam, and resurrected my old screen free Powerbook as a headless cam server. I've been experimenting with ways to beam the 2 streams to servers where my other sites are hosted, and the page's code to add an interactive aspect.
I appreciate your written explanation- very clear!
If you are curious about my finished project, write me a note & I'll send a link!

Posted by: Leslie Michel at July 14, 2009 03:03 AM

AMC by Axis is allowed to be used only with Axis products. Checked their license.

So I'm searching for "free" ActiveX solution.

//arl

Posted by: arl at January 28, 2015 04:05 AM

Post A Comment




Remember me?






Created By: Steven Nikkel (steven_nikkel@ertyu.org)
This webpage and others materials are Copyright © 1997-2016 Steven Nikkel, All Rights Reserved
counter