Skip to content
Sign in
VoiceLive captionsMenu

Live captionsPro

Rolling captions for voice: the recognizer's interim words in gray, settled words in ink, a fixed number of lines that roll up by exactly one line as speech wraps, and an overlay style for video.

ProA trail conditions line after a storm. Captions roll up a line at a time: unsettled words in gray, settled words in ink, and the cut where the caller spoke over the reply.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/live-captions

Usage

tsx
import { LiveCaptions } from "@/components/ui/chatcn/pro/live-captions"

<LiveCaptions segments={voice.segments} lines={2} size="lg" align="center" agentLabel="Trail line" />

Takes the same segments as Transcript, so one stream of speech feeds both. Consecutive turns by one speaker flow into a paragraph and a new speaker starts a new line with their name. The box is exactly lines tall: text is anchored to the bottom, older lines fade out at the top edge, and nothing around the captions ever moves while speech arrives.

Examples

Over video

variant="overlay" puts each line on its own dark box that wraps with the text, like broadcast captions, so it reads on any frame.

ProThe overlay style: every line on its own dark box that wraps with the text, readable on any frame.

States

ProWaiting, interim, settled, cut off, paused, unavailable, long unbroken text and every size.

Props

PropTypeNotes
segmentsTranscriptSegment[]Settled text, unsettled interim, interrupted, speaker
linesnumberLines kept on screen, 1 to 6. Default 2
size"sm" | "md" | "lg" | "xl"13/20, 15/24, 18/28, 24/32. Default md
variant"plain" | "overlay"overlay boxes each line for video. Default plain
align"start" | "center"Default start
speakersbooleanName the speaker at the start of each turn. Default true
agentLabel, userLabelstringDefault "Assistant" and "You"
status"live" | "paused" | "unavailable"Paused and unavailable keep the text, one step quieter, under a notice
messageReactNodeShown while unavailable. Say how to fix it
placeholderReactNodeShown before anything is said
announcebooleanRead finished agent lines once. Default true; turn it off when a transcript announces them
labelstringAccessible name. Default "Live captions"

Keyboard

Captions are read only and take no focus.

Accessibility

  • The window is a role="log" with live updates off, so screen readers never hear a sentence word by word. Each finished agent line is announced once through a polite status, and history present on mount is not read out.
  • Speaker names carry a hidden colon, so a screen reader reads "Trail line: Partly." rather than running the name into the words.
  • Interim words use the lightest readable gray, never a fade. The cut where the caller spoke over the reply is a hairline plus the words "Cut off", never color alone.
  • Unavailable is an alert with the fix. Set lang on the root for captions in another language, and RTL follows dir.

Motion

  • Text appends with no per word effects. When speech wraps to a new line, the block is shifted back to where it was and eased up by exactly that distance over 200 ms, so lines glide up instead of jumping. A wrap mid roll starts from where the text shows, so it never snaps.
  • Old text fades out at the top through a mask, only while the box overflows.
  • Under reduced motion the roll is instant.