Timeline
The whole transcript laid out on a scrolling time strip that slides under a fixed playhead, so every pause shows up as space between words
$ pnpm dlx shadcn@latest add @remocn/caption-timelineUsage
CaptionTimeline places every word of the transcript on a horizontal strip at
a position proportional to when it is spoken, pxPerSecond apart, and scrolls
the strip so the current moment sits under a fixed playhead. A pause in the
speech becomes empty space on the strip; when words come faster than the strip
can fit them, they are pushed apart so they never overlap. Words ahead of the
playhead are dimmed to upcomingOpacity and light up as the playhead reaches
them, and both ends of the strip fade out.
The strip is not paged, so combineTokensWithinMilliseconds and holdMs have
no effect, and it stays on screen for the whole transcript. Give it a fixed
width in composition pixels and place it yourself — see
Positioning and
Get a transcript.
import { AbsoluteFill } from "remotion";
import { CaptionTimeline } from "@/components/remocn/caption-timeline";
import captions from "./captions.json";
export const MyScene = () => (
<AbsoluteFill
style={{
justifyContent: "flex-end",
alignItems: "center",
paddingBottom: 108,
}}
>
<CaptionTimeline captions={captions} width={1600} />
</AbsoluteFill>
);Props13
| Prop | Type | Default |
|---|---|---|
| captions | Caption[]— The timed transcript, in the `Caption` shape from `@remotion/captions`. Times are relative to the start of the surrounding `Sequence`. | |
| width | number1100 Width of the visible strip in composition pixels. | |
| pxPerSecond | number260 How far apart one second of speech is on the strip — also the scroll speed during pauses. | |
| playheadPosition | number0.35 Where the playhead sits across the strip, from 0 (left edge) to 1 (right edge). | |
| playheadColor | string"#facc15" Colour of the playhead line. | |
| upcomingOpacity | number0.4 Opacity of words the playhead has not reached yet. | |
| fontSize | number64 Font size in pixels. | |
| fontWeight | number800 Font weight. The font itself is inherited. | |
| color | string"#ffffff" Text colour. | |
| shadow | booleantrue A tight text shadow that keeps the caption legible over bright footage. | |
| combineTokensWithinMilliseconds | number— Accepted for API parity with other caption styles; unused, since the strip is not paged. | |
| holdMs | number— Accepted for API parity with other caption styles; unused, since the strip never leaves the screen. | |
| className | string— Classes for the strip — font family, `uppercase`. | |
- captionsCaption[]
The timed transcript, in the `Caption` shape from `@remotion/captions`. Times are relative to the start of the surrounding `Sequence`.
Default
— - widthnumber
Width of the visible strip in composition pixels.
Default
1100 - pxPerSecondnumber
How far apart one second of speech is on the strip — also the scroll speed during pauses.
Default
260 - playheadPositionnumber
Where the playhead sits across the strip, from 0 (left edge) to 1 (right edge).
Default
0.35 - playheadColorstring
Colour of the playhead line.
Default
"#facc15" - upcomingOpacitynumber
Opacity of words the playhead has not reached yet.
Default
0.4 - fontSizenumber
Font size in pixels.
Default
64 - fontWeightnumber
Font weight. The font itself is inherited.
Default
800 - colorstring
Text colour.
Default
"#ffffff" - shadowboolean
A tight text shadow that keeps the caption legible over bright footage.
Default
true - combineTokensWithinMillisecondsnumber
Accepted for API parity with other caption styles; unused, since the strip is not paged.
Default
— - holdMsnumber
Accepted for API parity with other caption styles; unused, since the strip never leaves the screen.
Default
— - classNamestring
Classes for the strip — font family, `uppercase`.
Default
—