Grand Diomande Research · Full HTML Reader

Photography — Interval Capture and StageView Console

Photography is the third generative output of the system. Unlike music (continuous) and visuals (continuous), photography is discrete: the system captures moments.

Embodied Trajectory Systems research note experiment writeup candidate score 28 .md

Full Public Reader

Photography — Interval Capture and StageView Console

The Photography System

Photography is the third generative output of the system. Unlike music (continuous)
and visuals (continuous), photography is discrete: the system captures moments.

The design goal is to make the photographer invisible. The dancer moves; stills
appear without anyone pressing a button. The iPhones are the cameras; the iPad
is the control console.

Camera Nodes

Each iPhone in the system is a self-contained camera node. It:
- Serves a live MJPEG stream at `:8081/stream` (30fps)
- Handles `POST /capture` to take a still photo (AVCapturePhotoOutput)
- Runs its own interval timer (2/3/5/8 second automatic capture)
- Advertises itself on Bonjour as `_mmcam._tcp`
- Sends SSE events (`GET /events`) for `still_captured`, `session_changed`, `status`

The iPhone can operate as a camera node while simultaneously running the full
SAN/audio pipeline (primary performance device) or in camera-only mode (no SAN,
no audio — just the camera service).

StageView: The Operator Console

StageView is an iPad app that discovers all camera nodes and gives the operator
a unified view of the entire camera rig.

Discovery:
- Bonjour: `NetServiceBrowser` listens for `_mmcam._tcp` announcements
- mDNS hostname prober: `getaddrinfo` probes `iPhone-*.local.` hostnames
- /24 subnet scanner: parallel HTTP probes of all IPs in the iPad's subnet
- Extra subnet scan: always scans `10.0.0.x`, `10.0.1.x`, `192.168.0.x`,
`192.168.2.x` to catch devices on different WiFi networks
- Manual IP entry: + button allows adding Tailscale or non-standard IPs

Live feeds:
Each discovered node streams its MJPEG feed to StageView. The UIView-based
`MJPEGFeedView` renders frames via `CATransaction.setDisableActions(true)` on
`layer.contents` — required to bypass iOS 26 beta's implicit animation regression.

Controls (per-camera or "all" fan-out):
- Capture: fire shutter on one or all cameras
- Interval: start/stop auto-shoot timer with selectable period
- Lens: switch between wide/main/tele (device-dependent)
- Zoom: set magnification factor
- Torch: flash mode
- Session: assign a session name/ID for organizing stills

The Contact Sheet

As stills are captured, each iPhone sends a `still_captured` SSE event with a
thumbnail (base64-encoded JPEG thumbnail, ~5KB). StageView's SSE client receives
these events and appends the thumbnails to a horizontal contact sheet strip at
the bottom of the operator view.

This gives the operator a live curation view — they can see what's being captured
in real time without picking up any phone.

Interval Timer Logic

The interval timer (`IntervalShootController.swift` on iPhone) fires
`PhotoCaptureService.capture()` at the configured interval. The default periods
match the standard photography/filmmaking intervals: 2s (action), 3s (standard),
5s (considered), 8s (slow/portrait).

All iPhones in a session run their own independent timers started simultaneously
from StageView. The timers are not synchronized by a clock signal — they are
started at approximately the same time by fan-out HTTP calls. For posed stills,
this ~100ms jitter between phones is acceptable.

(Frame-perfect synchronization would require a scheduled-timestamp capture API,
which is a noted future option if needed for action sequences.)

ShootView: Curation

ShootView (the second iPad, or same iPad in a different app) aggregates all stills
from all camera nodes and provides:

Gallery: All stills from all phones in one scrollable grid, sorted by timestamp.
Star-rating for selection. Filter by session, camera, time range.

Filter: Per-image CoreImage filters (crop, exposure, saturation, contrast,
grain). All on-device, no server required.

Reel: `ReelComposer` assembles stills into a video: `AVMutableComposition` +
`AVMutableVideoComposition`, configurable seconds-per-still (1.5–4.0),
transition styles (cut, dissolve, zoom), duration targets (15/30/45/60s).
Exports 1080×1920 H.264 to the Photos library.

Lookbook: `LookbookRenderer` (1188 lines) builds a PDF from a curated selection
of stills. Layout, typography, page count — configurable. Shares via AirDrop or
saves to Files.

The Laptop-Free Vision

The entire photography system — discovery, live feed monitoring, capture control,
curation, reel building, lookbook rendering — runs on iOS devices only. No laptop,
no Mac, no multicam-server required.

The multicam-server (the Rust server at `:9404`) was the predecessor: it ran on
Mac1 and coordinated all devices centrally. The current architecture distributes
that function: each iPhone owns its own state, StageView orchestrates them without
a server in the loop.

This makes outdoor shoots, location shoots, and portable setups feasible. Two iPhones
and two iPads on a shared WiFi (or a phone hotspot) are the entire rig.

Hardware in the Photography Rig

DeviceRole
iPhone 16 Plus (`880B4058`)Primary camera node + SAN performer device
iPhone 16 Pro Max (`84109044`)Secondary camera node
iPhone 14 Pro Max (`45896348`)Third camera node (camera-only mode)
iPad A16 (`1938B9B3`)StageView operator console
iPad A16 (`1DE6FABC`)ShootView curation / second StageView

Promotion Decision

Attach run IDs, datasets, metrics, and reproduction commands.

Source Anchor

computational-choreography/04-generative-output/photography.md

Detected Structure

Method · Evaluation · Figures · Code Anchors · Architecture