caption-scene
remotionui/caption-sceneFreeBlock
Lower-third TikTok-style captions synced to audio
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/caption-scene.jsonSource
1import type { Caption } from "@remotion/captions";2import { loadFont } from "@remotion/google-fonts/Inter";3import { useMemo } from "react";4import {5 AbsoluteFill,6 interpolate,7 Loop,8 Sequence,9 useCurrentFrame,10 useVideoConfig,11} from "remotion";12import { CaptionHighlight } from "@/remotion/primitives/caption-highlight";13import { KaraokeCaptions } from "@/remotion/primitives/karaoke-captions";14import {15 DEFAULT_CAPTION_PAGE_MS,16 getPageSequenceTiming,17 groupCaptionsIntoPages,18} from "@/remotion/lib/caption-utils";19import {20 getSafeAreaPadding,21 scaleFont,22 type SafeAreaPadding,23} from "@/remotion/lib/layout";24import { DURATION, EASING } from "@/remotion/lib/motion-tokens";2526const { fontFamily } = loadFont("normal", {27 weights: ["500", "600", "700", "800"],28 subsets: ["latin"],29});3031export type CaptionPlacement = "lower-third" | "center";3233export type CaptionSceneMode =34 | "highlight"35 | "karaoke-scale"36 | "karaoke-underline";3738export type CaptionSceneProps = {39 captions: Caption[];40 combineTokensWithinMilliseconds?: number;41 activeColor?: string;42 inactiveColor?: string;43 backgroundColor?: string;44 placement?: CaptionPlacement;45 mode?: CaptionSceneMode;46 label?: string;47 /**48 * How long this scene actually plays for. Pass the enclosing `Sequence`'s49 * `durationInFrames` when the scene is nested inside one (it is shorter50 * than `useVideoConfig().durationInFrames`, which always reports the full51 * composition). Falls back to the composition duration when omitted.52 */53 durationInFrames?: number;54};5556const COLORS = {57 active: "#ff6b00",58 ink: "#111111",59 paper: "#f5f4f2",60 plate: "rgba(245, 244, 242, 0.92)",61 plateDark: "rgba(17, 17, 17, 0.78)",62 border: "rgba(17, 17, 17, 0.12)",63 muted: "rgba(17, 17, 17, 0.52)",64} as const;6566type CaptionPageProps = {67 page: ReturnType<typeof groupCaptionsIntoPages>[number];68 mode: CaptionSceneMode;69 activeColor: string;70 inactiveColor: string;71 fontSize: number;72 placement: CaptionPlacement;73 captionZoneWidth: number;74 safeArea: SafeAreaPadding;75 bottomSlot: number;76 label: string;77};7879function CaptionPage({80 page,81 mode,82 activeColor,83 inactiveColor,84 fontSize,85 placement,86 captionZoneWidth,87 safeArea,88 bottomSlot,89 label,90}: CaptionPageProps) {91 const frame = useCurrentFrame();92 const { fps, width } = useVideoConfig();93 const enter = interpolate(frame, [0, DURATION.fast], [0, 1], {94 extrapolateLeft: "clamp",95 extrapolateRight: "clamp",96// … truncated
More from remotionui
All 127 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ai-composer-showcaseai-composer-showcase | remotionui | Blocks | Free | no deps | |
| ai-generation-canvasai-generation-canvas | remotionui | Blocks | Free | no deps | |
| animated-bar-chartanimated-bar-chart | remotionui | Blocks | Free | no deps | |
| audiogram-sceneaudiogram-scene | remotionui | Blocks | Free | no deps | |
| auto-fit-titleauto-fit-title | remotionui | Blocks | Free | no deps | |
| b-roll-stackb-roll-stack | remotionui | Blocks | Free | no deps | |
| bento-panbento-pan | remotionui | Blocks | Free | no deps | |
| browser-flowbrowser-flow | remotionui | Blocks | Free | no deps |
