Picamera2
Python library for the Raspberry Pi camera with streaming support
Picamera2 is the official Python library for controlling Raspberry Pi cameras using the libcamera stack. It can be used to build self-hosted surveillance applications with live streaming, capture, and motion-based recording.
Key features
- libcamera-based Pi camera control
- MJPEG and H.264 streaming
- Capture and recording
- Scriptable in Python
Pros & cons
Strengths
- Official and well-documented
- Flexible for DIY systems
Trade-offs
- Library, not a full NVR
- Raspberry Pi specific
Picamera2 replaces
Last reviewed Sep 13, 2026 · 805 words
Picamera2 is the right tool when you are writing the camera code, and the wrong tool when you just want a camera that records. It is Raspberry Pi's official Python library over libcamera, preinstalled on Raspberry Pi OS, BSD-2-Clause licensed, and it gives you a capture loop, an MJPEG or H.264 encoder and a file or network output in about 15 lines. What it does not give you is a web UI, a timeline, motion zones or a retention policy; those are an NVR's job, and a Pi with Picamera2 makes an excellent camera for Frigate or MotionEye rather than a replacement for them. Decide which side of that line you are on before you write anything.
Fifteen lines to a live stream
A minimal MJPEG server, roughly the mjpeg_server.py example in the repository, is enough to view the camera from any browser on the LAN:
from picamera2 import Picamera2
from picamera2.encoders import MJPEGEncoder
from picamera2.outputs import FileOutput
picam2 = Picamera2()
picam2.configure(picam2.create_video_configuration(main={"size": (1280, 720)}))
picam2.start_recording(MJPEGEncoder(), FileOutput(stream))
where stream is a small class that buffers each frame and an http.server handler that writes them out as multipart/x-mixed-replace. Swap MJPEGEncoder for H264Encoder and FileOutput for FfmpegOutput("-f rtsp rtsp://localhost:8554/cam") and the Pi publishes an RTSP feed that any NVR can consume, with a MediaMTX or go2rtc process holding the stream. That second pattern is the one I actually run: Picamera2 as the sensor driver, everything else off the Pi.
Pi 5 has no hardware encoder, and it matters
The Pi 4 and Zero 2 W encode H.264 in hardware, so a 1080p30 stream costs almost nothing. The Pi 5 dropped the hardware encoder, and Picamera2's H264Encoder on it runs in software on the CPU; 1080p30 is achievable but eats a core, and 4K from a Camera Module 3 or HQ camera is not realistic. MJPEG is cheap everywhere but 10 times the bandwidth. Plan the resolution and framerate around the board you have: 720p at 15 fps on a Zero 2 W with 256 MB free RAM, 1080p at 30 fps on a Pi 4, and CPU headroom on a Pi 5 if you also want to run detection on it.
Motion recording without an NVR
Picamera2 ships a CircularOutput that keeps the last few seconds of encoded video in RAM, so a script that detects motion can write a clip that starts before the trigger. The repository's capture_motion.py example compares consecutive frames from a low-resolution second stream with numpy and starts recording above a threshold; that is a 40-line DIY equivalent of the motion daemon. It is good for a doorbell-style single camera. It falls over the moment you want 3 cameras, object detection rather than pixel change, and a UI to review last night, which is where a proper NVR earns its RAM.
The libcamera break, and which camera to buy
Anything written for the old picamera library or raspistill does not work on current Raspberry Pi OS; the legacy stack was removed and Picamera2 with rpicam-apps replaced it. When copying examples, check the import line. On hardware, the Camera Module 3 (12 MP, autofocus, about 25 dollars at last check) is the default; the HQ Camera takes C-mount lenses for a fixed outdoor view; the Global Shutter camera is for fast motion. Third-party sensors need a device tree overlay and often a vendor libcamera fork, which is where "Raspberry Pi specific" in the cons becomes "one specific Pi image".
The bigger tools to compare against
For a no-code camera on the Pi itself, MotionEye wraps the motion daemon with a web UI and supports libcamera cameras through a streamer. For a multi-camera home system, Frigate on a separate x86 box or a Pi 5 with a Coral accelerator and each Pi camera as an RTSP source is the setup I recommend, and the video surveillance category lays out the field. Picamera2 sits underneath all of them on the camera side; it is never the thing you look at.
What I'd do
Write a 30-line Picamera2 script that publishes H.264 over RTSP through MediaMTX, run it as a systemd service on a Pi 4 or Zero 2 W with a Camera Module 3, and add that RTSP URL to Frigate. Keep the script dumb: no detection, no storage, no UI on the camera. Buy a Pi 5 for the NVR side rather than the camera side, because of the encoder. And if you only want one camera watching a doorway with clips in a folder, the CircularOutput motion example is a perfectly good evening project that needs nothing else installed.
Compare Picamera2
1 head-to-head comparisons.
Similar video surveillance apps
MediaMTX
Video SurveillanceReady-to-use media server and RTSP/WebRTC proxy
Replaces Wowza
go2rtc
Video SurveillanceUltimate camera streaming gateway with low latency
Replaces Nest Cam
OpenALPR
Video SurveillanceAutomatic license plate recognition library
Replaces Rekor Scout, Plate Recognizer
CompreFace
Video SurveillanceSelf-hosted face recognition service with REST API
Replaces Amazon Rekognition
OpenCvSharp
Video Surveillance.NET wrapper for OpenCV computer vision
Replaces Commercial vision SDKs
ZoneMinder
Video SurveillanceFull-featured closed-circuit television software suite
Replaces Blue Iris, Milestone XProtect