MJPGServer documentation

The MJPGServer is a streaming server software for usual USB2.0 camera (or any supported V4L2 source) that supports multiple resolution streaming.

It can be used to both monitor a 3D printer with a low resolution video stream and capture high resolution picture to build nice timelapse video.

Using this server requires a video source that's compressing picture in JPEG format. Most USB2.0 camera with FullHD resolution supports this feature. If unsure, please follow the affiliated links below for a camera that works well for this task. It also requires a Linux computer (Raspberry Pi, Orange Pi, 3.1415926535...). You can use whatever distribution you like, the server does not have any dependencies.

Fetching the sources and building the server

If you have Git installed, you can fetch all the required source by running this command:

$ git clone https://github.com/X-Ryl669/MJPGServer.git

Else, you'll need to download the source code archive from here and unzip it in some folder (let's call it MJPGServer)

Then you can build the server this way:

$ cd MJPGServer/build/linux
$ make

(If the last command failed, you'll need to install a C++ compiler and GNU make, check your distribution documentation for this)

It should return this:

>  Computing dependencies for JSON.cpp
>  Computing dependencies for LogLevel.cpp
>  Computing dependencies for V4L2Source.cpp
>  Computing dependencies for MJPGServer.cpp
>  Compiling MJPGServer.cpp
>  Compiling V4L2Source.cpp
>  Compiling LogLevel.cpp
>  Compiling JSON.cpp
>  Compiling Threads.cpp into ClassPath/Threading/
>  Compiling Lock.cpp into ClassPath/Threading/
>  Compiling HashKey.cpp into ClassPath/Hash/
>  Compiling Logger.cpp into ClassPath/Logger/
>  Compiling bstrwrap.cpp into ClassPath/Strings/BString/
>  Compiling Strings.cpp into ClassPath/Strings/
>  Compiling MemoryBlock.cpp into ClassPath/Utils/
>  Compiling Linux.cpp into ClassPath/Platform/
>  Compiling File.cpp into ClassPath/File/
>  Compiling Encode.cpp into ClassPath/Encoding/
>  Compiling Streams.cpp into ClassPath/Streams/
>  Compiling __version__.cpp into ClassPath/
../../ClassPath/src/__version__.cpp:227:64: note: « #pragma message: Using ClassPath with flags _ AES _ _ TLS Base Float Chrono Atomic MD5 ExLock _ Compress _ RegEx _ _ _ _ _ _ Debug  »
  227 |         #pragma message("Using ClassPath with flags " FlagNames)
      |                                                                ^
>  Compiling Time.cpp into ClassPath/Time/
>  Compiling Socket.cpp into ClassPath/Network/
>  Compiling Server.cpp into ClassPath/Network/
>  Compiling Connection.cpp into ClassPath/Network/
>  Compiling Address.cpp into ClassPath/Network/
>  Compiling HTTP.cpp into ClassPath/Network/Servers/
>  Compiling AES.cpp into ClassPath/Crypto/
>  Compiling HTTPCode.cpp into ClassPath/Protocol/HTTP/
>  Compiling TextualHeaders.cpp into ClassPath/Network/Clients/
>  Compiling LinuxSpecific.cpp into ClassPath/Network/
>  Compiling Random.cpp into ClassPath/Crypto/
>  Compiling bstrlib.c into ClassPath/Strings/BString/
Linking mjpgsrv

Congratulations, you've finished building the software!

Testing it's working for you

By default the server requires configuration to know what video source, what format, what port and so on to run. While you can set all these parameters by hand, it's a lot easier to write a configuration file and let the server digest it.

Hopefully, I'm providing a default configuration file you can tweak with your own parameter, so let's do that:

$ cp ../../defaultConfig.json config.json
$ nano config.json

An editor should open to let you tweak the configuration. Basically, the following parameters are available:

Key Expected value format Meaning Default value
port unsigned integer in range [1-65535] The HTTP port to listen on 8080
closeDeviceTimeoutSec unsigned integer in seconds Delay before closing unused device, 0 to disable the function 0
device string Path to the V4L2 camera device to open /dev/video0
daemonize boolean (true or false) If true, the server runs in background & drop priviledges(*) false
logLevel -1, 0, 1, 2, 3 -1: debug, 0: info, 1: warning, 2: error, 3: silent 0
lowResWidth unsigned integer in pixels The row size of the preview (low resolution) video stream 640
lowResHeight unsigned integer in pixels The column size of the preview (low resolution) video stream 480
highResWidth unsigned integer in pixels The row size of the full resolution picture max detected
highResHeight unsigned integer in pixels The column size of the full resolution picture max detected
stabPicCount unsigned integer in frames The number of unstable frames to drop when switching res 0
securityToken string If given, access to the stream will require this secret token empty

When using daemonize mode, the server open the TCP/HTTP port and then drop priviledges (to avoid running with root priviledges). However, if you have enabled closeDeviceTimeoutSec, you might get an error once the software tries to re-open a closed device since it does not have the required priviledges anymore to do so.

So either disable closeDeviceTimeoutSec (by setting 0) or make sure the unpriviledged user has the right to reopen the video device.

securityToken, when used, requires appending a ?token=yoursecuritytokenhere to the streams' URL. This is to prevent free-access to the streams if the server is directly accessible to the Internet. This is security-by-a-secret which is transmitted in clear on the HTTP's parameter. This means that on HTTP protocol, it's free to snoop on the IP link. You should only rely on this single security if you have a reverse HTTPS proxy so the information is not transmitted in clear. Using it on plain HTTP is better than nothing (at least it keeps private eyes out of the view) but don't forget it's still limited, security wise.

Let's try it!

Once you are down tweaking your configuration value, check the server is working by running:

$ ./mjpgsrv -j config.json

This should output:

Thank you for using MJPGServer
Detected maximum picture size as 1280 x 720

Video set up for width:640, height:480, format:MJPG - LittleEndian
Server started on: http://10.250.3.89:8080?token=verySecretToken

The last line contains the URL you must visit to watch your stream. Copy and paste in your browser and you should see the video of your camera right into your browser. Also check you can capture full resolution pictures.

In this page, you'll have the 2 URL for the direct streams like this:

Screenshot of MJPGServer

You can copy these URLs in Octoprint (the first one goes into the live stream field, the last one in the Octolapse plugin).

Installing the server so it starts on boot

To install the server on startup, you need to launch this command from the building directory:

$ make install

Then edit the configuration file to match your expectations (with sudo nano /etc/mjpgserver/config.json), and add the service to the system so it can start as wanted:

$ sudo systemctl enable mjpgserver
$ sudo systemctl start mjpgserver

Congratulations!

Previous Post Next Post

Sponsored links

In order to pay for infrastructure cost for this blog, I'm listing some affiliated links about the hardware listed above.

Related Posts