How it works

Every phone runs the same page and both roles at once: each films, each can drive the others. Whoever presses REC is the rider for that run.

Pair onceOne phone shows a QR code, the other scans it. Keys never travel over radio.
Arm & recordREC starts connected phones now; out-of-range phones join when you pass them.
Sync lazilyThumbnail, then proxy, then original — newest run first, resumable per chunk.

Two planes, on purpose

Control: Bluetooth LE

Discovery, authentication, arm/start/stop, status and clock sync. Works alone — with no Wi‑Fi at all, cameras still roll and still hold their footage.

Every command is authenticated with the per-pair key from QR pairing; replays are rejected by nonce, sequence and message ID.

Media: local Wi‑Fi

Thumbnails, proxies and originals move over TCP on whatever Wi‑Fi both phones share — resort Wi‑Fi, a portable router, or the rider's hotspot. No internet needed.

The LAN is assumed hostile: the handshake is mutually authenticated and media is encrypted with per-direction keys (AES‑256‑GCM, forward secrecy). Each chunk is hash-verified; a file is only marked complete after its whole-file hash checks.

Pairing

+ Connect phone opens a sheet: this phone's pairing QR on top, Scan a code below. Either phone can show or scan, and one code pairs many phones. The QR carries the secret optically — it is never broadcast.

Connect sheet with pairing QR and scan button
The connect sheet: show or scan.
Phone list with per-phone record toggles
Choose which phones record, per phone.
Empty state before any phone is paired
Fresh start: “No other phone yet”.

Capture details

Runs, captures, angles

A run is one press of REC, numbered by the rider. Each phone's recording of it is a capture; captures from the same run group into one clip with an angle count. Max duration 30 / 45 / 60 / 90 s; quality from Battery Saver 1080p30 to 4K60.

Scheduler: newest & smallest first

Contact windows last seconds, so the rider pulls metadata, thumbnails and proxies of the most recent run before spending bandwidth on older originals. Progress persists per chunk — a dropped connection resumes, never restarts.

Recording is durable

Once a camera acknowledges START, it records to local storage until STOP or the max duration — regardless of connectivity, UI state, or sync activity. Capture state is persisted so a crash or reboot cannot silently orphan a file.

Gallery, share, delete

Originals this phone records or pulls land in the system gallery under Movies/pose.video/. Long-press a clip to share the best local file or delete it (gallery entries included) — deleted runs are tombstoned so sync does not pull them again.

The full spec

The wire protocol, state machines and power model are documented in the open: docs/ in the repo — start at requirements.md, then architecture.md and protocol.md.