Adom Video — Hydrogen-webview video player
UnreviewedFrame-accurate video player for Adom containers. Plays .webm/.mp4 with native HTML5 controls + custom toolbar. Path rows click-to-reveal in VS Code Explorer; extract/trim outputs auto-reveal too. CLI-
adom-video
Hydrogen-webview video player. Plays .webm / .mp4 from disk with frame-accurate scrub, A-B loop, pixel zoom up to 8×, gallery thumbnails, and frame-extract / trim.
CLI- and HTTP-drivable so Claude can seek, pause, extract-frame, and trim without simulating clicks.
Demo

Watch the 6-section feature tour: final.webm
The tour covers:
- Player + native controls + custom toolbar — a clip plays with the full HTML5 controls bar (timeline, volume, speed menu, fullscreen, picture-in-picture) AND the custom toolbar for everything the native bar doesn't give you.
- Folder gallery — every clip auto-probed for codec, resolution, frame count, recorded-at time parsed from the filename.
- Scrub + A-B loop — frame-step with
,., set markers withIO, instant loop fires. - Pixel zoom + pan — zoom up to 8× with pixel-perfect rendering, drag to pan.
- Extract frame → reveal in VS Code — files land next to the source clip in
extracts/and auto-reveal in the VS Code Explorer. - CLI + HTTP — every action exposed as a CLI subcommand and an HTTP endpoint.
Why this exists
adom-desktop produces screen and tab recordings as WebM. Until this tool, every demo round-tripped through the desktop ("send the file home, open it manually, scrub manually, screenshot a frame manually"). adom-video play <file> opens a tab next to VS Code, plays in a loop, and exposes every action as a CLI/HTTP call.
Quick use
adom-video play /tmp/recording.webm # one-clip player
adom-video play /tmp/recordings/ # gallery for the directory
adom-video gallery /tmp/recordings/ # explicit gallery view
adom-video probe /tmp/recording.webm # ffprobe → JSON
adom-video extract-frame v.webm 3.5 -o frame.png
adom-video trim v.webm 1.0 5.0 -o clip.webm
Extracts and trims land in <clip-folder>/extracts/<stem>-frame-<MMmSSsMMM>.png and <clip-folder>/trims/<stem>-trim-<in>-<out>.<ext> — sortable filenames, sane location, auto-revealed in the VS Code Explorer sidebar (sidebar is forced visible too).
Drive an open player from outside (port auto-discovered via /tmp/adom-video.port)
adom-video seek 12.5 # jump to t=12.5s in the open tab
adom-video pause
adom-video resume
adom-video set-rate 0.5 # half speed
adom-video status # current state JSON
adom-video stop # close tab + shut down server
HTTP API
| Method · Path | Purpose |
|---|---|
GET /api/library |
List clips with metadata + filename hints (rec-desktop-*, rec-tab-*) |
GET /api/state |
Current player state (file, currentTime, paused, rate, in/out points, zoom) |
POST /api/seek {t} |
Jump to time |
POST /api/pause {} · POST /api/resume {} |
|
POST /api/rate {rate} |
0.25 → 4.0 |
POST /api/zoom {zoom} |
1.0 → 8.0 |
POST /api/loop {t_in, t_out} |
Set A-B loop range |
POST /api/load {path} |
Load a different clip into the open player |
POST /api/extract-frame {path, t, out?} |
Write PNG, auto-reveal, return path |
POST /api/trim {path, t_in, t_out, output?} |
Stream-copy webm/mp4, auto-reveal |
POST /api/reveal {path} |
Reveal any path in the VS Code Explorer (forces sidebar visible) |
GET /api/console |
Recent JS console output (forwarded from the UI) |
GET /api/thumb?path=&t=&w= |
JPEG thumbnail (cached) |
Keyboard shortcuts
| Key | Action |
|---|---|
| Space / K | Play / pause |
| J / L | Slow down / speed up (0.25× → 4×) |
| ← / → | −5s / +5s · Shift = ±1s · Alt = ±0.1s |
| , / . | Previous / next frame (uses fps from probe) |
| 0–9 | Jump to 0%, 10% … 90% |
| I / O | Set A / B loop point · Shift+I/O = clear |
| + / − | Zoom in/out (1× → 8×) · 0 = reset · drag to pan when zoomed |
| F | Fullscreen |
| M | Mute |
| G | Toggle gallery view |
| ? | Show shortcut help |
Filename hints
Recordings produced by adom-desktop are auto-detected:
rec-desktop-<unix-ms>.webm→ taggeddesktop, recorded-at parsed from filenamerec-tab-<session>-<tab>-<unix-ms>.webm→ taggedtab
The Inspector panel surfaces this plus codec / dimensions / FPS / frame count / duration / bit rate / file size / encoder / clickable Folder + Path rows that reveal in the VS Code Explorer.
How the FPS is computed
Chrome MediaRecorder writes r_frame_rate=1000/1 and avg_frame_rate=1000/1 as placeholder values — both useless. adom-video probe falls back to ffprobe -count_packets and divides by duration when the reported FPS is implausible (>120 fps). For typical desktop screen recordings this gives the real capture rate (15–30 fps).
Architecture
- Rust +
tiny_http. Single static binary, ~1.6 MB. - HTTP byte-range support — required for
<video>element seek (the native scrubber works because of this). - ffprobe + ffmpeg must be on PATH.
- Server writes
/tmp/adom-video.portso subcommands find a running instance. - Always opens on a non-VS-Code Hydrogen pane — never covers Claude Code chat.
- Container webview URL uses
$VSCODE_PROXY_URIsubstitution (nolocalhost:baked in). - HTML uses
<base href="./">so relative URLs work in the proxied iframe. - Reveal-in-VS-Code via
adom-vscode reveal+adom-vscode sidebar show(sidebar forced visible so the highlighted entry is in view).
Brand
Adom dark + teal. Familjen Grotesk (headlines), Satoshi (body), JetBrains Mono (timecode + paths). Monochrome white SVG icons. No emoji.
License
AGPL-3.0-or-later.