This project turns a Raspberry Pi Zero 2 W into a webcam by combining it with an HDMI capture device.
A web interface for adjusting focus, exposure and white balance is provided using Flask and gunicorn to serve a configuration page.
A simpler version without the web UI can be found here.
My goal with this project was to make a webcam capable of 1920x1080 at 30 fps that would be compatible with most streaming and video conferencing software.
The uvc-gadget project and its forks make use of the Linux UVC Gadget driver to provide a class compliant USB video device. This is a pretty straightforward way to turn a Pi with USB OTG into a USB webcam.
The problem is that the uvc-gadget project and the Linux UVC Gadget driver only support the UVC 1.1 specification (at least as of 2025-01). This means that we are limited to raw (YUYV422) or MJPEG video streams, no H264. Raw video streams at resolutions at or above 720p 30 fps are not suitable for the relatively low bandwidth (~300 Mbit real world max) USB 2.0 bus on the Pi Zero 2 W. MJPEG streams can easily push 1080p 60 fps over USB 2.0, and this is what most webcams do. My Pi Zero 2 W immediately jumps to 65°C and climbing when encoding an MJPEG stream, and that might be fine but it made me uncomfortable. I don't want to sacrifice the compact nature of the Zero 2 by adding cooling, and this could be running for hours at a time.
USB 2.0 is easily enough for an H264 stream, and the Pi's GPU could encode it without the heat problems of CPU encoded MJPEG. Unfortunately, there is no sign of the kernel supporting a later version of UVC in the near future.
Using raspicam-vid you could easily output an H264 UDP or HTTP stream that would be suitable for many purposes. However, not all software that accepts video input can grab a network stream. Pretty much everything understands a UVC device like my HDMI capture dongle.
Use your browser to navigate to [IP OF PI]:[PORT] to view the web controls.
The default port is 8000. This can be changed in hdmi-cam/hdmi_cam.sh
(Assigning a static ip to the Pi will make this more convenient).
- Continuous AF - Toggle auto focus. When continuous mode is off, Focus button triggers an auto focus cycle.
- Auto Exposure - Toggle auto exposure.
- EV - Exposure value. Offsets the auto exposure target in half stop increments.
- White Balance - Compensate for different light source colors.
Raspberry Pi OS Lite 64 bit (Bookworm)
- Raspberry Pi Zero 2 W
- Raspberry Pi Camera Module 3
- Mini HDMI to HDMI cable
- HDMI USB Capture dongle (This one worked for me)
- $15 Raspberry Pi Zero 2 W
- $25 Raspberry Pi Camera Module 3
- $16 HDMI Capture dongle
- <$10 Mini HDMI to HDMI cable
- <$10 USB power brick and cable
Total: $56 - $76
Install Picamera2 (documentation):
sudo apt install python3-picamera2
Install gunicorn:
sudo apt install gunicorn
Copy hdmi_cam.service to /home/pi/.config/systemd/user/
Copy hdmi-cam/ to /home/pi/
Make the scripts executable:
chmod u+x /home/pi/hdmi-cam/hdmi_cam.sh
chmod u+x /home/pi/hdmi-cam/hdmi-ctl.py
Enable and start the service:
systemctl --user enable hdmi_cam.service
systemctl --user start hdmi_cam.service
Run raspi-config and under System Options -> Boot / Auto Login choose Console Autologin


