mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-20 17:25:52 +03:00
feat(web-test): add ElevenLabs TTS provider
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a8d8007846
commit
5bccca2475
@@ -216,6 +216,18 @@ For OpenAI-compatible provider:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For ElevenLabs:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tts": {
|
||||||
|
"provider": "elevenlabs",
|
||||||
|
"apiKey": "sk_...",
|
||||||
|
"voice": "JBFqnCBsd6RMkjVDRZzb"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Note: `voice` is the ElevenLabs voice ID (not a name). Default model: `eleven_multilingual_v2` (supports Russian and other languages).
|
||||||
|
|
||||||
### `showCaption()` speech parameter
|
### `showCaption()` speech parameter
|
||||||
|
|
||||||
The `speech` option controls what text is narrated (vs displayed):
|
The `speech` option controls what text is narrated (vs displayed):
|
||||||
@@ -236,7 +248,7 @@ Generate TTS and merge audio with video. Call after `stopRecording()`.
|
|||||||
|-----------|------|-------------|
|
|-----------|------|-------------|
|
||||||
| `videoPath` | `string` | Path to the recorded MP4 file |
|
| `videoPath` | `string` | Path to the recorded MP4 file |
|
||||||
| `opts.captions` | `Array` | Explicit captions (default: from last recording or `.captions.json`) |
|
| `opts.captions` | `Array` | Explicit captions (default: from last recording or `.captions.json`) |
|
||||||
| `opts.provider` | `string` | `'edge'` (default) or `'openai'` |
|
| `opts.provider` | `string` | `'edge'` (default), `'openai'`, or `'elevenlabs'` |
|
||||||
| `opts.voice` | `string` | Voice name (provider-specific) |
|
| `opts.voice` | `string` | Voice name (provider-specific) |
|
||||||
| `opts.apiKey` | `string` | API key (for openai) |
|
| `opts.apiKey` | `string` | API key (for openai) |
|
||||||
| `opts.apiUrl` | `string` | Endpoint (for openai) |
|
| `opts.apiUrl` | `string` | Endpoint (for openai) |
|
||||||
|
|||||||
@@ -3154,10 +3154,34 @@ async function openaiTtsProvider(text, outputPath, opts = {}) {
|
|||||||
writeFileSync(outputPath, buf);
|
writeFileSync(outputPath, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ElevenLabs TTS provider. Requires apiKey.
|
||||||
|
* @param {string} text — text to synthesize
|
||||||
|
* @param {string} outputPath — path for the output mp3 file
|
||||||
|
* @param {object} opts — { apiKey, apiUrl, voice, model }
|
||||||
|
*/
|
||||||
|
async function elevenlabsTtsProvider(text, outputPath, opts = {}) {
|
||||||
|
const voiceId = opts.voice || 'JBFqnCBsd6RMkjVDRZzb'; // George
|
||||||
|
const apiUrl = opts.apiUrl || `https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`;
|
||||||
|
if (!opts.apiKey) throw new Error('ElevenLabs TTS requires apiKey');
|
||||||
|
const resp = await fetch(apiUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'xi-api-key': opts.apiKey, 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
text,
|
||||||
|
model_id: opts.model || 'eleven_multilingual_v2',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
if (!resp.ok) throw new Error(`ElevenLabs TTS error ${resp.status}: ${await resp.text()}`);
|
||||||
|
const buf = Buffer.from(await resp.arrayBuffer());
|
||||||
|
writeFileSync(outputPath, buf);
|
||||||
|
}
|
||||||
|
|
||||||
/** Get TTS provider function by name. */
|
/** Get TTS provider function by name. */
|
||||||
function getTtsProvider(name) {
|
function getTtsProvider(name) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'openai': return openaiTtsProvider;
|
case 'openai': return openaiTtsProvider;
|
||||||
|
case 'elevenlabs': return elevenlabsTtsProvider;
|
||||||
case 'edge': default: return edgeTtsProvider;
|
case 'edge': default: return edgeTtsProvider;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,6 +225,24 @@ await showCaption('Технические детали', { speech: false });
|
|||||||
|
|
||||||
Голоса: `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`.
|
Голоса: `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`.
|
||||||
|
|
||||||
|
Поле `apiUrl` позволяет подключить любой OpenAI-совместимый сервис.
|
||||||
|
|
||||||
|
### ElevenLabs (платный)
|
||||||
|
|
||||||
|
Высокое качество синтеза, мультиязычная модель поддерживает русский.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tts": {
|
||||||
|
"provider": "elevenlabs",
|
||||||
|
"apiKey": "sk_...",
|
||||||
|
"voice": "JBFqnCBsd6RMkjVDRZzb"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`voice` — это ID голоса из библиотеки ElevenLabs (не имя). Список голосов — в личном кабинете ElevenLabs. Требуется платный тариф для использования через API.
|
||||||
|
|
||||||
## Полный пример
|
## Полный пример
|
||||||
|
|
||||||
Типовая структура озвученного сценария:
|
Типовая структура озвученного сценария:
|
||||||
|
|||||||
Reference in New Issue
Block a user