CONTENTS

Home
Updates
Software
Electronics
Music
Resume
Contact


YouTube
Twitter
GitHub
LinkedIn

MJPEG Webserver


Posted: December 2006
Updated: October 22, 2024

Introduction

MJPEG Webserver is both a tiny web server capable of serving static web pages with built in ability to serve out live and pre-recorded video in JPEG format from capture devices such as webcams and AVI/MJPEG files. The server is small enough (22k to 32k) to run on embedded platforms and has been tested on embedded computers including a Linksys WRT54GL router running OpenWrt. The server can be configured to serve out video from URLs similar to commercial IP cameras like Axis.

There is also a sample plugin for MJPEG Webserver that shows it doing motor control similar to what a commercial PTZ IP camera would have here: Atmel Motor Control. I'm using it to control the motors on a Linksys Helicopter.

Related pages on www.mikekohn.net: mjpeg_webserver, Linux PTZ Control, j2me ipcamview, Axis DBus

Featuers

  • Serve out AVI files as if they were a live webcam.
  • Serve out static html web content like any other webserver.
  • Executable size is currently around 22k (32k with video4linux compiled in).
  • Small/fast enough to run on embedded platforms.
  • Alias URL strings of commerical IP cameras.
  • Video4Linux support for live video (early stages.. but working with bttv and sn9c102 based video).
  • No dependencies unless video4linux is compiled in (libjpeg is needed then).
  • Client Pull/Server Push for MJPEG video.
  • Username / Password Basic-Authentication.
  • Runs on both Unix / Linux and Microsoft Windows platforms.

Source Code

git clone https://github.com/mikeakohn/mjpeg_webserver.git

Compiling

To build:

./configure
make


To compile in video4linux2 support it can be configured with ./configure --enable-v4l2. Typing ./configure --help will print out a list of options. MJPEG Webserver compiles on Unix/Linux platforms as well as Windows under MingW

Starting with the January 02, 2007 version, there is a --with-mmap option. This will force MJPEG Webserver to mmap() (or on Windows, map a file) the AVI videos to try and reduce i/o loads. I haven't had a chance to test this yet under a loaded system, but I'm thinking it will reduce the i/o significantly on computers with harddrives. It probably won't be a good thing to do embedded systems, but I haven't had a chance to test it yet.

Basic Configuration

Basically, you can define up to 100 AVI videos in the nakenweb.conf file. They are defined with the filename option and are numbered in order they are put in the file. The first defined AVI is video #0, the second is video #1, etc. After defining videos, maxconn is set to the max number of webclients that can connect to the server at one time. max_idle_time is set to how long a client can be connected to the server without sending any data before being booted. port tells the server which port to bind to. If you have no other web server, you'll probably want to set this to 80.

An example nakenweb.conf file could look like this:

filename /storage/videos/kitchen.avi filename /storage/videos/garage.avi filename /storage/videos/basement.avi minconn 10 maxconn 50 max_idle_time 3 port 80 # If not defined, non-builtin web pages will 404. # It's not required to define htdocs_dir. htdocs_dir /var/www/htdocs # If username and password are not defined, password # protection is turned off. username mike password pencil

To start the server type:

./nakenweb -f nakenweb.conf

This will start the server using nakenwebcam.conf as the configuration file. If you want more help with compiling or starting the server, you can read the documentation for Naken Chat. The docs there should be very similar, if not the same.

After the sever is started, try the following URLs in a webbrowser:

http://localhost/0 (kitchen.avi) http://localhost/1 (garage.avi) http://localhost/2 (basement.avi)

Refreshing the webbrowser, will load the next frame (by time) from the AVI file. It'd be pretty easy to write a web client that constantly grabs the newest frames from the videos to create full motion video.

IP Camera Emulation Configuration

Setting up an alias for an IP camera should be fairly straight forward. The following 2 examples will set up a couple of aliases in Axis's VAPIX API format:

alias /axis-cgi/mjpg/video.cgi { port camera type stream frame_rate fps }

Which would allow the URL:

http://localhost/axis-cgi/mjpg/video.cgi?camera=1

By setting up the "port camera" option, this tells the Naken Web server that if on the URL line the user adds the option camera=<some number> that it should use camera number to dictate which defined video number the user wants to look at. Note that this is video number - 1. So if the URL was video.cgi?camera=2, the user would be grabbing from Naken Web's video defined as number 1. type stream defines this as a server push video (multipart/x-mixed-replace). "frame_rate fps" tells the server that if the user adds fps=<some number> to use this frame rate for sending out video.

alias /axis-cgi/jpg/image.cgi { port camera type single }

This example is the same as the first example execpt it relies on a client pull. In other words, that URL will only send one image (JPEG) instead of a stream of images (mjpeg). The URL that would be used to grab an image would then be:

http://localhost/axis-cgi/jpg/image.cgi?camera=1

To emulate the URL of a Sony IP camera:

alias /oneshotimage.jpg { port 0 type single }

This will send a single image from he server's video source number 0. In this example, all ?paramter=value's will be ignored.

There is no limit to the number of aliases that can be created, although for each one defined a few bytes of memory will be allocated and a tiny amount of CPU is used to check if the current URL matches the alias for every hit to the server.

If anything doesn't make sense, feel free to send me an email.

Video4Linux2 Configuration

To set up a Video4Linux2 device, the capture parameter is used:

capture /dev/video0 { size 640x480 max_fps 5 }

This sets of a video4linux2 USB camera for use with Naken Web. Note that the capture option is counted in the same way the filename option is. In other words, if a capture options is defined first, then the capture option is defined as video #0. Capture and filename options can be intermixed so videos and cameras can be numbered how you want them.

capture /dev/video1 { size 352x240 max_fps 5 channel 1 # bttv can have 4 devices hooked up to the same chip format ntsc }

This sets of a video4linux2 bttv device for use with Naken Web.

Limitations

To serve out AVI files the AVI's need to use the MJPEG codec. To convert a video encoded with mpeg or some other file-format / codec to AVI/MJPEG (while also removing audio), the tool ffmpeg can be used with the following options:

ffmpeg -i input.mpeg -vcodec mjpeg -b 10000 -s 352x240 -an out.avi

The input.mpeg filename should be changed to the actual input file name and out.avi to what the output file should be called. The -b option is the bitrate and will affect the size of each JPEG in the AVI file along with the quality of the video. The -s option is the resolution of the video. The -an option tells ffmpeg to remove the audio.

New Features (March 2007)

The following features are implemented in the new version:

  • VFW (Video For Windows) code added for webcams and capture devices on Windows (2007-03-15)
  • CGI execution with php/cgi support (GET only right now) (2007-02-28).
  • Huge increase in performance, especially on Windows (2007-03-15)
  • mmap()'d avi's for possible added performance (2007-01-02)
  • Added the ability to serve static html (html, JPEG, png, etc) from an htdocs directory
  • Added URL aliasing for emulation of IP camera strings
  • Video4linux for display of live real-time video
  • Added server push support for MJPEG streaming
  • Username/Password Basic Authentication

The following are my list of things to work on:

  • Frames per second control
  • Mutex issues with video4linux
  • Memory allocation on JPEG compression
  • Networking send failure retries
  • RTSP streams (probably a bit in the future)
  • Virtual Hosts
  • Video4Windows support so USB webcams and such work on Microsoft Windows (Code is written and in subversion, just needs to be tested)

License: Since Naken Chat is GPL, this program is GPL also.

News

October 22, 2024 - Changed the name from Naken Web to MJPEG Webserver. Massive cleanup on the source code with more to come.

July 26, 2008 - Fixed a bug that caused plugins to not work. I have a video on YouTube of Naken Web being used on a Linksys router to communicate with an Atmel ATmega168 to control a servo motor here: https://www.youtube.com/watch?v=0KdkPXHDsVw.

July 23, 2008 - I started working on a module for this web server that can do motor control on an embedded computer, much the way Axis has their PTZ control. I have a project page here for anyone interested: atmel_motor_control.php.

History

A couple years ago I modified my Naken Chat chat server so that would act like a web server and serve out JPEG images out of an AVI file. Pressing the refresh button on a web browser to grab a new image would display the next image in the video based on the time that the web server was started. In other words, the video would play at normal speed in the browser. Waiting 5 seconds before pressing refresh and the AVI plays at 30 frames a second, 150 frames are skipped so the time in the video is always accurate.

Copyright 1997-2024 - Michael Kohn