After my recent move, the streaming and ‘workshop/den/laboratory’ setup has been a lot of work from the ground up on the computer system side. I used to have a Raspberry PI 4 used as a remote webcam that covered my old place’s 3D printing area. While that worked, I never liked the idea of dedicating a whole Raspberry Pi 4 to that – I wanted to try a Raspberry Pi Zero W and see if it could handle the load. Utilizing the popular MJPG-Streamer package, I was able to get that installed and running, though I had a few hiccups which I’ll reference at the bottom.
The article is a combination of various articles I found on the web, referencing older versions of one part or another, and this is a reference for my setup should I need to rebuild it.
Hardware
- Raspberry Pi Zero W – Purchased one of those kits on Amazon and it came with various cases and cables I needed, so I was happy with it.
- Logitech USB Webcam
- Power/HDMI/USB
- Keyboard/Mouse
Fresh Raspbian Install
I’m utilizing the latest version of Raspbian as of this writing, which was released around February, 2020. Flashing that to a simple 16 GB Micro SD Card for a blank slate:

Assuming you’re relatively familiar with the Pi, here’s the minimum I’m generally doing as post boot up task work:
- Changing default password
- Setting Up Wifi
- Enabling SSH
- Setting Hostname
- Setting Locale/Internationalization Options
- Rebooting
After that, the obligatory ‘update’ install:
sudo apt update sudo apt upgrade
I can now SSH into the Pi Zero W, disconnect the keyboard, and move along with the install.
Build Dependencies
We need to download some things first before we can build mjpg-streamer. I found some references to articles that pulled from the SVN repo to retrieve and compile, but I ended up getting a large amount of compile errors that look like some library was swapped but the source wasn’t updated. It’s the 'redefinition of ‘struct statx_timestamp’'
error.
Instead of pulling the SVN version, I’m going to be pulling the Git repo of mjpg-streamer that was created by jacksonliam. This (https://github.com/jacksonliam/mjpg-streamer) is the ‘official’ successor to the now abandoned SVN version at https://sourceforge.net/projects/mjpg-streamer/.
We’ll now install our dependencies before we download and compile mjpg-streamer code:
sudo apt-get install build-essential libjpeg8-dev imagemagick libv4l-dev cmake git -y
Git, Make, Install
mkdir ~/mjpg-streamer cd ~/mjpg-streamer git clone https://github.com/jacksonliam/mjpg-streamer.git cd mjpg-streamer/mjpg-streamer-experimental make sudo make install
The make install will copy binaries, libraries and the www pages to the /usr/local/ directory structure:
/usr/local/bin/mjpg_streamer
– The primary binary/usr/local/lib/mjpg-streamer/
– The directory of input/output modules/usr/local/share/mjpg-streamer/www
– The www server interface
Test The Build
I’m going to test the build by plugging in a webcam into the Pi Zero W’s lone USB port. Executing dmesg shows that it was loaded properly:
[ 1275.662775] usb 1-1: New USB device found, idVendor=046d, idProduct=082d, bcdDevice= 0.11 [ 1275.662796] usb 1-1: New USB device strings: Mfr=0, Product=2, SerialNumber=1 [ 1275.662806] usb 1-1: Product: HD Pro Webcam C920
Let’s test by trying to run mjpg-streamer against the input_uvc.so plugin, since I”m not using a Raspi-Camera, but a USB one instead. (Otherwise I’d use input_raspicam.so and enabling the camera module in raspi-config). I’ll also output using the http plugin. So my testing command line looks like this:
/usr/local/bin/mjpg_streamer -i "input_uvc.so -f 15 -r 640x480" \ -o "output_http.so -w /usr/local/share/mjpg-streamer/www"
Executing that line gives us a dump of data – here’s the relevant info:
MJPG Streamer Version: git rev: 5a6e0a2db163e6ae9461552b59079870d0959340 i: Using V4L2 device.: /dev/video0 i: Desired Resolution: 640 x 480 i: Frames Per Second.: 15 i: Format............: JPEG i: TV-Norm...........: DEFAULT o: www-folder-path......: /usr/local/share/mjpg-streamer/www/ o: HTTP TCP port........: 8080 o: HTTP Listen Address..: (null) o: username:password....: disabled o: commands.............: enabled
Our key variables to tweak are -f for frame rate, and -r for resolution. I’ll change those later, but for a quick test I head on out to my browser and point it at the www server at http://cam-pi-zero.local:8080/

Not only do we see the web interface, but a snapshot of the web cam, which was, clearly, laying down on a workbench behind me while I tried this out.
Validating the stream worked (by clicking ‘Stream’) and turning around, I could see myself moving:

You can now hit CTRL-C in your SSH window (or terminal) and quit the stream. After this point, I could delete the build files I downloaded.
Tweaking configuration
I wanted to run my camera at its intended resolution and at least a frame rate of 30fps. To do that I modified my command line:
#30fps, 1080 HD /usr/local/bin/mjpg_streamer -i "input_uvc.so -f 30 -r 1920x1080" \ -o "output_http.so -w /usr/local/share/mjpg-streamer/www"
I then loaded my own stream up in VLC by opening the direct network path to the stream:
http://cam-pi-zero.local:8080?action=stream
That worked, and I get about a 1-2 second delay from Pi to VLC. So I wouldn’t use this with audio feeds unless I was planning on creating a sync delay. I’m using this to monitor 3D prints, or watch birds outside, so my use case does not demand low latency. Is it exactly 30 frames per second? No…. NO it’s not.
At 1280×720, it seemed closer, but at 1920×1080, when set at 30fps, it definitely wasn’t even close. I’d guess more like 15.
The PI wasn’t maxed out on CPU, but it could just be the nature of USB 2.0 at this point. I’m not sure how I can tell if it’s overloaded there or not, but, once again, this is a light monitoring video stream, I don’t care too much about latency. It could be WiFi as well. Someday I may dig in a bit more and find out where the bottleneck is.
I think you could probably choose either 1920×1080 15fps or 1280×720 30fps routes and be okay.
Running On Startup
I liked Jacob Salmela‘s script – all I did was change it for my command line on the stop and restart section for my resolution and frame-rate. Save the following script by doing a sudo vi:
sudo vi /etc/init.d/livestream.sh
#!/bin/sh # /etc/init.d/livestream.sh ### BEGIN INIT INFO # Provides: livestream.sh # Required-Start: $network # Required-Stop: $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: mjpg_streamer for webcam # Description: Streams /dev/video0 to http://IP/?action=stream ### END INIT INFO f_message(){ echo "[+] $1" } # Carry out specific functions when asked to by the system case "$1" in start) f_message "Starting mjpg_streamer" /usr/local/bin/mjpg_streamer -b -i "input_uvc.so -f 15 -r 1920x1080" -o "output_http.so -w /usr/local/share/mjpg-streamer/www"-b sleep 2 f_message "mjpg_streamer started" ;; stop) f_message "Stopping mjpg_streamer…" killall mjpg_streamer f_message "mjpg_streamer stopped" ;; restart) f_message "Restarting daemon: mjpg_streamer" killall mjpg_streamer /usr/local/bin/mjpg_streamer -b -i "input_uvc.so -f 15 -r 1920x1080" -o "output_http.so -w /usr/local/share/mjpg-streamer/www" sleep 2 f_message "Restarted daemon: mjpg_streamer" ;; status) pid=`ps -A | grep mjpg_streamer | grep -v "grep" | grep -v mjpg_streamer. | awk ‘{print $1}’ | head -n 1` if [ -n "$pid" ]; then f_message "mjpg_streamer is running with pid ${pid}" f_message "mjpg_streamer was started with the following command line" cat /proc/${pid}/cmdline ; echo "" else f_message "Could not find mjpg_streamer running" fi ;; *) f_message "Usage: $0 {start|stop|status|restart}" exit 1 ;; esac exit 0
Then we enable this on startup by performing:
sudo chmod 755 /etc/init.d/livestream.sh sudo update-rc.d livestream.sh defaults
Now you can reboot your pi, or use commands like ‘sudo service livestream start’ I rebooted my pi, and my fed was running, and running a status command on my service yields:
pi@cam-pi-zero:~ $ sudo service livestream status ● livestream.service - LSB: mjpg_streamer for webcam Loaded: loaded (/etc/init.d/livestream.sh; generated) Active: active (running) since Thu 2020-05-14 11:46:09 CDT; 2min 51s ago Docs: man:systemd-sysv-generator(8) Process: 411 ExecStart=/etc/init.d/livestream.sh start (code=exited, status=0/SUCCESS) Memory: 2.2M CGroup: /system.slice/livestream.service └─416 /usr/local/bin/mjpg_streamer -b -i input_uvc.so -f 15 -r 1920x1080 -o output_http.so May 14 11:46:07 cam-pi-zero.local mjpg_streamer[416]: MJPG-streamer [416]: TV-Norm...........: DEFAUL May 14 11:46:08 cam-pi-zero.local mjpg_streamer[416]: MJPG-streamer [416]: www-folder-path......: /us May 14 11:46:08 cam-pi-zero.local mjpg_streamer[416]: MJPG-streamer [416]: HTTP TCP port........: 808 May 14 11:46:08 cam-pi-zero.local mjpg_streamer[416]: MJPG-streamer [416]: HTTP Listen Address..: (nu May 14 11:46:08 cam-pi-zero.local mjpg_streamer[416]: MJPG-streamer [416]: username:password....: dis May 14 11:46:08 cam-pi-zero.local mjpg_streamer[416]: MJPG-streamer [416]: commands.............: ena May 14 11:46:08 cam-pi-zero.local mjpg_streamer[416]: MJPG-streamer [416]: starting input plugin inpu May 14 11:46:08 cam-pi-zero.local mjpg_streamer[416]: MJPG-streamer [416]: starting output plugin: ou May 14 11:46:09 cam-pi-zero.local livestream.sh[411]: [+] mjpg_streamer started May 14 11:46:09 cam-pi-zero.local systemd[1]: Started LSB: mjpg_streamer for webcam.
Conclusion
Using the Raspberry Pi for video streams is good enough if we’re looking for low frame rate monitoring without audio. I’ve yet to find anything that really gives me the frame rate and audio (regardless of latency) that a standard USB webcam directly into my OBS machine would give. Maybe if NDI ever makes it on to the raspberry Pi, or if there is ever SLDP support.
Have you tried streaming across the network on a Raspberry Pi with a USB webcam? Did you fare better than I? Let me know!
Nevertheless, with that, I’m done! I can now embed this into OBS via the VLC media source or anything that can handle an HTTP Motion JPEG video stream. I won’t have audio, but that’s okay for what I’m using this for.
References
- https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md – Raspberry Pi Document on WIFI Setup
- https://www.amazon.com/Vilros-Raspberry-Starter-Power-Premium/dp/B0748MPQT4 – The Raspberry Pi Zero W kit I purchased
- https://sourceforge.net/projects/mjpg-streamer – The original source forge project.
- https://github.com/jacksonliam/mjpg-streamer – The successor to the abandoned Sourceforge project.
- https://jacobsalmela.com/2014/05/31/raspberry-pi-webcam-using-mjpg-streamer-over-internet/ – Reference for build information
- https://www.acmesystems.it/video_streaming – Another build reference
- https://qiita.com/xeno14/items/e32e52c688d969d182e2 – Another build reference
thankyou – finally a guide that works and give very little lag even on a pi-zerow
Glad it worked out for you! It’s not the best quality or speediest thing in the world but it does get the job done!
how to secure my cam ?
Looks like you have a few options to consider – one is just simple authentication – the second is more of encryption of the stream itself.
* https://medium.com/@petehouston/protect-http-media-stream-created-by-mjpg-streamer-2812efd08f75
* https://crish4cks.net/secure-webcam-streaming-mjpg-streamer-stunnel/
[…] Quelle: MJPG-Streamer on a Raspberry Pi Zero W with a USB Webcam Streaming Setup – Krystof.IO […]