MJPEG-ProxyGrab
Introduction
Two small cgi-programs written in C which can either grab an image or proxy the mjpeg stream from a Motion webcam.
Detailed Description
- mj-grab
- Cgi program which fetches one frame of the mjpeg stream and sends it to standard out (browser). The idea is to show a snapshot of a camera without saving any files on the web server. Can be used for "client pull" type webcam.
- mj-prox
- Cgi program which fetches the mjpeg stream from the Motion webcam server and sends it to standard out (browser). The idea is that the browser gets the stream from the standard http port 80 so that company firewalls does not block the stream. Additionally this program enables the webserver to have one IP address and motion running on another IP address and an applet such as Cambozola will still work because it gets the stream from the webserver. Both programs are made as a cgi programs for e.g. an Apache server.
Attached Files
The attached file is a tar.gz containing the source files for the programs. All written in C.
Change history
- Version 1.0 - 2003 November 19 - Initial Release
- Version 1.1 - 2003 November 22 - Greatly improved by Folkert van Heusden inspired by a suggestion from Torben Jensen
- Version 1.2 - 2005 April 02 - Fix for old versions of gcc provided by Christophe Grenier
Installation
First define the path of the webserver cgi-bin directory by editing the line in the Makefile
bindir = /usr/local/apache2/cgi-bin
Then edit the 3 X
#define
in the source files.
The source file has a detailed comment that documents everything.
The fast track steps are
- Edit the 3 defines in the .c files
- Edit the Makefile and run
-
make
-
make install
The mjgrab program only allocates 40000 bytes for the picture buffer. If you use an image size of 640x480 you will need to increate the buffer. In nph-mjgrab.c you will find
char chbuffer[40000] = "";
Change the 40000 to 100000 and you should be fine.
Users Guide
mjgrab
The program opens a socket to a running Motion webcam server. It then fetches ONE and only one frame of the mjpeg stream and sends it to standard out (browser) after having sent a few headers. It then closes the socket and terminates.
The idea is to show a snapshot of a camera without saving any files on the web server.
This program is made as a cgi program for e.g. an Apache server. It runs as a nph (direct to browser) program. It takes one variable which is the camera (Motion thread number). The program must be copied to a directory from which cgi scripts can run. It must be have access rights set as executable for the web server. The program must be named with the prefix
nph-
.
The cgi program is run by making an image tag in a HTML file like this:
<IMG SRC = "/cgi-bin/nph-mjgrab?1" WIDTH=320 HEIGHT=240>
Note the number after the "?". This is the camera number (Motion thread no.)
Below the 3 #defines must be set before you build the program.
You need to set IP address of the motion server, the portbase and the upper limit for the number of cameras you have. IP address 127.0.0.1 means local host (same machine). PORTBASE is the number from which the webcam port is calculated.
The calculated port = PORTBASE + Camera Number (thread number).
So if thread 1 has the webcam port set to 8081 the PORTBASE should be 8080.
mjprox
The program opens a socket to a running Motion webcam server. It then fetches the mjpeg stream from the Motion webcam server
and sends it to standard out (browser).
The idea is that the browser gets the stream from the standard http port 80 so that company firewalls does not block the stream. Additionally this program enables the webserver to be on one IP address and motion running on another IP address and an applet such as Cambozola will still work because it gets the stream from the webserver.
This program is made as a cgi program for for example an Apache server. It runs as a nph (direct to browser) program. It takes one variable which is the camera (Motion thread number). The program must be copied to a directory from which cgi scripts can run. It must be have access rights set as executable for the web server. The program must be named with the prefix
nph-
.
To use it with for example Cambozola add this to an HTML page
<applet code=com.charliemouse.cambozola.Viewer
archive=cambozola6.jar width=325 height=245>
<param name=url value="/cgi-bin/nph-mjprox?1">
<param name="accessories" value="none"/>
</applet>
Note the number after the "?". This is the camera number (Motion thread no.)
Below the 3 #defines must be set before you build the program.
You need to set IP address of the motion server, the portbase and the upper limit for the number of cameras you have. IP address 127.0.0.1 means local host (same machine). PORTBASE is the number from which the webcam port is calculated.
The calculated port = PORTBASE + Camera Number (thread number).
So if thread 1 has the webcam port set to 8081 the PORTBASE should be 8080
--
KennethLavrsen - 05 Oct 2004
Additional Notes
There are a couple more important advantages to using
mjprox rather than accessing your webcams directly:
- You can use Apache's access control to password protect your webcams - by password protecting access to mjprox.
- And for the really paranoid you can use Apache SSL to encrypt the webcam stream.
If you try either of the above points then make sure you set
webcam_localhost on
in your motion config otherwise it will be pointless as you will still be able to directly access the webcams - unencrypted and without a password.
Other implementations.
Several users posted some nice alternatives to mjgrab all written in PHP. I have created a related project topic for those and moved them there. See
MjpegFrameGrabPHP.
received by email
I have been using nph-mjgrab and mjprox to display single images and the
MJPEG stream on my webpage. They both work great, except when I use
mjprox and I close the browser connection, it appears that the pipe to the
program doesn't close, or maybe it doesn't realize. It continues to write
to stdout (I can verify it is getting a good return from fwrite).
I apologize if this is not related to motion code.. maybe its more an
apache issue. I have apache that came with Fedora Core 1.. so I think it
is 2.2.47.. Just wondering if you knew anyway for mjprox to realize the
client session has gone away or if you've seen this issue?
Thanks for any help,
KennethLavrsen for Stephen Blinick
Answer
I have never noticed that the mjprox program was hanging.
How long does it hang?
--
KennethLavrsen - 21 Dec 2005
Hi, thanks for copying my question here. The program itself works great.. But when the client browser closes the connection, it continues to run. So if for example you viewed it 3 times, the nph-mjprox application (spawned by apache) would continue to run and you'd have 3 processes going.
For Example, after two views, both client connections are closed but:
[root@machine]# ps -aef | grep nph
apache 29787 29748 0 23:39 ? 00:00:00 /var/www/security/cgi/nph-mjprox 1
apache 29788 29750 0 23:40 ? 00:00:00 /var/www/security/cgi/nph-mjprox 1
It appears they continue running forever. I was wondering if there is a way to know when the client has closed its connection so the nph-mjprox can terminate. I have checked and stdout remains open after the close. I also tried adding a signal handler to nph-mjprox to catch SIGPIPE but it doesn't seem to get a signal when the client closes.
--
StephenBlinick - 22 Dec 2005
I use mjprox myself on my public webcams so they are accessed all the time. I do not have these hanging processes. Exactly which Apache version do you have? I do not believe it is 2.2.47. Maybe 2.0.47?
rpm -qi httpd
will tell you.
--
KennethLavrsen - 22 Dec 2005
Yeah you're right, 2.0.47 is the version.
--> rpm -qi httpd
Name : httpd Relocations: (not relocateable)
Version : 2.0.47 Vendor: Red Hat, Inc.
Release : 10 Build Date: Thu 23 Oct 2003 03:55:16 AM MST
Install Date: Mon 12 Apr 2004 10:33:01 AM MST Build Host: daffy.perf.redhat.com
Group : System Environment/Daemons Source RPM: httpd-2.0.47-10.src.rpm
This weekend I'll try upgrading the version of apache.
--
StephenBlinick - 28 Dec 2005
Do not try to use both applications with Tomcat cgi server
Tomcat is not capable to manage nph cgi script
--
MarcoTozzini - 22 Mar 2006
Hello,
Hope it is the right place to ask this question.
Can mj-prox also be used to feed an MJPEG file to an apache server?
I have loads of MJPEG sequences that I'd like to "serve" on a webpage...
Thanks in advance
Antoine
--
AntwanOdy - 10 Oct 2006
No. To send an mjpeg file as a stream you will need to have a problem that also send the right headers and mime type. Probably the easiest way is to do it in PHP or Perl.
--
KennethLavrsen - 16 Oct 2006
Users of apache2 can use the apache proxy module instead of mjprox.
Just copy proxy.conf, proxy.load and proxy_http.load from mods-available to mods-enabled.
I have it running using this proxy.conf.
<IfModule mod_proxy.c>
ProxyRequests Off
<Proxy *>
AddDefaultCharset off
Order deny,allow
Allow from all
</Proxy>
ProxyVia On
ProxyPass /motion/live/1 http://localhost:8001
ProxyPass /motion/config/1 http://localhost:8000/1/config/list
</IfModule>
I use this proxy module with apache2 (the one with apache2)
http://httpd.apache.org/docs/2.0/mod/mod_proxy.html
--
DagErlandsson - 08 Jul 2007/30 Nov 2007
hi
DagaEarlandsson, but where have you set the password to access the web server?
what are these directories: /motion/live/1 and /motion/config/1, i can't found they in /etc/motion.
--
AntonioBlob - 05 Oct 2008
i solved, i add /motion/live/1 at the cambozola viewer in the html page
--
AntonioBlob - 08 Oct 2008
i have have a new problem, if i write in firefox myipaddress, for example 192.168.1.5/motion/live/1 i can watch the stream without the password and username, but the webserver is limited, because if i write only the ip 192.168.1.5 firefox ask me the password and user. What is wrong with it?
--
AntonioBlob - 09 Oct 2008