AGTCloud API Docs
РуководстваСправочник APIИнтеграции и ресурсыОбновления и помощь
Обработка аудиоMuse Voice Transcribe

Транскрипция в реальном времени

Непрерывно отправляйте аудио PCM через WebSocket Muse Voice Transcribe и получайте события транскрипции в реальном времени.

Muse Voice Transcribe в реальном времени принимает необработанное аудио PCM через постоянное соединение WebSocket и непрерывно возвращает события прогресса, речевых реплик и транскрипции. Этот интерфейс генерирует только текст, но не речевые ответы.

WSS
wss://api.agtcloud.cn/v1/asr/realtime

Аутентификация и подключение

После установления WebSocket отправьте первый текстовый кадр JSON в течение 10 секунд. Bearer-ключ API передаётся в authorization.accessToken, а не в Header рукопожатия WebSocket.

ПараметрЗначение
Адрес подключенияwss://api.agtcloud.cn/v1/asr/realtime
Расположение аутентификацииauthorization.accessToken первого текстового кадра JSON
Модельmuse-voice-transcribe-1.0
Необязательные параметры запросаsessionId, только для передачи ID сеанса; не означает поддержку восстановления соединения или получения истории сеансов

Первый кадр не содержит type и не должен превышать 64 KiB. Начинайте отправку аудио только после получения успешного ответа с sessionId; успешное обновление соединения до WebSocket ещё не означает успешную аутентификацию первого кадра.

Порядок работы сеанса

  1. Установите соединение WebSocket.
  2. Отправьте первый кадр с аутентификацией, моделью и настройками аудио.
  3. Дождитесь sessionId от сервера.
  4. Отправляйте необработанные двоичные кадры PCM с частотой, соответствующей реальному времени, и одновременно непрерывно принимайте события.
  5. После окончания аудио отправьте {"type":"endStream"}.
  6. Продолжайте принимать завершающую транскрипцию и сообщения закрытия.

speechComplete означает завершение одной речевой реплики, а не всего сеанса. После отправки endStream продолжайте читать события сервера до закрытия соединения.

Параметры первого кадра

ПолеТипОписание
authorization.accessTokenstringОбязательно, в формате Bearer your-api-key
modelstringОбязательно, используйте muse-voice-transcribe-1.0
audioEncodingstringОбязательно, для аудио в реальном времени используйте PCM_16KHZ или PCM_24KHZ
modestringНеобязательно: PUSH_TO_TALK, ENDPOINTING, DIARIZATION
partialModestringНеобязательно: CUMULATIVE возвращает накопленный текст, DELTA — новый текст
keywordsstring[]Необязательно, подсказки терминов или имён собственных
languageBiasstring[]Необязательно, подсказка ожидаемых языков
emitAudioProgressbooleanНеобязательно, возвращать ли события прогресса обработки аудио
zdrOverridebooleanНеобязательная настройка обработки данных; её действие зависит от текущего сервиса и разрешений аккаунта

Входное аудио

Аудио должно быть монофоническим PCM16 little-endian без заголовка WAV и соответствовать частоте дискретизации 16 kHz или 24 kHz, указанной в первом кадре. Каждый аудиокадр не должен превышать 1 MiB, а количество байтов должно быть чётным.

Рекомендуется отправлять аудио блоками по 100 ms с частотой реального времени: 4800 байтов для 24 kHz и 3200 байтов для 16 kHz. Если в тишине необходимо сохранять непрерывную временную шкалу, отправляйте данные тишины PCM в том же формате.

# Создать монофоническое необработанное аудио PCM16 с частотой 24 kHz
ffmpeg -i input.mp3 -ac 1 -ar 24000 -c:a pcm_s16le -f s16le audio.pcm

Пример Python

Установите клиент WebSocket, подготовьте audio.pcm и запустите пример. Отправка и получение выполняются в разных потоках, чтобы загрузка аудио не блокировала обработку событий сервера.

python -m pip install websocket-client
WSSПодключение Muse для транскрипции в реальном времени
import json
import sys
import threading
import websocket

url = "wss://api.agtcloud.cn/v1/asr/realtime"
stop = threading.Event()
sender = None
ws = websocket.create_connection(url, timeout=40, enable_multithread=True)

def send_audio():
    try:
        with open(sys.argv[1], "rb") as audio:
            while not stop.is_set():
                chunk = audio.read(4800)
                if not chunk:
                    break
                if len(chunk) % 2:
                    raise ValueError("Количество байтов PCM должно быть чётным")
                ws.send_binary(chunk)
                if stop.wait(len(chunk) / 48000):
                    return
        if not stop.is_set():
            silence = bytes(4800)
            for _ in range(10):
                ws.send_binary(silence)
                if stop.wait(0.1):
                    return
            ws.send(json.dumps({"type": "endStream"}))
    except Exception as exc:
        print("Отправка прервана:", exc)
        stop.set()
        ws.close()

try:
    ws.send(json.dumps({
        "authorization": {"accessToken": "Bearer your-api-key"},
        "model": "muse-voice-transcribe-1.0",
        "audioEncoding": "PCM_24KHZ",
        "mode": "ENDPOINTING",
        "partialMode": "CUMULATIVE",
        "languageBias": ["Mandarin Chinese"],
        "emitAudioProgress": True
    }))
    ack = json.loads(ws.recv())
    if ack.get("type") == "error" or not ack.get("sessionId"):
        raise RuntimeError("Ошибка инициализации подключения: " + json.dumps(ack, ensure_ascii=False))
    print("sessionId:", ack["sessionId"])
    sender = threading.Thread(target=send_audio, daemon=True)
    sender.start()
    while not stop.is_set():
        message = ws.recv()
        if not message:
            break
        event = json.loads(message)
        print(json.dumps(event, ensure_ascii=False))
        if event.get("type") == "error":
            break
finally:
    stop.set()
    ws.close()
    if sender is not None:
        sender.join(timeout=2)

Справочник событий

audioProcessedMs показывает накопленный прогресс обработки; значения разных событий не следует складывать. В режиме CUMULATIVE новый частичный текст заменяет предыдущий накопленный результат; в режиме DELTA новый текст добавляется к предыдущему.

События сервера · Прогресс

audioProgress

Возвращает текущий накопленный прогресс обработки аудио.

ПолеТипОбязательноОписаниеПример
typestringДаВсегда `audioProgress`.audioProgress
audioProcessedMsintegerДаНакопленная длительность обработанного аудио в миллисекундах.1600
Пример JSON
{
  "type": "audioProgress",
  "audioProcessedMs": 1600
}

speechComplete.transcript содержит полную транскрипцию текущей речевой реплики. При завершении сеанса событие transcript с final: true может не содержать текста; клиент не должен заменять уже сохранённый накопленный текст или speechComplete.transcript пустой строкой.

Ограничения сеанса и обработка ошибок

Сеанс длится до примерно 60 минут. Отсутствие сообщений клиента в течение 15 секунд может привести к завершению ввода; сеть или состояние сервера также могут завершить соединение раньше. Клиент должен задавать общую длительность, тайм-аут чтения и стратегию ограниченного количества повторных попыток.

Код закрытияЗначениеРекомендация
1008Ошибка политики или протоколаПроверьте структуру первого кадра, аутентификацию, параметры и последующие управляющие сообщения
1011Прерывание на сервере или в вышестоящем сервисеСохраните sessionId, событие ошибки и причину закрытия перед решением о повторной попытке
1013Сервис временно недоступен или ограничивает частоту запросовВыполняйте ограниченное количество повторных попыток с увеличивающейся задержкой

Оплата

Транскрипция в реальном времени оплачивается по длительности обработанного аудио. Актуальные цены указаны в каталоге моделей текущего сайта. Значения в миллисекундах из событий прогресса показывают временную шкалу обработки; их не следует суммировать как отдельные начисления.

Справочные материалы