Skip to content

feat: add live-captions demo - #26

Open
luke-speechify wants to merge 2 commits into
mainfrom
feat/live-captions
Open

feat: add live-captions demo#26
luke-speechify wants to merge 2 commits into
mainfrom
feat/live-captions

Conversation

@luke-speechify

Copy link
Copy Markdown
Contributor

Pairs with the upcoming speechify.ai post "Live captions as a browser extension with speech marks".

This is the hostable web update of the earlier post "Building real-time captions with Speechify TTS speech marks" — the original framed the captions as a browser extension, which can't be hosted, so this ships the same speech-marks logic as a page you can host and run.

What it does

  • One-page Next.js app: type text, click Synthesize, press play, and each word lights up the instant the voice speaks it.
  • POST /api/speak (Node runtime) synthesizes with client.audio.speech (model simba-3.2, voice geffen_32, MP3) and returns { audio, speechMarks }, where speechMarks is response.speech_marks.chunks — one entry per word with start_time / end_time in milliseconds and the word value.
  • The client plays the base64 MP3 and, on every requestAnimationFrame, reads audio.currentTime and highlights the word whose [start_time, end_time) window contains the current position (binary search). No forced alignment, no polling timer, no custom decoder.
  • README notes that the same activeIndexAt() logic drops straight into a browser-extension content script — swap the React state update for a classList toggle.

Security + gating

  • SPEECHIFY_API_KEY stays server-side: every Speechify call runs inside the app/api/speak route handler, and next.config.ts marks @speechify/api as a server-external package so the SDK is never bundled into client JS.
  • The route calls verifyTurnstile(req) first and returns 403 on failure; the client renders the shared Turnstile widget and attaches x-turnstile-token to the gated fetch. Turnstile fail-opens when unconfigured (local dev).

Hosting registration

  • Added a live-captions service + rewrite in vercel.json (rewrite placed before / and the catch-all).
  • Added demos/live-captions to pnpm-workspace.yaml.
  • Ran pnpm generate to refresh the README table and site manifest.
  • Dev port 8771 (unique across demos).

Verification

  • Build: pnpm --filter live-captions build
  • Live API call ✅ — confirmed the endpoint returns audio_data plus speech_marks.chunks, each chunk carrying start_time / end_time (ms) and value, with the exact model (simba-3.2), voice (geffen_32), and body the route sends.

@vercel

vercel Bot commented Aug 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
speechify-api-demos Ready Ready Preview Aug 21, 2026 12:06am

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant