AGTCloud API Docs
가이드API 레퍼런스통합 및 리소스업데이트 및 도움말
오디오 처리Muse Voice Transcribe

실시간 전사

Muse Voice Transcribe WebSocket으로 PCM 오디오를 지속적으로 보내고 실시간 전사 이벤트를 수신합니다.

Muse Voice Transcribe 실시간 API는 지속적인 WebSocket 연결로 원시 PCM 오디오를 수신하고 진행률, 발화 차례 및 전사 이벤트를 계속 반환합니다. 이 API는 텍스트만 생성하며 음성 답변은 생성하지 않습니다.

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

인증 및 연결

WebSocket 연결 후 10초 안에 첫 JSON 텍스트 프레임을 보내야 합니다. Bearer API 키는 WebSocket 핸드셰이크 Header가 아니라 authorization.accessToken에 있습니다.

항목값
연결 주소wss://api.agtcloud.cn/v1/asr/realtime
인증 위치첫 JSON 텍스트 프레임의 authorization.accessToken
모델muse-voice-transcribe-1.0
선택적 쿼리 매개변수sessionId는 세션 식별자만 그대로 전달하며 연결 복구 또는 이전 세션 조회를 지원한다는 의미는 아닙니다

첫 프레임에는 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선택적 데이터 처리 옵션이며 적용 여부는 현재 서비스 및 계정 권한에 따라 달라집니다

오디오 입력

오디오는 WAV 헤더가 없는 PCM16 little-endian 모노 데이터여야 하며 첫 프레임에 선언한 16 kHz 또는 24 kHz 샘플링 레이트와 일치해야 합니다. 각 오디오 프레임은 1 MiB를 넘을 수 없으며 바이트 수는 짝수여야 합니다.

100 ms 단위의 오디오 청크를 실시간 속도로 보내는 것을 권장합니다. 24 kHz는 4800바이트, 16 kHz는 3200바이트에 해당합니다. 무음 구간에도 연속적인 시간선을 유지하려면 같은 형식의 PCM 무음 데이터를 보내야 합니다.

# 24 kHz, 모노, PCM16 원시 오디오 생성
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
WSSMuse 실시간 전사 연결
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)

이벤트 Reference

audioProcessedMs는 누적 처리 진행률을 나타내므로 여러 이벤트의 값을 더해서는 안 됩니다. CUMULATIVE에서는 새 부분 텍스트가 이전 누적 결과를 대체하고 DELTA에서는 추가된 텍스트를 이어 붙입니다.

서버 이벤트 · Progress

audioProgress

현재 누적 오디오 처리 진행률을 반환합니다.

필드유형필수설명예시 값
typestring예`audioProgress`로 고정됩니다.audioProgress
audioProcessedMsinteger예누적 처리된 오디오 길이이며 단위는 밀리초입니다.1600
JSON 예시
{
  "type": "audioProgress",
  "audioProcessedMs": 1600
}

speechComplete.transcript에는 현재 발화 차례의 전체 전사 결과가 포함됩니다. 세션 종료 시 final: true인 transcript 이벤트에 텍스트가 없을 수 있습니다. 클라이언트는 빈 문자열로 저장된 누적 텍스트 또는 speechComplete.transcript를 덮어써서는 안 됩니다.

세션 제한 및 오류 처리

세션은 최대 약 60분입니다. 15초 동안 클라이언트 메시지가 없으면 입력 마무리가 시작될 수 있으며 네트워크 또는 서버 상태에 따라 연결이 조기에 종료될 수도 있습니다. 클라이언트는 총길이, 읽기 시간 초과 및 제한된 재시도 전략을 설정해야 합니다.

종료 코드의미처리 권장 사항
1008정책 또는 프로토콜 오류첫 프레임 구조, 인증, 매개변수 및 후속 제어 메시지를 확인합니다
1011서버 또는 업스트림 중단sessionId, 오류 이벤트 및 종료 사유를 저장한 후 재시도 여부를 결정합니다
1013서비스 일시 사용 불가 또는 요청 제한백오프 전략으로 제한된 횟수만 재시도합니다

과금

실시간 전사는 처리된 오디오 길이에 따라 과금합니다. 구체적인 가격은 현재 사이트의 모델 목록을 기준으로 합니다. 진행률 이벤트의 밀리초 값은 처리 시간선을 나타내며 개별 청구 항목으로 하나씩 더해서는 안 됩니다.

참고 자료