POST /chime {name} plays chimes/<name>.wav or .ogg via pacat.
Goes through the same queue as speak so playback stays ordered.
chimes/ directory holds the audio files (not committed).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
1.8 KiB
JavaScript
64 lines
1.8 KiB
JavaScript
/**
|
|
* TTS HTTP client — speaks text via a running tts-server.mjs instance.
|
|
*
|
|
* Usage:
|
|
* const tts = new Tts_Client()
|
|
* await tts.speak('Hello world.')
|
|
* await tts.speak('Hello.', { audio_prompt: '/path/to/voice.wav' })
|
|
* const { voices, current } = await tts.list_voices()
|
|
* await tts.set_voice('rommie')
|
|
*
|
|
* The server URL defaults to TTS_URL env var, then http://192.168.2.99:11500.
|
|
*/
|
|
|
|
const DEFAULT_URL = process.env.TTS_URL ?? 'http://192.168.2.99:11500'
|
|
|
|
export class Tts_Client {
|
|
constructor({ url = DEFAULT_URL } = {}) {
|
|
this._url = url
|
|
}
|
|
|
|
async speak(text, opts = {}) {
|
|
const res = await fetch(`${this._url}/speak`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ text, ...opts }),
|
|
})
|
|
if (!res.ok) {
|
|
const data = await res.json().catch(() => ({}))
|
|
throw new Error(data.error ?? `HTTP ${res.status}`)
|
|
}
|
|
}
|
|
|
|
async list_voices() {
|
|
const res = await fetch(`${this._url}/voices`)
|
|
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
|
return res.json() // { voices: [{name, description, active}], current }
|
|
}
|
|
|
|
async chime(name) {
|
|
const res = await fetch(`${this._url}/chime`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ name }),
|
|
})
|
|
if (!res.ok) {
|
|
const data = await res.json().catch(() => ({}))
|
|
throw new Error(data.error ?? `HTTP ${res.status}`)
|
|
}
|
|
}
|
|
|
|
async set_voice(name) {
|
|
const res = await fetch(`${this._url}/voice`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ name }),
|
|
})
|
|
if (!res.ok) {
|
|
const data = await res.json().catch(() => ({}))
|
|
throw new Error(data.error ?? `HTTP ${res.status}`)
|
|
}
|
|
return res.json() // { ok, name, path }
|
|
}
|
|
}
|