This component no longer exists. It was in remotionui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-11 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
karaoke-captions
remotionui/karaoke-captionsRemovedComponent
Active-word karaoke caption styling
Live preview
live · rendered by the registry
Rendered by remotionui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://remotionui.com/r/karaoke-captions.jsonSource
1import type { TikTokPage } from "@remotion/captions";2import { Fragment } from "react";3import {4 interpolate,5 interpolateColors,6 useCurrentFrame,7 useVideoConfig,8} from "remotion";9import {10 getAbsoluteTimeMs,11 getTokenEmphasis,12 isTokenActive,13} from "@/remotion/lib/caption-utils";14import { scaleFont } from "@/remotion/lib/layout";15import { EASING, EMPHASIS } from "@/remotion/lib/motion-tokens";1617export type KaraokeCaptionMode = "scale" | "underline";1819export type KaraokeCaptionsProps = {20 page: TikTokPage;21 activeColor?: string;22 completedColor?: string;23 inactiveColor?: string;24 fontSize?: number;25 fontWeight?: number | string;26 mode?: KaraokeCaptionMode;27 /** Peak scale of the active word. Defaults to `EMPHASIS.subtle`. */28 emphasisScale?: number;29 /** Underline track behind the wipe. Defaults to `inactiveColor`. */30 trackColor?: string;31 /**32 * Optional frame override.33 * Pass a parent `frame` when using inside `<Sequence from={...}>`.34 */35 frame?: number;36};3738const clamp01 = (value: number) => Math.min(1, Math.max(0, value));3940/**41 * Caption tokens carry their own leading space. It has to sit outside the42 * scaled box — a word that grows inside its own space closes the gap to the43 * word before it.44 */45function splitLeadingSpace(text: string) {46 const leading = /^\s+/.exec(text)?.[0] ?? "";47 return { leading, word: text.slice(leading.length) };48}4950export const KaraokeCaptions: React.FC<KaraokeCaptionsProps> = ({51 page,52 activeColor = "#ff6b00",53 completedColor = "#111111",54 inactiveColor = "rgba(17, 17, 17, 0.32)",55 fontSize: fontSizeProp,56 fontWeight = 800,57 mode = "underline",58 emphasisScale = EMPHASIS.subtle,59 trackColor,60 frame: frameOverride,61}) => {62 const localFrame = useCurrentFrame();63 const frame = frameOverride ?? localFrame;64 const { fps, width } = useVideoConfig();65 const fontSize = fontSizeProp ?? scaleFont(66, width);66 const absoluteTimeMs = getAbsoluteTimeMs(page, frame, fps);6768 return (69 <div70 style={{71 color: inactiveColor,72 fontSize,73 fontWeight,74 letterSpacing: 0,75 // The active word grows into the gaps on both sides, so the resting76 // rhythm has to be wider than a bare space character.77 wordSpacing: "0.12em",78 lineHeight: 1.18,79 textAlign: "center",80 whiteSpace: "pre-wrap",81 }}82 >83 {page.tokens.map((token) => {84 const active = isTokenActive(token, absoluteTimeMs);85// … truncated
