Captions
This content is for v0.4. Switch to the latest version for up-to-date documentation.
Captions are timed text on their own track, drawn by the engine with the same text renderer as text generators. This page explains caption tracks, cues and their style, and how to import SubRip and WebVTT files. After reading it you can subtitle a video.
A caption track
Section titled “A caption track”A track with "kind": "caption" has no clips. Its captions hold:
cues: each aCaptionCuewith atimeline_rangeand atext, a plain string in which\nstarts a line. Cues are in timeline order and don’t overlap; a track shows one cue at a time.style: theTextStyleevery cue of the track is drawn in, the same style a text generator uses. By default, white text at 5% of the canvas’s shorter side, centred near the bottom.colorsets the text color,outlinea band around the glyphs andbackgrounda box behind each line.
A track has one style. To draw some cues in another style, such as a second speaker in another color, put them on a caption track of their own. Simultaneous captions also take one track each.
A caption track draws over the tracks before it and under the ones after it, so put it last to draw it on top.
{ "id": "subs", "name": "Subtitles", "kind": "caption", "captions": { "style": { "font_family": "Hanken Grotesk", "font_size": 0.06, "background": { "color": { "red": 0, "green": 0, "blue": 0, "alpha": 0.6 }, "padding": 0.3 } }, "cues": [ { "timeline_range": { "start": 0, "end": 240000 }, "text": "The tide comes in twice a day." }, { "timeline_range": { "start": 240000, "end": 480000 }, "text": "Every word lands on time." }, { "timeline_range": { "start": 480000, "end": 720000 }, "text": "One cue at a time." } ] }}Importing SRT and WebVTT
Section titled “Importing SRT and WebVTT”parseCaptions in alpha2/captions reads SubRip ("srt") or WebVTT ("webvtt") text with the engine’s own parser, and captionTrack builds a track from the cues:
import init, * as wasm from "alpha2/wasm";import { captionTrack, parseCaptions } from "alpha2/captions";
await init();const { rows, skipped } = parseCaptions(wasm, vttText, "webvtt");const tracks = rows.map((cues, index) => captionTrack(`subtitles-${index}`, "Subtitles", cues, { font_family: "Hanken Grotesk" }),);- Timestamps are exact: 1 ms is 120 ticks.
rowsholds one caption track’s cues per row. Cues that overlap in the file go to different rows, since a track shows one cue at a time, and a row holds at most 4096 cues, the most a track holds.- Markup is dropped: a cue keeps its plain text. WebVTT voices, classes and inline timestamps are not kept.
skippedcounts blocks that could not be read as a cue.
In the editor, importCaptions imports caption files in one undoable step. In Python, alpha2.compose.Captions takes SubRip, WebVTT, cues or word timestamps.
