# Loom Capture Tool

Bun/Node script that captures Loom video walkthroughs as frame sequences when no transcript is available. Built for the JV project where Umar shares fast cursor-pointing demos via Loom.

## Captures stored here

| Folder | Loom | Date | Duration | Frames | Notes |
|---|---|---|---|---|---|
| `1-june-pdp-walkthrough/` | https://www.loom.com/share/ce4501e9de834cfdae628c60fe9e41d3 | 1 Jun 2026 | 2:12 | 45 | Umar walks through the JV "High Strength Calcium Citrate" PDP showing empty Results + FAQ sections; ends on a competitor reference. The direct brief on what content needs populating. |
| `21-may-uiux-walkthrough/` | https://www.loom.com/share/55449ee0013148e7936344b83caf9ba8 | 21 May 2026 | 2:42 | 54 | Broader UI/UX walkthrough showing reference patterns from Wild Nutrition (Scientific Studies), Spacegoods (Timeline), Grüns + Club EarlyBird (Comparison Tables), JV's own Figma (Results, FAQs). |

Each folder contains:
- `frame-000.png` … `frame-NNN.png` — full-resolution frames at 3-second intervals
- `contact-sheet.jpg` — 6-col grid of all frames for fast scanning
- `manifest.json` — frame index → seconds + mm:ss
- `transcript.txt` — Loom transcript JSON (both videos are **empty** — Umar didn't enable auto-transcription, returns `{"phrases":[],"schemaVersion":"1.1.3"}`)

## Re-capture a Loom

```sh
cd tools/loom-capture
node capture.mjs <loom-share-or-embed-url> ./out-folder [intervalSeconds]
```

Examples:
```sh
node capture.mjs https://www.loom.com/share/<id> ./my-capture 3
node capture.mjs https://www.loom.com/share/<id> ./my-capture 5   # less granular, faster
```

Notes:
- Script auto-converts `/share/<id>` → `/embed/<id>?autoplay=true` so the **real video** loads instead of Loom's 4-second preview clip.
- Cleans the target folder before re-running.
- Writes `manifest.json` mapping frame index → timestamp.
- Builds a `contact-sheet.jpg` (6 columns) via local ffmpeg using `%03d` sequence pattern (Windows-compatible — no `glob` support needed).

## Try to fetch the transcript

```sh
node transcript.mjs <loom-share-url> ./out/transcript.txt
```

Strategies it tries (in order):
1. Parse `__NEXT_DATA__` on the share page for embedded transcript URL
2. Intercept network responses during embed playback (`cdn.loom.com/mediametadata/transcription/<id>-2.json` + `captions/<id>-2.vtt`)
3. Toggle captions UI if present
4. Direct GET against well-known endpoints

For both JV Looms the endpoint returns an empty phrases array, confirming Umar didn't enable transcription. If a Loom returns a VTT, the script also writes a `.plain.txt` stripped version.

## Dependencies

- Node 18+ (tested on Node 24)
- `playwright` (installed locally in this folder via `npm i playwright` + `npx playwright install chromium`)
- `ffmpeg` on PATH (any modern build — globbing not required)

## Why frames-not-video?

Loom doesn't expose its mp4 publicly without auth, so direct `yt-dlp`-style download fails. Frame capture via Playwright `<video>` element seek + screenshot is the cleanest fallback — no auth, decent visual fidelity, fast to scan via the contact sheet.

## Where this fits in the project

These captures are the visual ground truth for the **4 PDP sections** Umar wants populated (Scientific Studies, Timeline/Results, Comparison Tables, FAQs). The plan referencing them is `../../PLAN_v2_2026-06-02.md`.
