video-to-ascii

An agent skill. Point it at a clip and it bakes the frames into a grid of brightnesses, small enough to ship, which a page can then read out as characters.

npx skills add NishantEC/skills --skill video-to-ascii

Or npx skills use NishantEC/skills@video-to-ascii to hand it to an agent once, without installing anything.

the demo

Below is a clip run through it, live. Replace it with one of your own and nothing about the path changes — same sampling, same crop, same bake.

cooking

Each frame is a grid of brightnesses, and turning one into text is picking a character per cell. The ramp is that lookup, ordered from empty to solid; contrast is the curve applied before it. Those are free — every control but one is a lookup on numbers that already exist, which is why moving them rebuilds the frame instantly.

Density is the one that isn't. It decides how many cells a frame is cut into, which is a property of the bake, so changing it runs the bake again.

Nothing is uploaded — the file becomes an object URL, a <video> element decodes it, and every frame is read out of a canvas, which is also why your machine does the work. Drag the divider to compare: one clock drives both sides, because a compare slider showing two different instants is worse than none.

how it works

Frames come out by seeking, never by playing, so every run gets the same ones. The subject is found by counting how often each row and column is lit, rather than by a union of per-frame boxes — those grow to fit the whole journey and frame a moving thing by where it has been. Cells are normalised against one global peak across the clip, because normalising per frame makes a dark frame as bright as a light one and the flicker reads as a fault.

The skill ships its measurements too, including the ones that made it worse.