The libcamera-based Python interface to Raspberry Pi cameras, based on the original Picamera library
—
Video recording capabilities with support for multiple encoders, various output formats, and hardware acceleration. The encoding system provides both simple recording methods and advanced encoder management for complex applications.
High-level recording interface for common video capture scenarios.
def start_recording(
self,
encoder: Encoder,
output: Output,
pts: str = None,
config: CameraConfiguration = None,
quality: Quality = None,
name: str = "main"
):
"""
Start video recording with specified encoder and output.
Parameters:
- encoder: Encoder instance (H264Encoder, MJPEGEncoder, etc.)
- output: Output instance (FileOutput, CircularOutput, etc.)
- pts: str, PTS file path for timestamp logging
- config: CameraConfiguration, configuration to apply before recording
- quality: Quality enum value for encoding quality
- name: str, stream name to encode
Raises:
- RuntimeError: If encoder fails to start or configuration invalid
"""
def stop_recording(self):
"""
Stop all active recording and encoding operations.
Stops all encoders and outputs, finalizes files, and releases resources.
"""
def start_and_record_video(
self,
output: str,
encoder: Encoder = None,
config: CameraConfiguration = None,
quality: Quality = None,
duration: float = None,
show_preview: bool = None,
audio: bool = False
):
"""
Convenience method to start camera and record video.
Parameters:
- output: str, output file path
- encoder: Encoder instance (default: H264Encoder)
- config: CameraConfiguration (default: video configuration)
- quality: Quality enum value
- duration: float, recording duration in seconds (None for indefinite)
- show_preview: bool, show preview during recording
- audio: bool, enable audio recording
"""Low-level encoder control for advanced recording scenarios.
def start_encoder(
self,
encoder: Encoder,
output: Output,
pts: str = None,
quality: Quality = None,
name: str = "main"
):
"""
Start individual encoder without stopping existing encoders.
Parameters:
- encoder: Encoder instance
- output: Output instance
- pts: str, PTS file path
- quality: Quality enum value
- name: str, stream name to encode
Returns:
Encoder instance that was started
"""
def stop_encoder(self, encoders: list[Encoder] = None):
"""
Stop specific encoders.
Parameters:
- encoders: list of Encoder instances to stop (None = stop all)
"""Base encoder class and available encoder implementations.
class Encoder:
"""Base class for video encoders."""
# Properties
running: bool # Whether encoder is active
width: int # Frame width
height: int # Frame height
size: tuple[int, int] # Frame dimensions
stride: int # Row stride
format: str # Input pixel format
output: Output # Output destination(s)
name: str # Encoder name
# Audio properties
audio: bool # Enable audio encoding
audio_input: dict # Audio input parameters
audio_output: dict # Audio output parameters
audio_sync: int # Audio sync offset
def encode(self, stream: str, request: CompletedRequest):
"""
Encode frame from request (abstract method).
Parameters:
- stream: str, stream name
- request: CompletedRequest with frame data
"""
def start(self, quality: Quality = None):
"""
Start encoding process.
Parameters:
- quality: Quality enum value
"""
def stop(self):
"""Stop encoding and finalize output."""
def outputframe(
self,
frame: bytes,
keyframe: bool = False,
timestamp: int = None,
packet: bytes = None,
audio: bytes = None
):
"""
Output encoded frame to destination.
Parameters:
- frame: bytes, encoded frame data
- keyframe: bool, whether frame is a keyframe
- timestamp: int, frame timestamp
- packet: bytes, packet data
- audio: bytes, audio data
"""
class Quality(Enum):
"""Encoding quality levels."""
VERY_LOW = 1
LOW = 2
MEDIUM = 3
HIGH = 4
VERY_HIGH = 5Available encoder types for different formats and use cases.
class H264Encoder(Encoder):
"""
H.264 video encoder with hardware acceleration when available.
Parameters:
- bitrate: int, target bitrate in bits/second
- framerate: float, target framerate
- repeat: bool, repeat sequence parameter sets
- iperiod: int, I-frame period (keyframe interval)
- profile: str, H.264 profile ("baseline", "main", "high")
- level: str, H.264 level ("3.1", "4.0", "4.1", etc.)
- intra_refresh: str, intra refresh mode
"""
class MJPEGEncoder(Encoder):
"""
MJPEG video encoder for high-quality sequential JPEG frames.
Parameters:
- q: int, JPEG quality (1-100)
"""
class JpegEncoder(Encoder):
"""
JPEG still image encoder for single frame capture.
Parameters:
- q: int, JPEG quality (1-100)
"""
class LibavH264Encoder(Encoder):
"""
H.264 encoder using libav/FFmpeg backend.
Parameters:
- preset: str, encoding preset ("ultrafast", "fast", "medium", etc.)
- crf: int, constant rate factor (0-51, lower = better quality)
- bitrate: int, target bitrate
"""
class LibavMjpegEncoder(Encoder):
"""MJPEG encoder using libav/FFmpeg backend."""
class MultiEncoder(Encoder):
"""
Composite encoder that manages multiple encoders simultaneously.
Allows encoding the same stream to multiple formats/outputs.
"""Output destinations for encoded video data.
class Output:
"""Base class for encoder outputs."""
recording: bool # Whether currently recording
pts_output: str # PTS timestamp file path
needs_pacing: bool # Whether output needs frame pacing
def start(self):
"""Start recording to output."""
def stop(self):
"""Stop recording and finalize output."""
def output_frame(
self,
frame: bytes,
keyframe: bool = False,
timestamp: int = None,
packet: bytes = None,
audio: bytes = None
):
"""Output encoded frame (abstract method)."""
def output_timestamp(self, timestamp: int):
"""Output timestamp to PTS file."""
class FileOutput(Output):
"""
Output to file with automatic format detection.
Parameters:
- filename: str, output file path
- pts: str, PTS file path for timestamps
"""
class FfmpegOutput(Output):
"""
Output via FFmpeg process for complex formats and streaming.
Parameters:
- cmd: list, FFmpeg command line arguments
- audio: bool, enable audio passthrough
"""
class CircularOutput(Output):
"""
Circular buffer output for continuous recording with size limit.
Parameters:
- filename: str, output file path
- buffersize: int, buffer size in seconds
- outputtofile: bool, write to file when buffer full
"""
class SplittableOutput(Output):
"""
Output that can split recording into multiple files.
Parameters:
- filename_template: str, filename template with placeholders
- split_size: int, split size in MB or seconds
"""from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import FileOutput
import time
picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)
picam2.start()
# Create encoder and output
encoder = H264Encoder(bitrate=10000000) # 10 Mbps
output = FileOutput("video.h264")
# Start recording
picam2.start_recording(encoder, output)
# Record for 10 seconds
time.sleep(10)
# Stop recording
picam2.stop_recording()
picam2.close()from picamera2 import Picamera2
from picamera2.encoders import H264Encoder, Quality
from picamera2.outputs import FileOutput
picam2 = Picamera2()
# High-resolution video configuration
video_config = picam2.create_video_configuration(
main={"size": (1920, 1080), "format": "YUV420"}
)
picam2.configure(video_config)
picam2.start()
# High-quality encoder
encoder = H264Encoder(
bitrate=20000000, # 20 Mbps
framerate=30,
profile="high",
level="4.1"
)
output = FileOutput("high_quality.h264")
# Record with high quality setting
picam2.start_recording(encoder, output, quality=Quality.VERY_HIGH)
time.sleep(30) # 30 second recording
picam2.stop_recording()
picam2.close()from picamera2 import Picamera2
from picamera2.encoders import H264Encoder, MJPEGEncoder
from picamera2.outputs import FileOutput
picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)
picam2.start()
# Multiple encoders for same stream
h264_encoder = H264Encoder(bitrate=10000000)
mjpeg_encoder = MJPEGEncoder(q=85)
h264_output = FileOutput("video.h264")
mjpeg_output = FileOutput("video.mjpeg")
# Start both encoders
picam2.start_encoder(h264_encoder, h264_output)
picam2.start_encoder(mjpeg_encoder, mjpeg_output)
time.sleep(15)
# Stop all encoders
picam2.stop_recording()
picam2.close()from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import CircularOutput
picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)
picam2.start()
encoder = H264Encoder()
# Keep last 30 seconds in buffer
circular_output = CircularOutput("buffer.h264", buffersize=30)
picam2.start_recording(encoder, circular_output)
# Record continuously - only last 30s kept in memory
# On motion detection or trigger, save buffer to file
input("Press Enter to save buffer and stop...")
# Save buffer content
circular_output.outputtofile = True
picam2.stop_recording()
picam2.close()from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import FfmpegOutput
picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)
picam2.start()
encoder = H264Encoder()
# Stream to RTMP server
ffmpeg_output = FfmpegOutput([
"-f", "h264",
"-i", "-",
"-c:v", "copy",
"-f", "flv",
"rtmp://localhost/live/stream"
])
picam2.start_recording(encoder, ffmpeg_output)
# Stream indefinitely
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
picam2.stop_recording()
picam2.close()from picamera2 import Picamera2
from picamera2.encoders import H264Encoder, Quality
picam2 = Picamera2()
# All-in-one recording method
picam2.start_and_record_video(
"recording.h264",
duration=60, # 60 seconds
quality=Quality.HIGH,
show_preview=True
)
# Camera automatically starts, records, and stops
print("Recording complete")from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import FfmpegOutput
picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)
picam2.start()
# Encoder with audio support
encoder = H264Encoder(bitrate=10000000)
encoder.audio = True
# Output with audio muxing
output = FfmpegOutput([
"-f", "h264", "-i", "-",
"-f", "alsa", "-i", "hw:1", # Audio input
"-c:v", "copy",
"-c:a", "aac",
"video_with_audio.mp4"
])
picam2.start_recording(encoder, output)
time.sleep(30)
picam2.stop_recording()
picam2.close()from picamera2 import Picamera2
from picamera2.encoders import H264Encoder, Quality
from picamera2.outputs import FileOutput
picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)
picam2.start()
# Test different quality levels
qualities = [Quality.VERY_LOW, Quality.LOW, Quality.MEDIUM,
Quality.HIGH, Quality.VERY_HIGH]
for i, quality in enumerate(qualities):
encoder = H264Encoder()
output = FileOutput(f"test_quality_{i}.h264")
picam2.start_recording(encoder, output, quality=quality)
time.sleep(5) # 5 second clips
picam2.stop_recording()
picam2.close()Install with Tessl CLI
npx tessl i tessl/pypi-picamera2