umbot
Version:
Мультиплатформенный фреймворк для создания голосовых навыков и чат-ботов с единой бизнес-логикой. Встроенная поддержка ВКонтакте, Telegram, Viber, MAX, Яндекс Алисы, Маруси и Сбера SmartApp. Архитектура на адаптерах позволяет подключать любые другие платф
287 lines (286 loc) • 10.6 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.YandexSpeechKit = void 0;
const YandexRequest_1 = require("./YandexRequest");
const index_1 = require("../../../index");
const node_path_1 = require("node:path");
/**
* Класс отвечающий за преобразование текста в аудио файл.
* Преобразование осуществляется через сервис Yandex SpeechKit.
* @see (https://cloud.yandex.ru/docs/speechkit/tts/request) Смотри тут
*
* @example
* ```ts
* import { YandexSpeechKit } from './api/YandexSpeechKit';
*
* // Создание экземпляра с токеном
* const speechKit = new YandexSpeechKit('your-oauth-token');
*
* // Настройка параметров синтеза
* speechKit.lang = YandexSpeechKit.L_RU; // Русский язык
* speechKit.voice = YandexSpeechKit.V_JANE; // Голос Jane
* speechKit.emotion = YandexSpeechKit.E_GOOD; // Доброжелательная интонация
* speechKit.speed = 1.2; // Скорость речи
* speechKit.format = YandexSpeechKit.F_OGGOPUS; // Формат OGG/OPUS
*
* try {
* // Пример с омографами и паузами
* const text = 'Я гот+ов - начать работу';
* const audio = await speechKit.getTts(text);
*
* // Сохранение или воспроизведение аудио
* // audio содержит бинарные данные в выбранном формате
* } catch (error) {
* console.error('Ошибка синтеза речи:', error);
* }
* ```
*/
class YandexSpeechKit extends YandexRequest_1.YandexRequest {
/**
* Адрес, на который будет отправляться запрос
*/
static TTS_API_URL = 'https://tts.api.cloud.yandex.net/speech/v1/tts:synthesize';
/**
* Положительная интонация
*/
static E_GOOD = 'good';
/**
* Отрицательная интонация
*/
static E_EVIL = 'evil';
/**
* Нейтральная интонация
*/
static E_NEUTRAL = 'neutral';
/**
* Голос для синтеза речи Оксана (ru)
*/
static V_OKSANA = 'oksana';
/**
* Голос для синтеза речи Джейн (ru)
*/
static V_JANE = 'jane';
/**
* Голос для синтеза речи Омаж (ru)
*/
static V_OMAZH = 'omazh';
/**
* Голос для синтеза речи Захар (ru)
*/
static V_ZAHAR = 'zahar';
/**
* Голос для синтеза речи Ермил (ru)
*/
static V_ERMIL = 'ermil';
/**
* Голос для синтеза речи Сильвер (tr)
*/
static V_SILAERKAN = 'silaerkan';
/**
* Голос для синтеза речи Эркан (tr)
*/
static V_ERKANYAVAS = 'erkanyavas';
/**
* Голос для синтеза речи Элис (en)
*/
static V_ALYSS = 'alyss';
/**
* Голос для синтеза речи Ник (en)
*/
static V_NICK = 'nick';
/**
* Голос для синтеза речи Алена (ru)
*/
static V_ALENA = 'alena';
/**
* Голос для синтеза речи Филипп (ru)
*/
static V_FILIPP = 'filipp';
/**
* Русский язык
*/
static L_RU = 'ru-RU';
/**
* Английский язык
*/
static L_EN = 'en_EN';
/**
* Турецкий язык
*/
static L_TR = 'tr-TR';
/**
* Формат файла lpcm
* @see format
*/
static F_LPCM = 'lpcm';
/**
* Формат файла oggopus
* @see format
*/
static F_OGGOPUS = 'oggopus';
/**
* Текст для озвучивания в кодировке UTF-8
* Можно использовать только одно из полей text и ssml
* Для передачи слов-омографов используйте + перед ударной гласной
* Например: гот+ов или def+ect
* Для паузы между словами используйте -
* Максимальная длина: 5000 символов
*/
text;
/**
* Язык синтеза речи
* ru-RU (по умолчанию) - русский
* en-US - английский
* tr-TR - турецкий
*/
lang;
/**
* Голос для синтеза речи
* По умолчанию: oksana
* @see V_OKSANA, V_JANE, V_OMAZH и другие константы
*/
voice;
/**
* Эмоциональная окраска голоса
* Поддерживается только для ru-RU и голосов jane/omazh
* good - доброжелательный
* evil - злой
* neutral (по умолчанию) - нейтральный
*/
emotion;
/**
* Скорость синтеза речи
* От 0.1 до 3.0
* 3.0 - самый быстрый
* 1.0 (по умолчанию) - средняя скорость
* 0.1 - самый медленный
* Не поддерживается для премиум-голосов
*/
speed;
/**
* Формат синтезируемого аудио
* lpcm - без WAV-заголовка
* oggopus (по умолчанию) - OGG контейнер с OPUS кодеком
*/
format;
/**
* Частота дискретизации для формата lpcm
* Поддерживаемые значения:
* - 48000 (по умолчанию) - 48 кГц, высокое качество
* - 16000 - 16 кГц, среднее качество
* - 8000 - 8 кГц, низкое качество, подходит для телефонии
*
* @remarks
* Параметр используется только при format = YandexSpeechKit.F_LPCM
* Для format = YandexSpeechKit.F_OGGOPUS игнорируется
*/
sampleRateHertz;
/**
* Идентификатор каталога для авторизации.
* Требуется только для пользовательского аккаунта
* Максимум 50 символов
*/
folderId;
/**
* Создает экземпляр YandexSpeechKit
* @param oauth Авторизационный токен для синтеза речи
* @param appContext Контекст приложения
*/
constructor(oauth = null, appContext) {
super(oauth, appContext);
this.lang = _a.L_RU;
this.emotion = _a.E_NEUTRAL;
this.speed = 1.0;
this.format = _a.F_OGGOPUS;
this.folderId = null;
this.voice = 'oksana';
}
/**
* Инициализация параметров для отправки запроса
*/
#initPost() {
this._request.post = {
text: this.text,
lang: this.lang,
voice: this.voice,
format: this.format,
};
if ([
_a.V_SILAERKAN,
_a.V_ERKANYAVAS,
_a.V_ALYSS,
_a.V_NICK,
].indexOf(this.voice) === -1) {
this._request.post.emotion = this.emotion;
}
if (this.voice !== _a.V_ALENA && this.voice !== _a.V_FILIPP) {
if (this.speed < 0.1 || this.speed > 3.0) {
this.speed = 1.0;
}
this._request.post.speed = this.speed;
}
if (this.format === _a.F_LPCM && this.sampleRateHertz) {
this._request.post.sampleRateHertz = this.sampleRateHertz;
}
if (this.folderId) {
this._request.post.folderId = this.folderId;
}
}
/**
* Получение голосового текста
* @param text Текст для преобразования в речь
* @returns Возвращает путь к сохраненному файлу и его бинарное содержимое
*
* @remarks
* Поддерживаемые форматы:
* - F_LPCM: RAW PCM без WAV-заголовка
* - F_OGGOPUS: OGG контейнер с OPUS кодеком (рекомендуется)
*
* Особенности текста:
* - Для омографов используйте + перед ударной гласной: гот+ов, з+амок
* - Для паузы между словами используйте -: слово - слово
* - Максимальная длина текста: 5000 символов
*
* Ограничения:
* - Эмоции (emotion) поддерживаются только для ru-RU и голосов jane/omazh
* - Скорость (speed) не поддерживается для премиум-голосов (alena, filipp)
*
* Важно! после выполнения запроса, не забудьте удалить файл с результатом.
*
* @example
* ```ts
* // Пример с LPCM форматом
* speechKit.format = YandexSpeechKit.F_LPCM;
* speechKit.sampleRateHertz = 16000;
* const pcmAudio = await speechKit.getTts('Текст для синтеза');
*
* // Пример с OGG/OPUS
* speechKit.format = YandexSpeechKit.F_OGGOPUS;
* const oggAudio = await speechKit.getTts('Текст для синтеза');
* ```
*
* @see (https://cloud.yandex.ru/docs/speechkit/tts/request) Смотри тут
*/
async getTts(text = null) {
if (text) {
this.text = text;
}
this._request.url = _a.TTS_API_URL;
this._request.isConvertJson = false;
this._request.isBinaryResponse = true;
this.#initPost();
const audioData = (await this.call());
if (!audioData) {
return null;
}
const fileName = `${this._appContext.appConfig.error_log || (0, node_path_1.join)(__dirname, '..', '..', 'logs')}/tts_${Date.now()}_${Math.floor(Math.random() * 100)}.ogg`;
await (0, index_1.fwrite)(fileName, new Uint8Array(audioData), 'w');
return {
fileName,
audioData,
};
}
}
exports.YandexSpeechKit = YandexSpeechKit;
_a = YandexSpeechKit;