( params: DeepgramTtsParams )
| 365 | } |
| 366 | |
| 367 | async function synthesizeWithDeepgram( |
| 368 | params: DeepgramTtsParams |
| 369 | ): Promise<{ audioBuffer: Buffer; format: string; mimeType: string; duration?: number }> { |
| 370 | const { |
| 371 | text, |
| 372 | apiKey, |
| 373 | model = 'aura-asteria-en', |
| 374 | encoding = 'mp3', |
| 375 | sampleRate, |
| 376 | bitRate, |
| 377 | container, |
| 378 | } = params |
| 379 | |
| 380 | const queryParams = new URLSearchParams({ |
| 381 | model: model, |
| 382 | encoding: encoding, |
| 383 | }) |
| 384 | |
| 385 | if (sampleRate && encoding === 'linear16') { |
| 386 | queryParams.append('sample_rate', sampleRate.toString()) |
| 387 | } |
| 388 | |
| 389 | if (bitRate) { |
| 390 | queryParams.append('bit_rate', bitRate.toString()) |
| 391 | } |
| 392 | |
| 393 | if (container && container !== 'none') { |
| 394 | queryParams.append('container', container) |
| 395 | } |
| 396 | |
| 397 | const response = await fetch(`https://api.deepgram.com/v1/speak?${queryParams.toString()}`, { |
| 398 | method: 'POST', |
| 399 | headers: { |
| 400 | Authorization: `Token ${apiKey}`, |
| 401 | 'Content-Type': 'application/json', |
| 402 | }, |
| 403 | body: JSON.stringify({ text }), |
| 404 | }) |
| 405 | |
| 406 | if (!response.ok) { |
| 407 | const error = await readTtsErrorJson(response, 'Deepgram TTS error response') |
| 408 | const errorMessage = getTtsErrorMessage(error, response.statusText) |
| 409 | throw new Error(`Deepgram TTS API error: ${errorMessage}`) |
| 410 | } |
| 411 | |
| 412 | const audioBuffer = await readResponseToBufferWithLimit(response, { |
| 413 | maxBytes: MAX_TTS_AUDIO_BYTES, |
| 414 | label: 'Deepgram TTS audio response', |
| 415 | }) |
| 416 | |
| 417 | let finalFormat: string = encoding |
| 418 | if (container === 'wav') { |
| 419 | finalFormat = 'wav' |
| 420 | } else if (container === 'ogg') { |
| 421 | finalFormat = 'ogg' |
| 422 | } |
| 423 | |
| 424 | const mimeType = getMimeType(finalFormat) |
no test coverage detected