Speech API
Сервис tagme-speech предоставляет HTTP/WebSocket proxy-API для распознавания и синтеза речи через SmartSpeech. В объединённом Swagger платформы HTTP-эндпойнты сервиса публикуются в разделе SpeechApi.
Параметры распознавания и синтеза в tagme-speech соответствуют тем же опциям SmartSpeech, что используются в upstream gRPC API. Разница состоит в транспортном уровне:
-
для batch ASR и TTS платформа предоставляет HTTP API;
-
для realtime ASR платформа предоставляет WebSocket API;
WebSocket endpoint распознавания речи в реальном времени /api/v0/speech/asr/ws не отображается в OpenAPI автоматически, поэтому его протокол описан на этой странице отдельно.
TTS
HTTP endpoint:
POST /api/v0/speech/tts
Content-Type: application/json
Параметры запроса соответствуют настройкам синтеза SmartSpeech, описанным в gRPC documentation, но передаются в JSON body HTTP-запроса.
Минимальный запрос:
curl -X POST "https://<host>/api/v0/speech/tts" \
-H "Content-Type: application/json" \
-d '{
"text": "Пример текста для синтеза",
"voice": "May_24000",
"audio_encoding": "wav"
}' \
--output speech.wav
Ответ возвращается как streaming audio body. Тип содержимого зависит от audio_encoding, например audio/wav, audio/ogg или audio/pcm.
ASR
HTTP endpoint:
POST /api/v0/speech/asr
Content-Type: multipart/form-data
Параметры распознавания соответствуют настройкам SmartSpeech Recognition API, но передаются как JSON-строка в поле options multipart/form-data запроса.
Минимальный запрос:
curl -X POST "https://<host>/api/v0/speech/asr" \
-F "file=@audio.wav"
Пример запроса с параметрами распознавания:
curl -X POST "https://<host>/api/v0/speech/asr" \
-F "file=@audio.wav" \
-F 'options={"sample_rate":16000,"encoding":"wav","language":"ru-RU","model":"general"}'
Пример ответа:
{
"text": "Привет, мир. Как дела?",
"utterances": [
{
"text": "привет мир",
"normalized_text": "Привет, мир.",
"start_ms": 0,
"end_ms": 1500,
"words": [
{
"word": "привет",
"start_ms": 0,
"end_ms": 600
},
{
"word": "мир",
"start_ms": 700,
"end_ms": 1500
}
],
"channel": 0,
"eou_reason": "organic",
"emotions": {
"positive": 0.7,
"neutral": 0.2,
"negative": 0.1,
"positive_a": 0.6,
"neutral_a": 0.3,
"negative_a": 0.1,
"positive_t": 0.8,
"neutral_t": 0.1,
"negative_t": 0.1
},
"speaker_info": null
},
{
"text": "как дела",
"normalized_text": "Как дела?",
"start_ms": 1600,
"end_ms": 2500,
"words": [],
"channel": 0,
"eou_reason": "organic",
"emotions": null,
"speaker_info": null
}
],
"backend_info": {
"model_name": "general",
"model_version": "M-02.002.00-general-01",
"server_version": "1.0.0"
},
"vad_events": [],
"insights": []
}
Realtime ASR over WebSocket
WebSocket endpoint:
WS /api/v0/speech/asr/ws
Параметры options соответствуют тем же настройкам SmartSpeech Recognition API, что и в batch ASR. В отличие от upstream gRPC API, в platform API они передаются в первом JSON-сообщении WebSocket-сессии.
Базовый сценарий работы:
-
Клиент открывает WebSocket-соединение.
-
Клиент отправляет конфигурацию распознавания.
-
Сервер отвечает сообщением готовности.
-
Клиент отправляет бинарные аудиофреймы.
-
Сервер возвращает события
partial,final,vad,backend_info,insight. -
Клиент отправляет
stopили закрывает соединение. -
Сервер отправляет
doneи закрывает сессию.
Пример первого сообщения клиента:
{
"type": "config",
"options": {
"sample_rate": 16000,
"encoding": "pcm_s16le",
"language": "ru-RU",
"model": "general",
"enable_partial_results": true,
"enable_multi_utterance": true,
"enable_vad": true
}
}
Пример ответа о готовности:
{
"type": "ready",
"session_id": "8f5c6c5f-7c2a-4e6a-9db0-4d5f77a2c123"
}
Пример промежуточного результата:
{
"type": "partial",
"text": "пример",
"start_ms": 0,
"end_ms": 420
}
Пример финального результата:
{
"type": "final",
"utterance": {
"text": "пример финального текста",
"normalized_text": "Пример финального текста.",
"start_ms": 0,
"end_ms": 1260,
"words": [],
"channel": 0,
"eou_reason": "organic",
"emotions": null,
"speaker_info": null
}
}
Пример остановки со стороны клиента:
{
"type": "stop"
}
Использование в шаблонах разметки
Ниже приведены минимальные примеры интеграции без привязки к конкретной структуре формы.
TTS в шаблоне
const response = await fetch("/api/v0/speech/tts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
text: "Пример текста",
voice: "May_24000",
audio_encoding: "wav",
}),
});
const audioBlob = await response.blob();
ASR в шаблоне
const formData = new FormData();
formData.append("file", audioBlob, "audio.wav");
formData.append(
"options",
JSON.stringify({
sample_rate: 16000,
encoding: "wav",
language: "ru-RU",
model: "general",
})
);
const response = await fetch("/api/v0/speech/asr", {
method: "POST",
body: formData,
});
const result = await response.json();
Realtime ASR в шаблоне
const wsProtocol = window.location.protocol === "https:" ? "wss:" : "ws:";
const ws = new WebSocket(`${wsProtocol}//${window.location.host}/api/v0/speech/asr/ws`);
ws.onopen = () => {
ws.send(JSON.stringify({
type: "config",
options: {
sample_rate: 16000,
encoding: "pcm_s16le",
language: "ru-RU",
model: "general",
enable_partial_results: true,
},
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log(message);
};
function sendAudioChunk(int16PcmChunk) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(int16PcmChunk.buffer);
}
}
function stopRecognition() {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: "stop" }));
}
}