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
Intelligent Camera Detection
PiCamera2 Web Streamer now includes intelligent camera detection that ensures it always finds the correct camera device, even if Linux changes the /dev numbering:
- USB ID Detection: Identifies cameras by vendor and product ID (e.g., Arducam 12MP = 0c45:636d)
- Name Pattern Matching: Falls back to identifying cameras by name
- Configuration Options: Fine-tune detection through config.ini
- Diagnostic Tool: Use
examples/find_camera.py
to troubleshoot camera detection
Configuration Options
In config.ini
, you can configure camera detection:
[camera]
usb_camera_id = 0c45:636d
Improved Logging System
The new version includes a robust logging system:
- Configurable Log Levels: Set log verbosity in config.ini with DEBUG, INFO, WARNING, ERROR, or CRITICAL
- Automatic Log Rotation: Prevents log files from growing too large
- Log Compression: Old logs are automatically compressed to save space
Logs are stored in /var/log/picamera2-webstream.log
and rotated weekly.
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
- Run the diagnostic tool:
python examples/find_camera.py
-
Camera found but with incorrect device:
- The system automatically detects the correct USB camera
- Specify a USB ID in config.ini:
usb_camera_id = vendor:product
- Run the diagnostic tool to verify:
python examples/find_camera.py
-
Excessive logging:
- Reduce log level in config.ini:
level = WARNING
- Check service configuration:
Environment=LIBCAMERA_LOG_LEVELS=*:WARNING
- Rotate logs manually:
sudo logrotate /etc/logrotate.d/picamera2-webstream
-
ImportError for picamera2:
- Make sure system packages are installed:
sudo apt install python3-libcamera python3-picamera2
- Ensure you're using the virtual environment
-
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