Frame-by-frame video viewer that runs directly in the browser with no dependencies.
Link: https://cristianosword.github.io/player-frame-a-frame/
Precise frame-by-frame video analysis tool. Useful for animation, motion analysis, scene review, and any workflow that needs exact playback control.
Open index.html in any modern browser. No install or local server is required.
Load a video by dragging it into the drop area or clicking to open the file picker. Supported formats include MP4, WebM, MOV, AVI, and any other format accepted by the browser.
| Control | Description |
|---|---|
| progress bar | Jump to any point in the video by dragging the slider. |
| prev / next | Move exactly one frame backward or forward using the configured FPS. |
| play / pause | Start or pause playback in real time. |
| speed | Goes from -8x to 8x, including reverse playback. |
| volume | Adjust audio levels or toggle mute. |
| snapshot | Capture and download the current frame as a PNG image. |
| FPS | Defines the frame duration used by frame stepping. Default: 24 fps. |
| loop | Repeats automatically when the video reaches the beginning or end. |
| Key | Action |
|---|---|
← → or J L |
Step backward / forward one frame |
space or K |
Play / pause |
M |
Toggle mute |
1-7 |
Quick playback speed select (0.25x to 4x) |
Shortcuts are ignored while an editable field is focused.
| Field | Description |
|---|---|
| frame | Current frame number calculated from time and FPS. |
| time | Current position in seconds with millisecond precision. |
| duration | Total video length. |
| resolution | Width x height in pixels. |
The main code is split into:
index.html: page structure.style/main.css: styles.player-core.js: pure player logic helpers.app.js: DOM integration, events, state, and translations.
npm testThe video is rendered onto a <canvas> layered over the <video> element, allowing precise frame inspection. Files stay local and are never uploaded.
Frame accuracy depends on how the browser seeks through the source video. Videos with sparse keyframes may still be imprecise on long jumps.
