Skip to content

P5 Recorder

Lumlux Art Lab

P5 Recorder

Turn a p5.js sketch into an MP4 file. How to use it, and how to read what it tells you.

Start here

  1. Paste your sketch into the panel on the left. An example loads by default — replace it, or pick another from the dropdown above the editor.
  2. Set the output. Size, length, frame rate and bitrate are on the right. The defaults (1920×1080, 10 s, 30 fps, 12 Mbps) are a good place to start.
  3. Run preview. The sketch plays in the black frame, looping over the length you chose. This is exactly what will be recorded, at the same virtual speed.
  4. Record MP4. The tape fills up as frames are encoded. Nothing leaves your computer.
  5. Save file. The button lights up when the file is ready.

Reading the panel

The frame tape

The wide strip is a counter, not a progress bar in the usual sense. Each tick is one second of finished video. The blue fill is how much of the clip has been encoded, and the number above it is the exact frame.

Recording is not real time. A heavy sketch may take a minute to produce ten seconds of video; a light one can be faster than real time. Either way the result is exactly the length you asked for — the tape tells you where you are, not how long you still have to wait.

The status word

ShowsMeaning
idleNothing running. Safe to edit code or change settings.
preparingChecking the encoder and loading your sketch into the sandbox.
recordingFrames are being drawn and encoded. Leave the tab in the foreground.
flushingAll frames are in. The encoder is finishing the last few and the file is being assembled.
doneFollowed by the file size. Save file is now active.
failedSomething stopped. The reason is the red line in the log at the bottom left.

The encoder badge

Top right. It shows which H.264 profile your browser gave you, for example h.264 ready — avc1.640034. If it says no encoder was found, MP4 export is off in this browser; see Browsers.

The log

Bottom left, under the editor. Blue lines are normal progress. Red lines are errors from your sketch, with the message p5 gave — a red line usually means a typo or an undefined variable, not a problem with the recorder.

What the settings actually change

SettingWhat it doesHow to choose
Output sizePixel size of the MP4.1920×1080 for landscape, 1080×1920 for stories and TikTok, 1080×1080 for feed posts. Odd numbers get rounded down — H.264 needs even dimensions.
Resize canvasForces your canvas to the output size after setup().Leave it on unless your sketch lays itself out in setup() and breaks when resized. Off means the recording uses whatever size your sketch made.
LengthClip duration, and therefore the frame count.10 s covers most loops. Longer clips take proportionally longer and produce bigger files.
Frame rateFrames per second in the file.30 is the safe default. 60 for fast motion. 25 if the clip has to sit next to European broadcast footage.
BitrateHow much data per second of video, so how much detail survives compression.8–12 Mbps is fine for social. Push to 20–30 if you have fine grain, dense particles or heavy noise, which compress badly. Roughly: file size in MB ? Mbps × seconds ÷ 8.
Random seedFixes random() and noise() so every render is identical.Leave empty while exploring. Fill it in once you find a version you want to be able to reproduce.
p5 versionWhich p5 library is loaded.1.11.13 runs almost anything written in the last decade. Switch to 2.3.2 only if your sketch was written for it.

Time inside the recorder

This is the part worth understanding, because it is where recorders normally go wrong.

A screen recorder captures whatever the browser managed to draw. When a frame takes too long, it gets dropped and the motion stutters. This tool does the opposite: it draws frame 1, waits for it, encodes it, then asks for frame 2. Nothing is dropped, ever.

To make that work, the clock inside your sketch is virtual. millis(), deltaTime and frameCount all follow the frame number rather than the wall clock. A frame that takes two seconds to compute still advances time by exactly 1/fps.

Practical consequence: motion that looks right in the preview will look right in the file, no matter how slow your machine is.

Writing a sketch that loops

Four values are handed to your sketch: RENDER_W, RENDER_H, RENDER_FPS and RENDER_FRAMES. The last one is the total number of frames in the clip.

Drive everything from a single normalised time value and the last frame will meet the first:

function setup() {
  createCanvas(RENDER_W, RENDER_H);
}

function draw() {
  const t = frameCount / RENDER_FRAMES;   // 0 ? 1 across the clip
  background(18);
  translate(width / 2, height / 2);
  rotate(TWO_PI * t);                     // exactly one turn
  rect(-100, -100, 200, 200);
}

Anything that returns to its starting value at t = 1 will loop: sin(TWO_PI * t), cos(TWO_PI * t), a full rotation, a noise field sampled around a circle. Anything that only ever increases — a counter, a position that drifts — will jump at the loop point.

WEBGL

Use createCanvas(RENDER_W, RENDER_H, WEBGL). The recorder detects it and switches on the setting that keeps the drawing buffer readable; without it a 3D sketch records as black frames. You do not have to do anything.

What is not supported yet

Loading external files — loadImage(), loadFont(), loadModel(), loadJSON() — is blocked. The sandbox has no network access, on purpose. Generate what you need in code, or wait for the next version.

Browsers

MP4 export needs WebCodecs, the browser’s built-in video encoder. That means Chrome or Edge. In Safari and Firefox the preview works and the Record button is switched off with a note in the log.

Keep the tab in the foreground while recording. Browsers throttle background tabs, and although no frames will be lost, the render will crawl.

When something goes wrong

SymptomCause and fix
Black video, 3D sketchYou are drawing outside the visible depth range, or the canvas was created without WEBGL. Check the preview first — if the preview is black, the file will be too.
Red line: undefinedA p5 error from your own code. The message names the variable or function.
“No draw() function found”Your sketch uses instance mode, or draw is nested inside something. The recorder needs a global draw().
The loop jumpsSomething in the sketch is driven by a value that keeps growing instead of by frameCount / RENDER_FRAMES.
File looks mushyRaise the bitrate. Fine noise and dense particles are the hardest things to compress.
Different result every renderEnter a seed.
Nothing happens on RecordCheck the badge top right. No encoder means wrong browser.

Where the file goes

Nowhere but your own downloads folder. The sketch runs in an isolated frame with no network access, the encoding happens on your machine, and the tool has no server behind it. Nothing you paste is stored or sent anywhere.

ENEnglishNLNederlandsSoonFRFrançaisSoonDEDeutschSoonESEspañolSoonITItalianoSoonPTPortuguêsSoon中文中文Soon日本語日本語Soon