Streams video (MJPEG) and audio (Raw PCM) from a USB webcam connected to a Raspberry Pi over the network via a simple web interface. Includes auto-detection for USB audio devices.
Author: Enzo Peres Afonso (2025)
- Streams video via MJPEG, viewable directly in most web browsers.
- Streams raw audio (PCM s16le), playable using tools like
aplay. - Simple web interface showing video feed and instructions.
- Automatic detection of USB audio input devices (can be overridden manually).
- Configurable video resolution, frame rate, and audio settings.
- Uses threading for concurrent audio/video capture and streaming.
- Includes basic troubleshooting tips in the web UI and console output.
- Graceful shutdown on Ctrl+C.
- Raspberry Pi (tested on Pi 3B+, Pi 4, should work on others)
- USB Webcam with built-in microphone (or a separate USB microphone)
- Power Supply for Raspberry Pi
- SD Card with Raspberry Pi OS (or similar Linux distribution)
- Network connection (Ethernet or WiFi)
- Operating System: Raspberry Pi OS (Legacy/Bullseye/Bookworm) recommended.
- Python: Python 3.7+
- pip: Python package installer.
- System Libraries:
portaudio19-dev: Required by PyAudio for audio I/O.libatlas-base-dev: Often needed for NumPy optimizations.libopenjp2-7: Dependency for OpenCV image formats.libavcodec-dev,libavformat-dev,libswscale-dev: FFmpeg libraries used by OpenCV.v4l-utils: Useful for listing and testing video devices (v4l2-ctl --list-devices).alsa-utils: Useful for listing and testing audio devices (arecord -l,aplay).
-
Update System & Install Prerequisites: Open a terminal on your Raspberry Pi and run:
sudo apt update sudo apt upgrade -y sudo apt install -y python3-pip python3-venv portaudio19-dev libatlas-base-dev libopenjp2-7 libavcodec-dev libavformat-dev libswscale-dev v4l-utils alsa-utils git
(Note: Some dependencies might already be installed)
-
Clone the Repository:
git clone https://github.com/enzoperesafonso/SAAO-IO-piStream.git cd SAAO-IO-piStream -
Set up Python Virtual Environment (Recommended):
python3 -m venv venv source venv/bin/activate # To deactivate later, just type 'deactivate'
-
Install Python Dependencies:
pip install -r requirements.txt
Most configuration options are at the top of the piStream.py script. Edit this file before running if needed:
AUDIO_DEVICE_INDEX: Leave asNoneto attempt auto-detection (searches for "USB" in the device name). If auto-detection fails or selects the wrong device, set this manually to the correct index number. Run the script once to see the list of detected devices and their indices, or usearecord -lin the terminal.VIDEO_DEVICE_INDEX: Usually0for the default USB webcam. Change if you have multiple cameras. Usev4l2-ctl --list-devicesto check.RATE: Crucial! Audio sample rate.48000or44100are common, but must match what your microphone supports. If you get "Invalid sample rate" errors, check the script's console output for instructions on usingarecord --dump-hw-paramsto find supported rates.CHANNELS: Typically1for mono microphones.FRAME_WIDTH,FRAME_HEIGHT,FRAME_RATE: Desired video resolution and FPS. The camera may not support all combinations; the script will report the actual settings used. Lower values reduce CPU load and network bandwidth.JPEG_QUALITY: Video compression quality (0-100). Lower values reduce bandwidth but decrease quality.75is a reasonable default.
-
Ensure Virtual Environment is Active (if used):
source venv/bin/activate -
Run the Server:
python piStream.py
-
Access the Stream:
- The script will print messages indicating which audio/video devices are being used and if the server started successfully.
- Find your Raspberry Pi's IP address (e.g., run
hostname -Iin another terminal). - Open a web browser on another computer on the same network and go to:
http://<YOUR_PI_IP>:5000(replace<YOUR_PI_IP>). - You should see the video stream and instructions for accessing the audio stream.
-
Listening to Audio: The web page provides an example command using
aplay(part ofalsa-utils). You'll needalsa-utilsandcurlinstalled on the client machine listening to the audio:# On the client machine (e.g., your laptop): # Make sure rate (-r), format (-f), channels (-c) match the server config! curl -N http://<YOUR_PI_IP>:5000/audio.raw | aplay -r 48000 -f S16_LE -c 1 -
Press Ctrl+C in the terminal where the script is running.
- Check Console Output: The script prints detailed information about device detection, errors, and chosen settings when it starts. Look here first!
- No Video / "Could not open video device":
- Verify the camera is securely connected.
- Check
VIDEO_DEVICE_INDEXinstream_server.py. - Run
v4l2-ctl --list-deviceson the Pi to see detected video devices and their paths (e.g.,/dev/video0). - Ensure the camera isn't being used by another application.
- Try a lower resolution/framerate.
- No Audio / "Error initializing audio stream" / "Invalid sample rate":
- Verify the microphone is connected.
- Check
AUDIO_DEVICE_INDEXinstream_server.py. Let the script run once to see the detected devices and indices, or usearecord -l. - Verify the
RATEsetting. This is the most common audio issue. Use thearecord --dump-hw-params -D hw:X,Ycommand (findX,Yfromarecord -l) as suggested in the script's error output to find the rates your hardware actually supports. Editstream_server.pyand restart. - Ensure the user running the script has permissions for audio devices (usually ok if in the
audiogroup - check withgroups $USER).
- Audio Sounds Bad / Glitchy:
- Could be network congestion or high CPU load on the Pi. Try lowering video resolution/framerate/quality.
- Ensure the
aplayparameters on the client exactly match the server'sRATE,FORMAT(S16_LE = 16-bit signed little-endian), andCHANNELS.
- Permission Denied Errors: Add the current user to the
videoandaudiogroups:sudo usermod -aG video $USERandsudo usermod -aG audio $USER. You may need to log out and log back in for changes to take effect. - High CPU Usage: Streaming video, especially encoding, can be demanding. Lowering
FRAME_WIDTH,FRAME_HEIGHT,FRAME_RATE, orJPEG_QUALITYcan help significantly.