Animated captions for your product
One renderFrame draws word-level animated captions on canvas: live over a <video> in the browser, and frame for frame into an MP4 with FFmpeg. No headless browser.
MIT licensed · React-free core · Node + FFmpeg for server renders
SamecaptionsinyourbrowserandinFFmpeg
Styles
Pick a look, ship it everywhere
Each preset is a plain object: use it as is or clone and tweak it. The same preset runs in the browser preview and in the FFmpeg render.
Every preview is rendered by the engine itself, the same way npx captions.js burn renders your video.
Styles the engine is getting next. These are motion sketches in CSS, not engine renders yet. Want one first? Upvote or request it on GitHub.
Use it
One renderer, four ways in
import captionsjs, { getPreset, toCaptions } from "captions.js";
const video = document.querySelector("video")!;
// Deepgram response or a plain [{ word, startTime, endTime }] array
const captions = toCaptions(transcript);
const instance = captionsjs({
video,
preset: getPreset("Karaoke"),
captions,
});
// live updates, no remount
instance.preset(getPreset("Focus Box"));
instance.captions(editedCaptions);
instance.destroy();Features
Kinetic captions, identical in both places
Preview equals export
The browser overlay and the FFmpeg render call the same renderFrame on the same Konva scene. What your user styles is what comes out.
No headless browser
Server renders run on skia-canvas piped into FFmpeg. No Chrome in your production pipeline.
26 style presets
Karaoke, Focus Box, Banger, Neon Pulse, Cinema and more. Each preset is a plain object you can clone and edit.
10 word animations
bounce, pop, scale, box, box-word, underline, slide-left, slide-up, slide-down or none.
Any word timings
toCaptions() reads a Deepgram response or a plain word array; the server also takes Whisper verbose_json.
Full typography
Google Fonts on demand, stroke, shadow, capitalization, active and past word colors, sentence-aware line breaks.
Put animated captions in your product this afternoon.
Rather not run render servers? captions.js Cloud is in early access.