10. API - Streams

The picamera library defines a few custom stream implementations useful for implementing certain common use cases (like security cameras which only record video upon some external trigger like a motion sensor).

10.1. PiCameraCircularIO

class picamera.PiCameraCircularIO(camera, size=None, seconds=None, bitrate=17000000, splitter_port=1)[source]

A derivative of CircularIO which tracks camera frames.

PiCameraCircularIO provides an in-memory stream based on a ring buffer. It is a specialization of CircularIO which associates video frame meta-data with the recorded stream, accessible from the frames property.

Warning

The class makes a couple of assumptions which will cause the frame meta-data tracking to break if they are not adhered to:

  • the stream is only ever appended to - no writes ever start from the middle of the stream
  • the stream is never truncated (from the right; being ring buffer based, left truncation will occur automatically); the exception to this is the clear() method.

The camera parameter specifies the PiCamera instance that will be recording video to the stream. If specified, the size parameter determines the maximum size of the stream in bytes. If size is not specified (or None), then seconds must be specified instead. This provides the maximum length of the stream in seconds, assuming a data rate in bits-per-second given by the bitrate parameter (which defaults to 17000000, or 17Mbps, which is also the default bitrate used for video recording by PiCamera). You cannot specify both size and seconds.

The splitter_port parameter specifies the port of the built-in splitter that the video encoder will be attached to. This defaults to 1 and most users will have no need to specify anything different. If you do specify something else, ensure it is equal to the splitter_port parameter of the corresponding call to start_recording(). For example:

import picamera

with picamera.PiCamera() as camera:
    with picamera.PiCameraCircularIO(camera, splitter_port=2) as stream:
        camera.start_recording(stream, format='h264', splitter_port=2)
        camera.wait_recording(10, splitter_port=2)
        camera.stop_recording(splitter_port=2)
frames

Returns an iterator over the frame meta-data.

As the camera records video to the stream, the class captures the meta-data associated with each frame (in the form of a PiVideoFrame tuple), discarding meta-data for frames which are no longer fully stored within the underlying ring buffer. You can use the frame meta-data to locate, for example, the first keyframe present in the stream in order to determine an appropriate range to extract.

clear()[source]

Resets the stream to empty safely.

This method truncates the stream to empty, and clears the associated frame meta-data too, ensuring that subsequent writes operate correctly (see the warning in the PiCameraCircularIO class documentation).

copy_to(output, size=None, seconds=None, first_frame=PiVideoFrameType.sps_header)[source]

Copies content from the stream to output.

By default, this method copies all complete frames from the circular stream to the filename or file-like object given by output.

If size is specified then the copy will be limited to the whole number of frames that fit within the specified number of bytes. If seconds if specified, then the copy will be limited to that number of seconds worth of frames. Only one of size or seconds can be specified. If neither is specified, all frames are copied.

If first_frame is specified, it defines the frame type of the first frame to be copied. By default this is sps_header as this must usually be the first frame in an H264 stream. If first_frame is None, not such limit will be applied.

Warning

Note that if a frame of the specified type (e.g. SPS header) cannot be found within the specified number of seconds or bytes then this method will simply copy nothing (but no error will be raised).

The stream’s position is not affected by this method.

10.2. CircularIO

class picamera.CircularIO(size)[source]

A thread-safe stream which uses a ring buffer for storage.

CircularIO provides an in-memory stream similar to the io.BytesIO class. However, unlike io.BytesIO its underlying storage is a ring buffer with a fixed maximum size. Once the maximum size is reached, writing effectively loops round to the beginning to the ring and starts overwriting the oldest content.

The size parameter specifies the maximum size of the stream in bytes. The read(), tell(), and seek() methods all operate equivalently to those in io.BytesIO whilst write() only differs in the wrapping behaviour described above. A read1() method is also provided for efficient reading of the underlying ring buffer in write-sized chunks (or less).

A re-entrant threading lock guards all operations, and is accessible for external use via the lock attribute.

The performance of the class is geared toward faster writing than reading on the assumption that writing will be the common operation and reading the rare operation (a reasonable assumption for the camera use-case, but not necessarily for more general usage).

getvalue()[source]

Return bytes containing the entire contents of the buffer.

read(n=-1)[source]

Read up to n bytes from the stream and return them. As a convenience, if n is unspecified or -1, readall() is called. Fewer than n bytes may be returned if there are fewer than n bytes from the current stream position to the end of the stream.

If 0 bytes are returned, and n was not 0, this indicates end of the stream.

read1(n=-1)[source]

Read up to n bytes from the stream using only a single call to the underlying object.

In the case of CircularIO this roughly corresponds to returning the content from the current position up to the end of the write that added that content to the stream (assuming no subsequent writes overwrote the content). read1() is particularly useful for efficient copying of the stream’s content.

readable()[source]

Returns True, indicating that the stream supports read().

readall()[source]

Read and return all bytes from the stream until EOF, using multiple calls to the stream if necessary.

seek(offset, whence=0)[source]

Change the stream position to the given byte offset. offset is interpreted relative to the position indicated by whence. Values for whence are:

  • SEEK_SET or 0 – start of the stream (the default); offset should be zero or positive
  • SEEK_CUR or 1 – current stream position; offset may be negative
  • SEEK_END or 2 – end of the stream; offset is usually negative

Return the new absolute position.

seekable()[source]

Returns True, indicating the stream supports seek() and tell().

tell()[source]

Return the current stream position.

truncate(size=None)[source]

Resize the stream to the given size in bytes (or the current position if size is not specified). This resizing can extend or reduce the current stream size. In case of extension, the contents of the new file area will be NUL (\x00) bytes. The new stream size is returned.

The current stream position isn’t changed unless the resizing is expanding the stream, in which case it may be set to the maximum stream size if the expansion causes the ring buffer to loop around.

writable()[source]

Returns True, indicating that the stream supports write().

write(b)[source]

Write the given bytes or bytearray object, b, to the underlying stream and return the number of bytes written.

lock

A re-entrant threading lock which is used to guard all operations.

size

Return the maximum size of the buffer in bytes.

10.3. BufferIO

class picamera.BufferIO(obj)[source]

A stream which uses a memoryview for storage.

This is used internally by picamera for capturing directly to an existing object which supports the buffer protocol (like a numpy array). Because the underlying storage is fixed in size, the stream also has a fixed size and will raise an IOError exception if an attempt is made to write beyond the end of the buffer (though seek beyond the end is supported).

Users should never need this class directly.

getvalue()[source]

Return bytes containing the entire contents of the buffer.

read(n=-1)[source]

Read up to n bytes from the buffer and return them. As a convenience, if n is unspecified or -1, readall() is called. Fewer than n bytes may be returned if there are fewer than n bytes from the current buffer position to the end of the buffer.

If 0 bytes are returned, and n was not 0, this indicates end of the buffer.

readable()[source]

Returns True, indicating that the stream supports read().

readall()[source]

Read and return all bytes from the buffer until EOF.

readinto(b)[source]

Read bytes into a pre-allocated, writable bytes-like object b, and return the number of bytes read.

seek(offset, whence=0)[source]

Change the buffer position to the given byte offset. offset is interpreted relative to the position indicated by whence. Values for whence are:

  • SEEK_SET or 0 – start of the buffer (the default); offset should be zero or positive
  • SEEK_CUR or 1 – current buffer position; offset may be negative
  • SEEK_END or 2 – end of the buffer; offset is usually negative

Return the new absolute position.

seekable()[source]

Returns True, indicating the stream supports seek() and tell().

tell()[source]

Return the current buffer position.

truncate(size=None)[source]

Raises NotImplementedError as the underlying buffer cannot be resized.

writable()[source]

Returns True, indicating that the stream supports write().

write(b)[source]

Write the given bytes or bytearray object, b, to the underlying buffer and return the number of bytes written. If the underlying buffer isn’t large enough to contain all the bytes of b, as many bytes as possible will be written before raising IOError.

size

Return the maximum size of the buffer in bytes.