Потоковое распознавание речи
Транскрипция в реальном времени через WebSocket /v1/realtime/transcriptions: формат событий OpenAI Realtime, подключение, аудио-формат, биллинг, пример кода
Потоковое распознавание превращает речь в текст по мере произнесения: вы шлёте
аудио-чанки в WebSocket, сервер отвечает промежуточными результатами (delta)
и финальной транскрипцией. Подходит для живых субтитров, диктовки и транскрипции
звонков. Модели с этим режимом отмечены в каталоге
бейджем «Потоковая».
Формат событий совместим с OpenAI Realtime API (transcription-режим) — при переносе клиентского кода достаточно сменить URL.
Подключение
wss://api.tsarrouter.ru/v1/realtime/transcriptions?model=<id модели>Два способа авторизации:
| Способ | Как | Для кого |
|---|---|---|
| Заголовок | Authorization: Bearer <ключ> | серверные клиенты |
| Subprotocol | ["realtime", "openai-insecure-api-key.<ключ>"] | браузер (заголовки в WebSocket недоступны) |
Оба держат ключ вне URL. Передавать ключ query-параметром нельзя — секрет попал бы в журналы сервера.
Модель задаётся query-параметром ?model= или событием session.update
(поле session.audio.input.transcription.model).
События
Клиент → сервер:
| Событие | Назначение |
|---|---|
session.update | Настроить формат аудио и/или модель (до первого аудио) |
input_audio_buffer.append | Чанк аудио: {"audio": "<base64 PCM16LE>"}, рекомендуем ~200 мс |
input_audio_buffer.commit | Конец фразы — запросить финальную транскрипцию |
Сервер → клиент:
| Событие | Назначение |
|---|---|
session.created / session.updated | Подтверждение сессии и настроек |
conversation.item.input_audio_transcription.delta | Прирост текста по мере речи |
input_audio_buffer.committed | Фраза принята в финализацию |
conversation.item.input_audio_transcription.completed | Финальный текст + usage.seconds |
error | Ошибка; фатальные дополнительно закрывают соединение (коды) |
Серверного VAD нет: конец фразы задаёт клиент событием commit
(turn_detection: null).
Формат аудио
Сырой PCM16LE mono (audio/pcm), частота дискретизации 8000–48000 Гц
(по умолчанию 16000). Частота задаётся в session.update:
{"type": "session.update", "session": {"audio": {"input": {"format": {"type": "audio/pcm", "rate": 16000}}}}}Биллинг и лимиты
Тарификация посекундная — по длительности принятого аудио (не времени
соединения: паузы между чанками бесплатны). Списанные секунды каждой фразы
приходят в usage.seconds события completed. На старте сессии на балансе
резервируется стоимость аудио-бюджета сессии, по завершении списывается только
фактическое — остаток возвращается сразу.
Лимиты сессий (аудио-бюджет, одновременные сессии, таймаут бездействия) зависят от уровня аккаунта — см. Лимиты.
Пример (Python)
# pip install websockets
import asyncio, base64, json, websockets
URL = "wss://api.tsarrouter.ru/v1/realtime/transcriptions?model=palatine/palatine_stream"
async def main():
async with websockets.connect(
URL, additional_headers={"Authorization": "Bearer sk-tsar-ваш-ключ"},
) as ws:
await ws.send(json.dumps({"type": "session.update", "session": {
"audio": {"input": {"format": {"type": "audio/pcm", "rate": 16000}}},
}}))
pcm = open("audio.pcm", "rb").read() # PCM16LE mono 16 кГц
for i in range(0, len(pcm), 6400): # чанки ~200 мс
await ws.send(json.dumps({
"type": "input_audio_buffer.append",
"audio": base64.b64encode(pcm[i:i + 6400]).decode(),
}))
await ws.send(json.dumps({"type": "input_audio_buffer.commit"}))
async for raw in ws:
ev = json.loads(raw)
if ev["type"] == "conversation.item.input_audio_transcription.delta":
print(ev["delta"], end="", flush=True)
elif ev["type"] == "conversation.item.input_audio_transcription.completed":
print("\n---", ev["transcript"], ev["usage"])
break
asyncio.run(main())Попробовать без кода можно в песочнице личного кабинета — с записью с микрофона.
Быстрый старт
ЦАРЬ РОУТЕР - агрегатор российских и open-source нейросетей с единым OpenAI-совместимым API. Один ключ, один формат: меняете base_url - и весь код на OpenAI SDK работает без изменений. Не нужно регистрироваться в Yandex Cloud, Cloud.ru, GigaChat или MWS - ЦАРЬ РОУТЕР берёт это на себя.
Лимиты
Лимиты запросов API Царь Роутера: уровни, сетка по типам моделей, заголовки x-ratelimit-*, эндпоинт GET /v1/key