
Security News
US Government Forces Anthropic to Pull Claude Fable Days After Launch
Anthropic says the directive cited national security concerns over a narrow jailbreak, but offered no specific technical details.
@pie-players/tts-client-server
Advanced tools
Client-side TTS provider that calls server API for synthesis
Client-side TTS provider that calls a server API for synthesis with speech marks support.
For the cross-package TTS architecture and provider layering, see TTS Architecture. This README focuses on the browser-side server provider API.
This package provides a browser-side TTS provider that offloads synthesis to a server API. The server handles provider selection (AWS Polly, Google Cloud TTS, etc.) and credential management, while the client plays audio and coordinates word highlighting.
npm install @pie-players/tts-client-server
import { ServerTTSProvider } from '@pie-players/tts-client-server';
import { TTSService } from '@pie-players/pie-assessment-toolkit';
const provider = new ServerTTSProvider();
const ttsService = new TTSService();
await ttsService.initialize(provider, {
apiEndpoint: '/api/tts', // Your SvelteKit API route
provider: 'polly', // Server-side provider to use
voiceId: 'Joanna',
language: 'en-US',
});
// Note: `apiEndpoint`, `provider`, and `voiceId` are server-provider-specific
// options. When using TTSConfig, pass these inside `providerOptions` rather
// than as top-level fields:
//
// const config: TTSConfig = {
// providerOptions: {
// apiEndpoint: '/api/tts',
// provider: 'polly',
// voiceId: 'Joanna',
// },
// language: 'en-US',
// };
apiEndpoint is required when using ServerTTSProvider directly. Toolkit-level
tools.providers.textToSpeech integration may provide a default endpoint for
server-backed backends, but direct client usage should pass this explicitly.
await ttsService.initialize(provider, {
apiEndpoint: '/api/tts',
provider: 'polly',
authToken: 'your-jwt-token',
organizationId: 'org-123',
});
// The provider automatically coordinates word highlighting
await ttsService.speak('Hello world, this is a test.', {
contentElement: document.getElementById('content'),
});
ServerTTSProvider now supports two transport modes:
pie (default): POST ${apiEndpoint}/synthesize, inline base64 audio + inline speech markscustom: POST to root endpoint, then fetch audioContent and JSONL marks URLsRequest:
{
"text": "Hello world",
"provider": "polly",
"voice": "Joanna",
"language": "en-US",
"rate": 1.0,
"includeSpeechMarks": true
}
Response:
{
"audio": "base64-encoded-audio",
"contentType": "audio/mpeg",
"speechMarks": [
{ "time": 0, "type": "word", "start": 0, "end": 5, "value": "Hello" },
{ "time": 340, "type": "word", "start": 6, "end": 11, "value": "world" }
],
"metadata": {
"providerId": "aws-polly",
"voice": "Joanna",
"duration": 1.5,
"charCount": 11,
"cached": false
}
}
{
"audio": "base64-encoded-audio",
"contentType": "audio/mpeg",
"speechMarks": [
{ "time": 0, "type": "word", "start": 0, "end": 5, "value": "Hello" }
]
}
{
"text": "Hello world",
"speedRate": "medium",
"lang_id": "en-US",
"cache": true
}
{
"audioContent": "https://cdn.example.com/audio.mp3",
"word": "https://cdn.example.com/marks.jsonl"
}
Speech marks are fetched from the word URL and parsed as JSONL.
GET ${apiEndpoint}/voices remains optional and is only used when endpoint validation is configured with endpointValidationMode: "voices".
See the implementation guide in tts-architecture.md.
Example route structure:
apps/<host-app>/src/routes/api/tts/
├── synthesize/+server.ts
└── voices/+server.ts
interface ServerTTSProviderConfig {
apiEndpoint: string; // API base URL (required)
provider?: string; // Server provider ('polly', 'google', etc.)
transportMode?: 'pie' | 'custom';
endpointMode?: 'synthesizePath' | 'rootPost';
endpointValidationMode?: 'voices' | 'endpoint' | 'none';
authToken?: string; // JWT or API key
includeAuthOnAssetFetch?: boolean;
assetOrigins?: string[]; // Trusted origins for Authorization header
organizationId?: string; // For multi-tenant setups
headers?: Record<string, string>; // Custom headers
voiceId?: string; // Voice ID
language?: string; // Language code
rate?: number; // Speech rate (0.25-4.0)
volume?: number; // Volume (0-1)
}
ServerTTSProvider treats apiEndpoint and authToken as host-owned.
The host is responsible for authenticating /api/tts/* (session cookie,
JWT, or equivalent), rate-limiting callers, and keeping vendor
credentials (AWS, Google, etc.) server-side only. End-to-end guidance —
including a SvelteKit hooks.server.ts sketch and rate-limit example —
lives in
@pie-players/tts-server-polly → INTEGRATION-GUIDE.md § Security Considerations.
The provider itself enforces one piece of security directly: it scrubs
the Authorization header when following URLs returned by the TTS
server that fall outside a trusted origin set.
assetOrigins — allow-list of origins permitted to receive the
bearer token when the provider fetches custom-transport audio or
speech-mark URLs. Defaults to the origin of apiEndpoint (or, for a
relative apiEndpoint, window.location.origin). Non-http(s)
URLs and malformed URLs are always rejected, regardless of this
setting.includeAuthOnAssetFetch — defaults to false. When true, the
provider will forward Authorization on asset fetches only to
origins in assetOrigins; off-allow-list origins are fetched without
auth. Leave at the default unless your CDN / storage backend actually
requires the bearer token to read assets.See
docs/tools-and-accomodations/tool_host_contract.md#backend-endpoints-for-tool-providers
for the host-wide contract this provider fits into.
speak(text)/synthesize or root POST)The provider uses a polling-based approach for reliable synchronization:
// Every 50ms, check current audio time
const currentTime = audio.currentTime * 1000; // Convert to ms
// Find words that should be highlighted
for (const timing of wordTimings) {
if (currentTime >= timing.time) {
onWordBoundary('', timing.charIndex, timing.length);
}
}
This is much more reliable than browser's onboundary events (which are broken in Safari and unreliable in Chrome).
The provider automatically manages Blob URLs:
try {
await ttsService.speak('Hello world');
} catch (error) {
console.error('TTS failed:', error.message);
// Fallback to browser TTS or show error
}
Requires:
HTMLAudioElement APIfetch APIURL.createObjectURLatob for base64 decodingMIT
FAQs
Client-side TTS provider that calls server API for synthesis
We found that @pie-players/tts-client-server demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Anthropic says the directive cited national security concerns over a narrow jailbreak, but offered no specific technical details.

Security News
A network of 152 Chrome live wallpaper extensions hid ad tracking and made extension-driven traffic look like Google search clicks.

Company News
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.