Turn any MJPEG streaming source (e.g. IP camera) into a virtual camera

With UV4L and the mjpegstream driver it’s possible to make any source of MJPEG streams over HTTP (e.g. an IP camera) appear as a camera physically connected to the Raspberry Pi so to make it transparently accessible by any Video4Linux2-compliant applications, including the powerful UV4L Streaming Server and WebRTC module themselves which open the door to an infinite number of unique use cases. For example, you can simply relay the original video stream (in native MJPEG) to local clients, or, more interestingly, add an audio track from a microphone, re-encode, encrypt (yes!) the video track in VP8, VP9 or H264  and finally “push” the combined stream to a remote Jitsi or Janus conference room on Internet that you can later join with your browser (no plugin is required) or another Raspberry Pi.

We will see how to do this with a D-Link DSL-930L IP camera, although this short example can be easily applied to IP cameras of different brands or to other kinds of MJPEG sources over HTTP in a similar way.

First of all install the UV4L core module and the mjpegstream driver according these instructions. Optionally also install the Streaming Server module and the WebRTC extension mentioned in the same instructions. To fully reproduce this example you will need the latters.

Finally, find out and take note of the exact URI providing the raw MJPEG stream from the IP camera, as you will need to pass it to uv4l. Depending on the camera access restrictions, you might need to also include username and password in the URI. Some cameras can accept extra arguments in the URI to allow them to be configured on-the-fly. The general URI is in typically the form http://username:password@host.domain:8080/path/file?action=stream.

In this specific case, the command is the following:

uv4l --driver mjpegstream --auto-video_nr --uri "http://admin:@192.168.1.10/video.cgi?resolution=VGA" --server-option=--port=8000
[...]
<notice> [core] Trying driver 'mjpegstream' from external plug-in's...
<notice> [core] Device detected!
<notice> [core] Trying to load the the Streaming Server plug-in...
<notice> [server] HTTP/HTTPS Streaming & WebRTC Signalling Server v1.1.73 built on Jul 11 2016
[...]
<notice> [core] Registering device node /dev/video1

Okay. If you look at the above output, you will notice that a device node (/dev/video1) has been created and is now in background – just like with any other real cameras – and a new dedicated Streaming Server is also ready to be used through its web interface at port 8000.

The mjpegstream driver accepts many other options. You are encouraged to read through the driver manual.