CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-picamera2

The libcamera-based Python interface to Raspberry Pi cameras, based on the original Picamera library

Pending
Overview
Eval results
Files

recording.mddocs/

Video Recording and Encoding

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.

Capabilities

Recording Control

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
    """

Encoder Management

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)
    """

Encoder Classes

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 = 5

Concrete Encoder Implementations

Available 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 Classes

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
    """

Usage Examples

Basic Video Recording

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()

High-Quality Recording

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()

Multiple Encoder Recording

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()

Circular Buffer Recording

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()

Streaming with FFmpeg

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()

Convenience Recording

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")

Audio Recording

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()

Quality Control

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

docs

advanced.md

capture.md

configuration.md

controls.md

core-operations.md

index.md

preview.md

recording.md

tile.json