Agora Real-Time STT — 전사·번역 메시지 처리
Agora Real-Time STT 작업이 RTC channel의 audio를 전사하고 Beta 번역 결과를 DataStream으로 전달하는 흐름을 설명합니다. 공식 `SttMessage.proto` schema로 payload를 역직렬화하고 `(uid, sentence_id)` 단위로 중간 결과를 갱신합니다. UI debounce는 protocol 규칙이 아닌 application 정책으로 분리합니다.
Agora Real-Time STT는 RTC 채널의 음성을 실시간으로 전사하고, Beta 기능인 번역 결과를 자막 데이터로 채널에 보낼 수 있습니다. Conversational AI의 음성 에이전트 API와는 별도 제품·엔드포인트입니다. 이 글에서는 STT 작업 시작, 번역 설정, Protobuf 메시지 파싱과 자막 카드 상태 관리를 다룹니다.
전체 데이터 흐름
클라이언트가 직접 음성 인식을 하는 구조가 아닙니다. Real-Time STT 작업이 지정한 RTC 사용자 음성을 구독하고, 전사·번역 결과를 DataStream으로 채널에 게시합니다.
핵심 구성 요소
| 구성 요소 | 역할 |
|---|---|
/api/token | RTC 토큰 생성 (agora-token 패키지) |
/api/stt | Real-Time STT REST API 프록시(REST 자격 증명 보호) |
page.tsx | 클라이언트 — RTC 연결, 미디어, STT, UI |
UID 구성
| UID | 용도 |
|---|---|
| Random 1000~100999 | 로컬 사용자 |
88888 | STT subtitle-pushing bot(pubBotUid) |
55555 | 화면 공유 (별도 RTC client) |
STT Agent 시작/중지
STT 시작 — 작업 생성
Real-Time STT v1의 시작 엔드포인트는 /api/speech-to-text/v1/projects/{appid}/join입니다. 서버 프록시는 Customer ID/Secret 기반 Basic 인증을 보관하고, 브라우저에는 노출하지 않습니다. pubBotUid는 채널 안에서 고유해야 하며, App Certificate를 사용하면 해당 UID의 RTC 토큰을 pubBotToken으로 전달합니다.
STT 중지 — Agent Leave
DataStream 메시지 파싱
Real-Time STT의 기본 자막 포맷은 Agora가 제공하는 SttMessage.proto의 Agora.SpeechToText.Text 메시지입니다. msgId|partIdx|partSum|base64 형식은 현재 공식 STT 프로토콜이 아니므로 직접 청크를 조립하거나 atob()로 JSON을 만들지 않습니다. Web에서는 공식 .proto로 JavaScript 코드를 생성한 뒤 stream-message payload를 역직렬화합니다.
rtcConfig.enableJsonProtocol: true를 선택하면 JSON을 gzip 압축한 형식으로 받을 수도 있습니다. 이 글은 기본값인 Protobuf 경로를 사용합니다.
메시지 타입
data_type: "transcribe" — 음성 인식 결과
words[].is_final이false이면 해당 결과는 이후 갱신될 수 있습니다.sentence_id와text_ts를 사용해 같은 자막 문장의 갱신을 연결합니다.
data_type: "translate" — 번역 결과
original_transcript: 번역의 원문 전사trans[].lang,trans[].texts: 대상 언어와 번역 결과
자막 카드와 세그먼트 상태
중간 전사 결과는 같은 문장에 대해 여러 번 도착할 수 있습니다. UI 상태는 사용자 UID와 sentence_id를 함께 키로 사용해야 기존 문장을 덮어쓰지 않으면서 중간 결과를 갱신할 수 있습니다.
구조
| 개념 | 역할 |
|---|---|
| 카드 | 한 사용자의 연속 발화를 묶음 |
| 세그먼트 | (uid, sentence_id)별 전사·번역 텍스트 저장 |
| 타이머 | 애플리케이션이 정한 무음 시간 뒤 진행 중 카드를 완료 처리 |
| clearTimeout | 새 결과가 오면 기존 완료 타이머를 취소 |
sentence_id로 중간 결과 갱신하기
같은 sentence_id로 들어오는 중간 결과는 기존 세그먼트를 갱신하고, 새 sentence_id는 새 세그먼트로 추가합니다. 서로 다른 사용자가 같은 값을 가질 가능성에 대비해 UID도 키에 포함합니다.
번역 결과는 trans[].lang별로 저장하고, original_transcript와 sentence_id를 이용해 원문 세그먼트에 연결합니다. words[].is_final 또는 trans[].is_final이 false인 동안에는 같은 키의 값이 다시 올 수 있으므로 추가가 아니라 갱신으로 처리합니다.
연속 발화 묶기 — 애플리케이션 디바운스
아래 1초 값은 Agora 프로토콜이 보장하는 발화 경계가 아니라 이 데모의 UI 정책입니다. 사용 환경의 발화 속도와 자막 지연을 측정해 조정해야 합니다.
실제 시나리오: "안녕하세요" → (0.3초 쉼) → "반갑습니다"
| 단계 | 이벤트 | 카드 상태 | 타이머 |
|---|---|---|---|
| 1 | transcribe (sentence_id=A, "안녕하세요") | 새 카드와 세그먼트 생성 | 없음 |
| 2 | translate (sentence_id=A, "Hello", final) | 번역 추가 | 1초 타이머 시작 |
| 3 | 0.3초 후 transcribe (sentence_id=B, "반갑습니다") | clearTimeout 후 같은 카드에 세그먼트 추가 | 취소 |
| 4 | translate (sentence_id=B, "Nice to meet you") | 번역 추가 | 1초 타이머 재시작 |
| 5 | 1초 동안 새 결과 없음 | 카드를 완료 목록으로 이동 | 실행 |
화면 공유 구조
Agora SDK는 하나의 RTC client에서 2개의 video track을 publish할 수 없습니다. 화면 공유를 위해 별도 RTC client(UID 55555)를 생성합니다.
브라우저의 "공유 중지" 버튼 클릭 시 track-ended 이벤트로 자동 정리됩니다.
지원 언어와 제한
languages에는 전사할 언어를, translateConfig.languages에는 원문과 대상 언어를 지정합니다. 현재 v1 API는 전사 언어를 최대 4개까지 받고, subscribeAudioUids는 최대 32개 UID를 받을 수 있습니다. 실시간 번역은 Beta 기능이며 지원 언어와 제한은 바뀔 수 있으므로 고정 목록을 코드나 문서에 복제하지 말고 공식 지원 언어 표를 배포 시점에 확인합니다.
번역 설정은 소스 언어를 최대 4개, 소스별 대상 언어를 최대 10개까지 받을 수 있습니다. 번역이 동시에 처리하는 화자는 최대 5명입니다. 대규모 회의에서는 전체 RTC 참가자 수와 별개로 이 제한을 반영해 구독 대상을 선택해야 합니다.
핵심 요약
- Real-Time STT 작업이 채널의 음성을 구독하고 전사·번역 결과를 DataStream으로 전송
- 기본 결과는
SttMessage.proto기반 Protobuf이므로 공식 스키마로 역직렬화 (uid, sentence_id)를 키로 중간 결과를 갱신하고 새 문장을 별도 세그먼트로 보존- 1초 디바운스는 프로토콜 규칙이 아니라 데모의 UI 그룹화 정책
- 화면 공유는 별도 RTC client로 구현 (SDK 제약 때문)
관련 글
- #5 Conversational AI 통합 가이드 — 음성 대화 에이전트와 transcript 수신이 필요한 경우의 별도 제품 구조
- #3 RTM 실시간 채팅 시스템 구축 — RTC 미디어와 Signaling 메시지를 함께 구성하는 방법
- #23 오디오 파이프라인 해부 — Opus/RTP/Jitter Buffer — STT 에이전트가 채널에서 받아 ASR에 먹이는 오디오가 어떻게 운반되는지
- #2 Agora RTC 실시간 화상통화 구현 — STT를 얹기 전, RTC 채널/토큰/트랙 연결의 베이스라인
참고 자료
- Real-Time STT — Quickstart — 작업 시작·조회·중지 흐름
- Real-Time STT — Join API — v1 요청 필드와 제한
- Real-Time STT — Parse transcription data — Protobuf/JSON 메시지 구조와 파싱 절차
- Real-Time STT — Real-time translation (Beta) — 번역 설정과 제한
- Real-Time STT — Supported languages — 현재 전사·번역 언어 목록
- AgoraRTC.createScreenVideoTrack — Web SDK API Reference — 화면 공유 트랙 생성 및 별도 client publish 제약 확인
실제 데모
/agora-demo/stt