uficap is a small service for UniFi Protect camera systems. Given a start time, a duration and a named group of cameras, it fetches the same window of footage from every camera, lines the clips up, and composes them into a single MP4 that can be watched, edited and shared.

What it does

A capture is requested over HTTP with a key the caller chooses:

PUT /captures/:key   {"start": "...", "duration_s": 20, "preset": "front"}

The request is idempotent and answers immediately with the URL where the finished video will live. The caller can store that URL before anything exists, and resend or delete the request if its event moves. uficap owns the job from there. It exports the footage through the UniFi client library, trims each camera's lead-in so the clips align, and tiles them with ffmpeg into one frame. A camera that had no footage is drawn as a "no footage" tile rather than silently dropped. The caller's identity and correlation tags are written into the file's metadata.

Because a capture keeps its per-camera sources, it can be rendered again in other ways:

360° fisheye cameras get dewarped views that act as tiles of their own, aimed by dragging on the camera's own image. A capture's window can be moved after the fact, and only the missing footage is fetched. A render can be shared with one person through a signed, expiring link, and a finished capture can be compacted to just the renders worth keeping.

How it is built

uficap is an Elixir application with Phoenix LiveView pages: a list of captures, a page to play, edit and manage one, a live view of every camera, and a page for building camera groups. It has no database. State that must survive a restart is kept as files in its data directory, and jobs are recovered at boot. It never talks to Protect directly. All console access goes through a single shared session of the UniFi client library, because the console rate-limits logins. ffmpeg and ffprobe are external tools, and if they are missing uficap refuses to start rather than failing mid-job. The test suite stubs the console at the library boundary and runs real ffmpeg on tiny generated clips.

It is designed for a trusted local network and is open by default, saying so at boot. Turning authentication on requires a login for the pages (local accounts or an LDAP directory) and a scoped, revocable token for the API. Each capture records which token made it.

Status

uficap 0.1.0 was its first release. It runs as a container image managed by a single-file control script, or as a release under systemd. It has been used against a real Protect console, and the timing of the console's exports was measured rather than assumed.