pi-webrtc

Recording

pi-webrtc can save MP4 video files and JPEG snapshots on the device, all the time or only when a viewer asks. Recording uses the full camera resolution, even when WebRTC lowers the streaming resolution.

Pages

  • Storage: record to a USB drive, or to a disk image with a fixed size.
  • Timelapse: turn snapshots into a timelapse video.

What and when

Two options control recording. --record-type sets what to save, and --record-mode sets when:

--record-type=video--record-type=snapshot--record-type=both (default)
--record-mode=backgroundMP4 files, all the timeJPEGs at a fixed intervalBoth
--record-mode=on-demandMP4 files while a viewer asksJPEGs while a viewer asksBoth
--record-mode=both (default)Two recorders, in two directories

Nothing is saved until you set a path. The background recorder needs --record-path. The on-demand recorder needs --record-ondemand-path, which defaults to <record-path>/on-demand/. Both must be absolute paths. If pi-webrtc cannot create the directory, that recorder stays off.

./pi-webrtc ... --record-path=/mnt/ext_disk/video
Format
VideoH.264
AudioAAC
Snapshot and thumbnailJPEG

Files on disk

Files are sorted into folders by date and hour, and named after the time they start:

/mnt/ext_disk/video/
└── 20260730/
    ├── 09/
    │   ├── 20260730_090000.mp4
    │   ├── 20260730_090000.jpg
    │   ├── 20260730_090100.mp4
    │   └── 20260730_090100.jpg
    └── 10/
        └── ...

Every MP4 file has a .jpg preview from the same video. Clients use it to draw a thumbnail grid quickly.

  • --file-duration sets the length of each video file: 60 seconds by default. In snapshot mode, it is the time between snapshots.
  • --jpeg-quality sets the quality of snapshots and thumbnails.

If pi-webrtc stops or the power goes off, the current file still plays, up to about its last second. This needs FFmpeg 7.1 or newer.

Rotation

Every 60 seconds, pi-webrtc checks the free space on the recording disk. While less than 400 MB is free, it deletes the oldest hour of files. MP4 and .jpg files are deleted together, and empty date and hour folders are removed.

So the disk keeps as much history as fits, and recording never stops because the disk is full. To keep recording away from the system disk, give it its own disk. See Storage.

On-demand recording

With --record-mode=on-demand (or both), a connected viewer starts and stops recording over the DataChannel. This is useful when you want video of events, not of everything.

CommandPayloadResponse
START_RECORDINGnoneRecordingResponse { is_recording: true, filepath }
STOP_RECORDINGnoneRecordingResponse { is_recording: false, filepath }

The response contains the path of the file. The client can download it later with TRANSFER_FILE.

On-demand files are saved under --record-ondemand-path, apart from the background recordings. So rotation and browsing treat them separately.

Browsing recordings

Clients list and download recordings over the same DataChannel. QUERY_FILE returns file details: the path, the length, and a small base64 JPEG thumbnail. TRANSFER_FILE sends the file itself, in chunks.

QueryFileRequest takes a type and a parameter:

TypeParameterReturns
LATEST_FILEnoneThe newest complete file
BEFORE_FILEA file name, for example 20260719_103000.mp4Up to 8 files older than that one
BEFORE_TIMEA time, for example 20260719_103000The file at that time, or the one before it

The mode field selects the set of files:

  • RECORDING: the recordings under --record-path, in the date and hour folders above.
  • TIMELAPSE: the files in <record-path>/timelapse, for timelapse videos that you made yourself. See Timelapse.

The DataChannel also has TAKE_SNAPSHOT, for one JPEG at a chosen quality, and CONTROL_CAMERA, to change the image controls while running. See DataChannels.

Edit on GitHub

On this page