Archive

Stream Webcam

Streaming your webcam from your website

Introduction

You want to stream (i.e. (near) real-time) your webcam from your website. However:

  • The server your website is on isn’t on your LAN (the same network as you).
  • You don’t want to open up and forward ports from the Internet in to your LAN.
  • You want the setup to work anywhere you are.
  • You want to enable anyone to view it (even if they’re behind a corporate firewall for example).

This document will show you how to stream your webcam from your website and comply to the bullet points above.

Requirements

  • Your webcam should already be working (this document doesn’t cover troubleshooting webcam problems).
  • You need SSH access to the server your website is on.

Step 1: Install camserv to do the streaming

Camserv takes a video-for-linux (V4L) input and streams it live to clients, on request via a mini-webserver that’s built in to camserv.

Install camserv (Debian users: aptitude install camserv).

Step 2: Configure camserv

You need to edit /etc/camserv/camserv.cfg. This contains “sections”.

With regards to the video source sections, I removed them all (BTTV, FreeBSD driver etc.) apart from the video_v4l_qcam section, because I have a Logitech Quickcam. Don’t remove the video_basic driver though.

I then created myself a custom overlay to use:

[banner_text] path            /usr/lib/camserv/libtext_filter.so.0 text            /home/david :: Webcam bg              transparent fg              #000000 x               0 y               230 mangle          1 fontname        6x11

In the “socket” section, I changed the listen_port to 9191.

I then changed the “filters” section so it looks like:

[filters] num_filters             3 filter0_section         time_stamp filter1_section         banner_text filter2_section         jpg_filter

And finally, the “video” section was changed so that video_section matched what driver I was using (video_v4l_qcam in this case) and set the maxfps option to 1. Make sure memhack is set to 1.

== Step 3: Run and testing camserv ===

Simply run camserv /etc/camserv/camserv.cfg from the command line, as a normal user.

To test it, open your web browser and browse to http://localhost:9191 (assuming you changed the port to 9191, which will be assumed from now on). You should see your webcam image and it should be streaming. Although at this stage it’ll be very “jittery” stream and it won’t seem like 1fps.

Step 4: Enable the web server to access the stream

This is the part the gets around the issue of opening up ports, forwarding them from the Internet in to your LAN and then you’re stuck with the machine the port is forwarded to and you can’t move around freely. To enable all this, we use a reverse SSH tunnel.

Assuming in your camserv configuration you changed the port to 9191, create a reverse SSH tunnel to the server your website is on:

$ ssh -C -c blowfish-cbc -R 127.0.0.1:9191:127.0.0.1:9191 -l username webserver.com

Once you’re SSH’d to the web server (webserver.com in the above ssh command), telnet to 127.0.0.1 on port 9191 and you should see loads of rubbish on the screen. Pressing Ctrl+] and then typing quit will exit you from telnet.

If you don’t see anything or you get “Connection refused”, something is horribly wrong.

Step 4: Install the web page components

SSH’d to the server your website is on, you need to download Cambozola which is a Java applet to let users view your live webcam stream:

$ mkdir webcam $ cd webcam $ wget http://www.charliemouse.com/code/cambozola/cambozola-latest.tar.gz $ tar -zxvf cambozola-latest.tar.gz $ cp cambozola-0.68/dist/cambozola.jar . $ rm cambozola-latest.tar.gz $ rm -rf cambozola-0.68

Now you need to create a “proxy” using PHP which Cambozola will connect to and in turn this PHP proxy will connect to your reverse SSH tunnel and get the live webcam stream from you.

Create a file called connect.php:

<? set_time_limit(0);  $fp = @fsockopen ("127.0.0.1", 9191, $errno, $errstr, 5); if ($fp) {       {{{         fputs ($fp, "GET / HTTP/1.0r r ");                 while ($str = trim(fgets($fp, 4096)))                 header($str);                 fpassthru($fp);                 @fclose($fp); } ?>

}}}

Create a HTML page to tie everything together (such as index.html):

<html> <head> <title>Webcam</title> </head> <body>  <div align="center"> <applet code="com.charliemouse.cambozola.Viewer" {{{         archive="cambozola.jar"         width="320" height="240"         style="border-width: 1px; border-color: black; border-style: solid;">      <param name="url" value="/webcam/connect.php" />   <param name="accessories" value="[[ZoomIn]],[[ZoomOut]],Pan,Info" />   <param name="retries" value="5" />   <param name="delay" value="1000" />   <param name="failureimage" value="/images/offline.gif" /> </applet> </div>

}}}

Step 5: Testing it out

Simply go to http://webserver.com/webcam/ and (fingers crossed) your your image should be streaming, in real time (ish)! It’s best to test it from another machine in case the Java applet hasn’t been configured correctly and it’s connected directly to camserv via 127.0.0.1 for some reason.

Step 6: Automating everything

Under Debian, camserv is run at boot time unless you’ve changed something. So that’s taken care of.

This script will setup the SSH tunnel when you login (this goes on your local machine and is probably very hacky):

#  if [[ -z|$(ps fx | grep ssh | grep '127.0.0.1:9191' | grep -v grep | awk '{print $1}') ]]; then {{{         echo "  * Creating reverse SSH tunnel."         ssh -o '[[ServerAliveInterval]]=10' -o '[[KeepAlive]]=yes' -f -q -nNT -R 127.0.0.1:9191:127.0.0.1:9191 -C -c blowfish-cbc -l username webserver.com fi

}}}

Save it somewhere sensible (for example ~/bin, assuming that ~/bin is in your $PATH) and chmod +x the script. Now you can either run this script manually each time you login to your machine or we can automate it so it runs on login.

If you want to do this, edit your ~/.bash_profile to call the “webcam SSH reverse tunnel script” we created above. But it’s also important you edit/create ~/.bash_logout so it contains:

webcamtunnel=$(ps fx | grep ssh | grep '127.0.0.1:9191' | grep -v grep | awk '{print $1}') if [[ !|-z "$webcamtunnel" ]]; then kill -TERM $webcamtunnel; fi

Otherwise when you logout, shutdown or reboot your local machine, the server your website is on doesn’t realise this and keeps the reverse SSH tunnel open. So the next time you login nothing will work because the port is already in use.

Summary

  • We’ve configured camserv on your local machine. This provides “the stream”.
  • We’ve setup a reverse SSH tunnel from your local machine to the web server.
  • We’ve install all the web components that make this work.
  • When a user views your stream, they load a Java applet (Cambozola)
  • This applet opens the connect.php URL which acts as the middle man.
  • connect.php connects over the reverse SSH tunnel to camserv (thus bypassing any firewalls or the need to open and forward ports).
  • The user sees the live stream!

When things go wrong

  • The reverse SSH tunnel is still open, even though it should be closed (e.g. the local machine was shutdown in a non-standard way).
    • This does happen. The reverse SSH tunnel can’t tell when to “hang up”. To close the reverse SSH tunnel, on the web server use netstat -pan | grep 9191 to find the PID of the SSH process that’s keeping this port open and then kill it.

To-do/Notes

  • Previously I was using motion… but this hogs too much CPU power, compared to camserv. Although I feel camserv lacks the polish that motion has.
    • Reading the Debian TODO for camserv, this may change with the list of features it describes.
  • Is using SSH compression and changing the cipher to blowfish really a good bandwidth saver when streaming 1fps, over SSH?

Page written by DavidRamsden

Leave a Reply