PiCamera2 Web Streamer
A Flask-based web streaming solution for Raspberry Pi cameras using PiCamera2. Stream your Raspberry Pi camera feed securely over HTTPS with minimal latency.
Features
- Real-time MJPEG streaming over HTTPS
- Adaptive frame rate based on client connections
- Clean shutdown handling
- Mobile-responsive web interface
- Thread-safe implementation
- Configurable camera parameters
- Resource-efficient with multiple client support
Dependencies
A split installation approach ensures compatibility with Raspberry Pi OS while keeping application-specific dependencies isolated.
System Packages (installed via apt)
- python3-libcamera
- python3-picamera2
- python3-opencv
- python3-numpy
Virtual Environment Packages (installed via pip)
- flask
- Additional Python-only dependencies
Installation
Via pip
pip install picamera2-webstream
Quick Installation
For a quick automated installation:
git clone https://github.com/glassontin/picamera2-webstream.git
cd picamera2-webstream
For an ffmpeg based webstream:
./install_ffmpeg.sh
For a picamera2 OpenCV based webstream use:
./install_picamera.sh
The installation script will:
- Install all required system dependencies
- Enable the camera interface
- Set up a Python virtual environment
- Install Python package dependencies
- Generate SSL certificates
- Add your user to the video group
- Verify camera detection
After installation completes:
- Log out and log back in (required for video group access)
- Activate the virtual environment:
source venv/bin/activate
- Run the example:
python examples/ffmpeg_stream.py
- Open
https://your-pi-ip
in your browser
To uninstall:
./uninstall.sh
Usage
Two streaming implementations are available:
1. FFmpeg-based (Recommended)
from picamera2_webstream import FFmpegStream, create_ffmpeg_app
stream = FFmpegStream(
width=1280,
height=720,
framerate=30,
device='/dev/video0'
).start()
app = create_ffmpeg_app(stream)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=443, ssl_context=('cert.pem', 'key.pem'))
Advantages:
- Lighter weight (fewer dependencies)
- Hardware acceleration where available
- Better performance for basic streaming
- Works with both USB and CSI cameras
- Lower CPU usage
2. PiCamera2-based
from picamera2_webstream import VideoStream, create_picamera_app
stream = VideoStream(
resolution=(1280, 720),
framerate=30,
brightness=0.0,
contrast=1.0
).start()
app = create_picamera_app(stream)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=443, ssl_context=('cert.pem', 'key.pem'))
Advantages:
- Full PiCamera2 feature set
- More camera controls
- Better for image processing
- Native Raspberry Pi camera support
- Access to raw camera data
Choosing the Right Implementation
Use FFmpeg-based streaming when:
- You need basic video streaming
- You want minimal dependencies
- CPU resources are limited
- You're using a USB webcam
Use PiCamera2-based streaming when:
- You need advanced camera controls
- You want to do image processing
- You need raw camera data
- You're using the Raspberry Pi camera module
Accessing the Stream
For either implementation:
- Open your browser and navigate to
https://your-pi-ip
- Accept the self-signed certificate warning
- View your camera stream!
Camera Configuration
Automatic Configuration
To find the optimal settings for your camera, run the diagnostic tool:
python examples/camera_diagnostics.py
This will:
- Detect all available cameras
- Show detailed camera capabilities
- Test different resolutions and formats
- Measure actual achievable framerates
- Suggest optimal configuration settings
Manual Configuration
You can customize various parameters when initializing the VideoStream:
stream = VideoStream(
resolution=(1280, 720),
framerate=30,
format="MJPEG",
brightness=0.0,
contrast=1.0,
saturation=1.0
)
Common camera settings:
- Resolution: Common values include (1920, 1080), (1280, 720), (640, 480)
- Format: Usually "MJPEG" for web streaming
- Framerate: Higher values (30+) for smooth video, lower values (15-) for reduced bandwidth
To see all available settings for your camera:
v4l2-ctl --list-devices
v4l2-ctl -d /dev/videoX --all
v4l2-ctl -d /dev/videoX --list-formats-ext
For USB cameras, you might also want to check:
lsusb -v | grep -A 10 "Video"
Performance Considerations
- Higher resolutions and framerates require more CPU and bandwidth
- MJPEG format provides good quality with reasonable bandwidth usage
- If streaming over the internet, consider lower resolutions and framerates
- Monitor CPU usage and network bandwidth to find optimal settings
Development
If you want to modify the code:
- Create a development environment:
git clone https://github.com/glassontin/picamera2-webstream.git
cd picamera2-webstream
python3 -m venv venv
source venv/bin/activate
pip install -e .
- Run tests (once implemented):
pip install pytest
pytest
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Thanks to the picamera2 team for their excellent camera interface
- The Flask team for their lightweight web framework
Troubleshooting
Common issues and solutions:
-
Camera not detected:
- Ensure the camera is properly connected
- Check if the camera interface is enabled in
raspi-config
- Verify with
libcamera-hello
command
-
ImportError for picamera2:
- Make sure system packages are installed:
sudo apt install python3-libcamera python3-picamera2
- Ensure you're using the virtual environment
-
SSL Certificate issues:
- Regenerate certificates if they've expired
- Ensure certificates are in the same directory as the script
-
Permission denied errors:
- Ensure your user is in the video group:
sudo usermod -a -G video $USER
- Logout and login again for group changes to take effect