diff --git a/README.md b/README.md index 1019530..47c472d 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Demos with a **Live** link run in your browser at [demos.speechify.ai](https://d | [`demos/docs-read-aloud/`](./demos/docs-read-aloud) | TypeScript (zero-dep server) | | A documentation-style page with a Listen button that reads the article aloud. The button POSTs the text to a tiny server route, which synthesizes it with the Speechify API (key stays server-side) and returns the MP3 for the browser to play. Framework-agnostic. | | [`demos/ivr-ssml/`](./demos/ivr-ssml) | Next.js | [Open](https://demos.speechify.ai/ivr-ssml) | A phone-system playground for getting names, account numbers, and product terms right with SSML. Hear plain vs SSML side by side; the API key stays server-side. | | [`demos/webpage-audiobook/`](./demos/webpage-audiobook) | Next.js | [Open](https://demos.speechify.ai/webpage-audiobook) | Paste a URL, get narrated audio. The server fetches the article, extracts the text, chunks it on sentence boundaries, and synthesizes each part with the Speechify TTS API. | +| [`demos/streaming-tts-karaoke/`](./demos/streaming-tts-karaoke) | Next.js | [Open](https://demos.speechify.ai/streaming-tts-karaoke) | Realtime TTS with word timestamps: each word lights up the instant its audio arrives over the stream, then again as it plays. Key held server-side. | ## Get an API key diff --git a/demos/streaming-tts-karaoke/.env.example b/demos/streaming-tts-karaoke/.env.example new file mode 100644 index 0000000..534cec4 --- /dev/null +++ b/demos/streaming-tts-karaoke/.env.example @@ -0,0 +1 @@ +SPEECHIFY_API_KEY=your_api_key_here diff --git a/demos/streaming-tts-karaoke/.gitignore b/demos/streaming-tts-karaoke/.gitignore new file mode 100644 index 0000000..4c516b0 --- /dev/null +++ b/demos/streaming-tts-karaoke/.gitignore @@ -0,0 +1,11 @@ +node_modules/ +.next/ +.env +next-env.d.ts +*.tsbuildinfo + +# Playwright +test-results/ +playwright-report/ +/.playwright/ +.last-run.json diff --git a/demos/streaming-tts-karaoke/README.md b/demos/streaming-tts-karaoke/README.md new file mode 100644 index 0000000..08277bc --- /dev/null +++ b/demos/streaming-tts-karaoke/README.md @@ -0,0 +1,65 @@ +# Streaming TTS karaoke + +Realtime text-to-speech with word timestamps. Speechify's streaming endpoint +returns audio **and** per-word timings as it synthesizes, so this demo shows two +highlights at once: + +1. **Received** — each word lights up the instant its audio + timestamp arrive + over the stream. This is the wire speed: the marks race ahead of playback. +2. **Playing** — a second highlight follows the actual audio position as it plays + back through the browser. + +The Speechify API key never reaches the browser — the page talks to a one-route +server proxy. + +Pairs with the Speechify post *Realtime streaming TTS with word highlighting*. + +## What you get + +- **[`app/api/stream/route.ts`](./app/api/stream/route.ts)** — a Node route that + proxies `POST /v1/audio/stream/with-timestamps` (Server-Sent Events) and pipes + it straight to the browser, key held server-side. +- **[`app/page.tsx`](./app/page.tsx)** — parses the SSE `speech.chunk` events, + maps each word mark to the rendered text by character offset (the "received" + highlight), streams the base64 audio into a `