Speaker Label Captions
Multi-speaker caption track with name tags and colour coding. Install with npx remotion-ui@latest add speaker-label-captions.
PrimitiveData & mediaAdvanced
$ npx remotion-ui@latest add speaker-label-captionsA caption track for more than one voice: name tag, colour, and a side of the frame per speaker.
import { SpeakerLabelCaptions } from "@/remotion/primitives/speaker-label-captions";
import { parseSubtitles } from "@/remotion/lib/caption-utils";
<SpeakerLabelCaptions
cues={parseSubtitles(vttSource)}
speakers={[
{ name: "Nadia", color: "#e8b86d", align: "left" },
{ name: "Sam", color: "#2dd4bf", align: "right" },
]}
/>Identity three ways
Tag, colour and alignment all carry the speaker, because each one fails somewhere: a tag alone is slow to read at caption speed, colour alone is invisible to a good share of viewers, and alignment alone cannot separate three voices. Undeclared speakers get a colour from the palette and alternate sides in the order they first appear.
Cues
Timings are in milliseconds, so a track parsed from SRT or WebVTT drops straight
in — parseSubtitles already fills speaker from a WebVTT <v Name> tag.
Between cues the last card holds rather than clearing. A card blinking out in
every pause is more distracting than one that waits for the next line.
showPrevious keeps the line before it on screen, dimmed to about a third — it
is context, and matching the live line's weight would defeat both.
Where it sits
This is a track, not a frame: talking-head-layout handles the shot
composition. They compose — put this over that.
Speaker identity is carried by tag, colour and side at once, because each fails alone: a tag is slow to read at caption speed, colour is invisible to many viewers, and alignment cannot separate three voices. Between cues the last card holds — blinking out in every pause is worse than waiting.
Agent notes
Install first, then import the copied source component locally. AI guide →
@/remotion/primitives/speaker-label-captions- Use when: captioned videos, social clips, and synced text scenes.
- Customize: cues, speakers, defaultSpeaker, fontSize, plus copied source for timing, layout, colors, and typography.
- Rule: do not import this component from the
remotion-uinpm package; it is copied into your project.
Usage
import { SpeakerLabelCaptions } from "@/remotion/primitives/speaker-label-captions";
import { parseSubtitles } from "@/remotion/lib/caption-utils";
<SpeakerLabelCaptions
cues={parseSubtitles(vttSource)}
speakers={[
{ name: "Nadia", color: "#e8b86d", align: "left" },
{ name: "Sam", color: "#2dd4bf", align: "right" },
]}
/>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| cues | SubtitleCue[] | required | `{ text, startMs, endMs, speaker? }` — the shape `parseSubtitles` returns. |
| speakers | SpeakerStyle[] | [] | `{ name, color?, align? }` per voice. Undeclared voices are assigned. |
| defaultSpeaker | string | "Speaker" | Name for cues that carry none. |
| fontSize | number | 42 | Caption size. Tag and padding scale off it. |
| cardColor | string | rgba(12,12,18,0.82) | Plate behind a line. |
| maxWidth | number | 0.7 | Card width as a share of the frame. |
| showPrevious | boolean | true | Keep the previous speaker's card on screen, dimmed. |
| enterInFrames | number | 10 | Frames a card takes to arrive. |
| frame | number | undefined | Frame override — pass the parent frame inside a `<Sequence>`. |