A real motion-compensated codec, fed a broken stream until the video melts.
A procedural video loop is compressed by a miniature MPEG-style codec: YCbCr frames cut into 8x8 macroblocks, keyframes coded with a quantized DCT, and P-frames coded as motion vectors (found by a rate-penalized diamond search) plus DCT residuals, skip blocks and intra fallbacks, all written to an Exp-Golomb bitstream with one slice per block row. A separate decoder parses those bytes. Datamoshing is feeding that decoder a stream it was never meant to see: drop the keyframe at a scene cut and the next shot's vectors drag the previous shot's pixels around; repeat a P-frame and its vectors push the same pixels again and again. Flipping bytes makes the parser lose sync for the rest of a slice, and the damage overlay follows the broken blocks as later frames copy them forward until a clean keyframe gets through.
Try it. Click the video to corrupt bytes at that block and watch the damage spread. Drag to paint your own motion vectors into the stream. Hold Bloom (or B) to duplicate the current P-frame, toggle keyframe dropping (K), scale or reverse the vectors (G), show the vector field (V), send a clean keyframe (H) and pause (Space).
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a datamosh toy with JavaScript and the HTML canvas element: a tiny video codec that I can break on purpose. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a 320x200 offscreen canvas and draw a short animated "video" into it each frame with ordinary canvas calls: two scenes of about three seconds each with plenty of motion, for example colored circles drifting across a gradient, then a rotating, zooming flower of petals.
- Write an encoder that works on 8x8 blocks of the frame. A keyframe just stores the pixels. Every other frame is a P-frame: for each block, search a small window (say plus or minus 8 pixels) in the previous decoded frame for the best match by sum of absolute differences, and store that motion vector plus the leftover difference (the residual), rounded to multiples of 16 so most of it becomes zero.
- Write a separate decoder that rebuilds each frame from the previous decoded frame, the vectors and the residuals, and show its output scaled up to fill the window.
- Send a keyframe whenever the scene changes.
Once that works, break it:
- Add a "drop keyframes" toggle. When it is on, skip keyframes at scene cuts, so the second scene's motion drags the first scene's pixels around. That smear is datamoshing.
- Hold a key to repeat the last P-frame's vectors over and over (a "bloom"), and add a multiplier that scales every vector.
- Let me drag on the video to paint my own motion vectors into the blocks under the pointer.
- Draw the motion vectors as little lines on top when I press V.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as coding the residual with an 8x8 DCT, writing everything to a real bitstream so flipped bits can desynchronize the decoder, or tracking which blocks inherit corrupted data.