Recording MJPEG Streams from the Axis 210 Cameras

Author:  David Cottingham

The Axis network cameras are network attached video cameras. They have CS mount lenses (i.e. standard ones that can be interchanged), and run Linux.

The streams that can be outputted are various. For Windows, you will need to access the camera via a web browser, select to view the MPEG-4 stream from the dropdown on the top-left, accept the installation of the ActiveX control (note that Internet Explorer may well not pop up a dialogue, but just an information bar at the top of the screen!), and then view away. Having installed the control, the relevant applet in the Windows control panel will have an MPEG-4 tab (if this is not present, re-install the control). You will now be able to view the stream using Windows Media Player, using one of the URLs listed at  http://www.axis.com/techsup/faq/index.php?id=53526 .

Under Linux, the stream URLs listed above do not work (they use protocol names prefixed with "ax").

Before trying any of the below, ensure that your firewall permits incoming UDP traffic. An interim (but insecure) solution is:

iptables -F
iptables -P INPUT ACCEPT
iptables -F OUTPUT ACCEPT

Note that by default the camera requires a username and password to view the images from it. You can allow anonymous viewing by going to the camera's web administration interface and then the "Live Image" section. Mplayer will allow you to give a username and password in the form rtsp://user:password@192.168.0.90, but VLC is (I think!) less forgiving.

Having tried extensively to obtain a programme that was able to get the MPEG-4 stream, I have drawn a blank. Programmes tried are:

  • Mplayer (with all codecs; when accessing the RTSP stream gave fuzzy lines at top of screen, so nearly working!)
  • RTSPGet (failed to access the RTSP stream at all)
  • ffplay (part of ffmpeg; couldn't find the stream).
  • Quicktime for Linux (so many dependencies that I couldn't get it to compile!)

An e-mail to Axis Technical Support was very promptly answered, and they suggested  VLC player for Linux.

Installation involves getting the  unofficial RPM for the correct version of Suse (there are many!). You will also need most of the other RPMs listed at the bottom of that page, which VLC depends on.

Try to install VLC, using rpm -iv and you'll probably have failed dependencies. Use yast to search for them, remembering to tick the "provides" checkbox in the search, as many of the libraries you'll need are not in packages of the same name.  RPM Search is also incredibly useful for those that SuSe doesn't include.

On Gentoo, first insert the following line into /etc/portage/packages.use:

media-video/vlc dvd ffmpeg mpeg mad wxwindows aac dts a52 ogg flac theora oggvorbis matroska freetype bidi xv svga gnutls stream vlm httpd cdda vcd cdio live

You will also need the following line in /etc/portage/package.keywords:

media-video/vlc ~x86

This will ensure that all the correct codecs etc. are installed, and that you get the latest version of VLC (version 0.8.1 does not work. 0.8.2 does), when you run

emerge vlc

(Otherwise you will get an error about not having an appropriate codec for MJPEG when you attempt to access the stream, or an odd error about the X server sending "." [which terminates the process]).

Test VLC on a sample MPEG file, to confirm it's working. If you get errors such as

main input error: no suitable access module for ...

the chances are that it can't actually access the file or stream you're trying to play.

I attempted to access the MPEG-4 over RTSP stream from the camera, and had the above error. The URL concerned was

rtsp://192.168.0.90/mpeg4/media.amp

However, the  Axis Camera API is very detailed, and gives the URL for accessing the Motion JPEG stream. This can be done as follows:

  • Start vlc
  • "File", "Open Network Stream"
  • Select "HTTP/HTTPS/FTP/MMS"
  • Type http://192.168.0.90/axis-cgi/mjpg/video.cgi?fps=30&nbrofframes=0 into the "Open" box

You should now be able to watch the stream. Quality is fine, see the API for other options such as resolution arguments. The stream appears to be delayed by 2 seconds or so.

If you wish to rotate the image, add the parameter &rotation=degs where degs is an integer number of degrees to rotate the image by, to the URL above. To show the date and time, add &date=1&clock=1 to the URL.

If you wish to record the stream, check the "Stream Output" box in the same dialogue, and then click "Settings" to specify the file. Check the "file" box, and specify a path to output to. Select that the "Encapsulation Method" be MPEG-TS, and do not choose to "dump raw input".

Playback of the stream can also be done using VLC. Just ensure that you untick the "stream output" box, as it will have remained ticked from when you were recording from the camera, and will happily overwrite your saved file!

Gentoo on piddle(2), even with the 0.8.2 version, refuses to actually display the video. If the stream is written to a file, this appears to work fine, but playing the stream or the file will result in X locking to such an extent that even killing X will not release the keyboard/mouse. Ssh-ing into the machine still works though.

A  command line interface for VLC is also available.

To obtain simple JPEG snapshots from the camera, the  Axis API also describes in detail the different parameters that can be used, including compression and resolution. I used:

http://192.168.0.90/axis-cgi/jpg/image.cgi?resolution=320x240&clock=1&date=1&textpos=bottom&compression=25

Note that wget will need this to be surrounded by quote marks. You can use the -O (letter "o") to specify the output filename.

UPDATE 23/02/07: Frame processing using ffmpeg

Author:  Robert Harle

vlc is fine if you want to play the stream, but it's a pain if you actually want to video process (i.e. get and process the stream frame by frame in memory). This is actually quite trivial to achieve using ffmpeg (specifically libavcodec and libavformat). There is, however, a trick: ffmpeg needs to be able to derive the stream format from the supplied filename or stream URL. Unfortunately, the MJPEG stream URL (the one we use under Linux) is something like:

http://xxx.xxx.xxx.xxx/axis-cgi/mjpg/video.cgi?resolution=320x240

which does not specify the format. To do so you can either do this manually if you want to play it:

ffplay -f mjpeg http://xxx.xxx.xxx.xxx/axis-cgi/mjpg/video.cgi?resolution=320x240

or add ".mjpg" to the end of the URL:

ffplay "http://xxx.xxx.xxx.xxx/axis-cgi/mjpg/video.cgi?resolution=320x240&.mjpg"

The latter solution is the key to making it work in code that uses libavcodec/libavformat. Just feed it the modified URL above in place of the filename, and you should find your code works fine! You can av_open_input_file() on it, then use av_read_frame() and av_decode_frame() exactly as per  this page.