Webcam Streaming

November 29th, 2020

Just connected a USB webcam to Raspberry and wanted to access it via a network. The old good VLC came up to help. The following command line does do the stuff:

cvlc -v \
v4l2:///dev/video0:width=1920:height=1080:chroma=mjpg:fps=30 \
--sout \
'#standard{access=http{mime=multipart/x-mixed-replace;boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8888/abc}'

Input

The input is a the /dev/video0 device serviced by the video for linux (v4l2) – or whatever camera you are about to use.

The optional arguments are:

Output

VLC is able to forward the stream, transcode it on-the-fly and/or offer it via a number of network protocols. In the example above, an MJPEG stream transported over http is requested:

Client

To open the stream, enter the path either in a web browser or any other player (e.g. a VLC):

http://YOUR_ADDRESS:8888/abc

Video format

The camera I use generates an MJPEG stream natively (so to say, a stream of consecutive JPEG pics). In this mode it is capable of up to 30 fps at 1080p or up to 60 fps at 720p. Any other format, like yuv2 or mp2v will force the webcam to drop most of the frames as its processor is too weak.

This has a consequence for the output stream. In the example above, we just forward the original stream to the network. In order to use any better format (e.g. transporting audio as well) and protocol (like TS over RTSP), the stream must be re-encoded. This did not work in my case and I’m still searching for a solution.

Failed approaches

Re-encoding the video stream from MJPEG (as this is the only one offering 30fps @ 1080p):

cvlc -v \
v4l2:///dev/video0:width=1920:height=1080:chroma=mjpg:fps=30 \
--sout \
'#transcode{vcodec=mp2v,acodec=none,fps=30}:standard{access=http{mime=video/MP2T},mux=ts,dst=:8888/abc}'

This ends up with a number of errors mmal_codec generic error: MMAL error 2 “ENOSPC”. It seems that the GPU does not have enough memory. Open question: maybe it would help to assign more memory in /boot/config.txt to at least 128MB-144MB.

Just to try to force the camera to give the right stream right away, does not work due to the limited processing power. So the command:

cvlc -v v4l2:///dev/video0:width=1920:height=1080:chroma=yuv2:fps=30…

Would end up with maybe like 5 fps. Additionally, I did not manage to successfully connect a client to such a stream.

And independently from the above issues, I did not manage to offer an RTSP stream so that a client wants to connect to it:

'#transcode{vcodec=mp2v,acodec=none,fps=30}:rtp{mux=ts,sdp=rtsp://:8888/live.sdp}'

Still investigating…


Next: GitHub with SSH keys

Previous: JavaFX Episode 1

Main Menu