Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 22x 1x 1x 22x 22x 22x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 4x 5x 2x 2x 2x 2x 2x 2x 2x 5x 5x 5x 1x 1x 1x 1x 1x 5x 5x 5x 1x 1x 4x 4x 5x 5x 5x 5x 5x 5x 1x 1x 1x 1x 1x 4x 4x 4x 1x 1x 3x 3x 3x 4x 4x 4x 4x 1x 1x 1x 1x 1x 7x 7x 7x 7x 7x 7x 7x 7x 4x 4x 4x 4x 4x 4x 7x 3x 3x 3x 3x 3x 3x 7x 1x | /**
* HTTP Client for Speech Synthesis Service
*/
import type { TTSRequest, TTSResponse, Voice, TTSServiceStatus, ServiceHealth } from './types.js';
import type { TTSProviderConfig } from './config.js';
export class TTSClient {
private baseUrl: string;
private verbose: boolean;
constructor(config: Required<TTSProviderConfig>) {
this.baseUrl = `${config.serverUrl}:${config.port}`;
this.verbose = config.verbose;
}
/**
* Synthesize text to audio
*/
async synthesize(request: TTSRequest): Promise<TTSResponse> {
const response = await fetch(`${this.baseUrl}/tts`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request),
});
if (!response.ok) {
const errorText = await response.text().catch(() => response.statusText);
throw new Error(`TTS synthesis failed: ${errorText}`);
}
const buffer = Buffer.from(await response.arrayBuffer());
return {
audio: buffer,
format: request.format || 'wav',
};
}
/**
* Get available voices
*/
async getVoices(): Promise<Voice[]> {
const response = await fetch(`${this.baseUrl}/tts/voices`);
if (!response.ok) {
throw new Error(`Failed to fetch voices: ${response.statusText}`);
}
const data = await response.json() as { voices: string[]; available: boolean };
return (data.voices || []).map(id => ({
id,
name: id,
lang: id.split('-')[0] || 'en_US',
}));
}
/**
* Get service status
*/
async getStatus(): Promise<TTSServiceStatus> {
const response = await fetch(`${this.baseUrl}/status`);
if (!response.ok) {
throw new Error(`Status check failed: ${response.statusText}`);
}
const data = await response.json() as { tts?: { available?: boolean; voices?: string[] } };
return {
available: data.tts?.available ?? false,
voices: data.tts?.voices ?? [],
};
}
/**
* Check service health
*/
async checkHealth(timeoutMs: number = 5000): Promise<ServiceHealth> {
const start = Date.now();
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(`${this.baseUrl}/health`, {
signal: controller.signal,
});
clearTimeout(timeoutId);
return {
healthy: response.ok,
responseTimeMs: Date.now() - start,
};
} catch (error) {
clearTimeout(timeoutId);
return {
healthy: false,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
}
}
|