The short answer: record the live prototype, not the screenshots. The prototypes
already animate and already drive themselves, so OpenScreen's demo-script path does
almost all of the work — and the same markdown file is both the browser choreography
and the narration.
c12-ios-demo.md 18 beats · drives prototype/ · 4:14
c12-android-demo.md 18 beats · drives prototype-android/ · 4:29
rolemodel-openscreen has a format built for exactly this shape
(lib/demo-script.mjs): one markdown file where prose is narration and fenced
`do blocks are browser actions. parseScript skips fenced blocks, so
rm-voice reads the same file unchanged and the actions are invisible to it.
Better still, the pace is derived from the words before anything is recorded —
165 wpm, measured — so a step that carries a line *holds long enough for the line*.
Alignment is structural, not something to fix in the edit.
The two files here are already in that format, generated from
VO-SCRIPT.md and VO-SCRIPT-ANDROID.md.
They point at the published prototypes, so they work from any machine.
| Approach | Verdict | |
|---|---|---|
| 1 | Demo script against the live prototype | Use this. Real motion — the gold tab pill slides, the summary types itself, the blur clears, fields fly into the form. None of that exists in a PNG. |
| 2 | openscreen record while pressing Space | Good fallback. The prototype's autoplay runs the whole walkthrough unattended. Simpler, but the timing is the prototype's, not the narration's. |
| 3 | Build scenes from the 52 PNGs | Only for cutaways. Use components/scene.html + render-scene.mjs if you want a split-screen iOS-vs-Android section. |
Everything happens in Openscreen.app (Spotlight → Openscreen). Do not launch it
from a terminal — macOS grants Screen Recording to whatever hosts Electron, and a
shell launch grants it to your terminal instead.
scripts/ folder. The library layout is .
One clip per line, measured, and the SRT is written from durations it already
knows. /voice af_nova is set at the top of each file; change it there.
the do blocks.
```bash
node ~/Development/openscreen/rolemodel-openscreen/bin/rm-video.mjs brand \
c12-ios.openscreen --preset rolemodel --variant master \
--title "C12 — the native app" --eyebrow "UX Assessment" \
--watermark --duration-ms 254000
```
Android is --duration-ms 269000.
```bash
/Applications/Openscreen.app/Contents/MacOS/Openscreen export \
c12-ios.openscreen -o c12-ios.mp4 --auto-zoom --json
```
lib/share.mjs publishes the finished video as a page withtimestamped notes on it. That is a better review surface for C12 than a file in
Slack, and it is the same review loop the rest of the toolkit uses.
Match the title against what openscreen sources actually returns — never guess.
&shot=1, if you want the device alone on a transparent-ready background. For the
film the rail is useful context, so the scripts leave it on.
--auto-zoom earns its keep here. The device is a tall rectangle in a wideframe; auto-zoom pushes in on the phone rather than letterboxing it.
platforms, so a split-screen cut works without re-timing anything.
If the narration changes, rebuild them so the two cannot drift.
The do blocks address real selectors — #glassBar .tb[data-tab='3'],
[data-act='draft'], .tsctl b[data-ts='3']. Renaming those in the prototype
breaks the recording, so change both together.
cd c12/audit/video
./record.sh ios # ~8 min, unattended
./record.sh android
Records, brands and exports. Renders land in video/out/, which is git-ignored. Open Openscreen.app from Spotlight at least once first — never from a terminal.