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.
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!
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.
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:
You can copy these URLs in Octoprint (the first one goes into the live stream field, the last one in the Octolapse plugin).
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!
In order to pay for infrastructure cost for this blog, I'm listing some affiliated links about the hardware listed above.