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.