A simple WebSocket-based video streaming system from Raspberry Pi to a web interface.
- Backend: FastAPI WebSocket server that receives video from Pi and broadcasts to viewers
- Pi Connection: Python client that captures video from Pi Camera and streams via WebSocket
- Frontend: Simple HTML/JS viewer embedded in the backend
- Install dependencies:
cd backend
pip install -r requirements.txt- Run the server:
python main.pyThe server will start on http://0.0.0.0:8000
- Open a browser and go to
http://localhost:8000to view the stream
- Install system dependencies (if not already installed):
sudo apt-get update
sudo apt-get install -y python3-picamera2 python3-libcamera python3-pip libcap-dev- Create virtual environment with system-site-packages (required for libcamera access):
python3 -m venv --system-site-packages .venv
source .venv/bin/activate- Install Python dependencies:
pip install -r requirements.txt- Set up SSH tunnel from Pi to your desktop:
# On the Raspberry Pi, create SSH tunnel to desktop
ssh -L 8000:localhost:8000 your_username@your_desktop_ipKeep this SSH connection open in a separate terminal.
- Enable the camera:
sudo raspi-config
# Navigate to: Interface Options -> Camera -> Enable- Run the stream client (in a new terminal on the Pi):
python3 stream.pyThe client will connect to localhost:8000 which tunnels to your desktop.
-
Pi Side:
- Captures video frames from the Pi Camera
- Encodes frames as JPEG
- Sends frames via WebSocket to
/ws/piendpoint
-
Backend Side:
- Receives frames from Pi at
/ws/pi - Broadcasts frames to all connected viewers at
/ws/viewer - Serves a simple HTML viewer at the root URL
- Receives frames from Pi at
-
Viewer Side:
- Connects to
/ws/viewervia WebSocket - Receives JPEG frames as binary data
- Displays frames as images in the browser
- Connects to
GET /- HTML viewer interfaceWS /ws/pi- WebSocket endpoint for Pi to send streamWS /ws/viewer- WebSocket endpoint for viewers to receive streamGET /health- Health check endpoint
- Default port: 8000
- Change in the
uvicorn.run()call
- SERVER_HOST: localhost (via SSH tunnel)
- WIDTH/HEIGHT: Video resolution (default: 640x480)
- FPS: Frame rate (default: 20 fps)
The Pi connects to your desktop via SSH tunnel:
# From Pi to Desktop
ssh -L 8000:localhost:8000 user@desktop_ipThis forwards port 8000 on the Pi to port 8000 on your desktop.
- Ensure camera is enabled:
sudo raspi-config - Check camera connection:
libcamera-hello - Verify picamera2 installation:
python3 -c "import picamera2"
- Ensure SSH tunnel is active and running
- Check that backend server is running on desktop
- Verify SSH connection:
ssh user@desktop_ip - Test tunnel:
curl http://localhost:8000/health(from Pi)
- Lower FPS in
stream.py - Reduce resolution (e.g., 320x240)
- Check network bandwidth
- Add audio streaming
- Multiple camera support
- Recording functionality
- Authentication
- Better error handling
- Stream quality controls