Agora ConvoAI를 활용하면 RTC 채널의 음성을 실시간으로 텍스트 변환(STT) 하고 다른 언어로 번역까지 할 수 있습니다. 이 글에서는 ConvoAI의 STT + Translation이 어떻게 동작하는지, DataStream 청크 프로토콜과 카드 시스템의 구조를 정리합니다.
전체 데이터 흐름
[사용자 마이크] → Agora RTC 채널
↓
STT Agent (클라우드) 채널 참여
↓
ASR → Translation
↓
DataStream (UDP 청크)으로 결과 전송
↓
클라이언트: 청크 재조립 → JSON 파싱 → UI 렌더링
클라이언트가 직접 음성 인식을 하는 게 아닙니다. 클라우드 AI 에이전트가 RTC 채널에 참여하여 음성을 듣고, 인식·번역 결과를 DataStream으로 돌려보내는 구조입니다.
핵심 구성 요소
구성 요소
역할
/api/token
RTC 토큰 생성 (agora-token 패키지)
/api/convoai
STT REST API 프록시 (credentials 보호)
page.tsx
클라이언트 — RTC 연결, 미디어, STT, UI
UID 구성
UID
용도
Random 1000~100999
로컬 사용자
88888
ConvoAI STT Agent
55555
화면 공유 (별도 RTC client)
STT Agent 시작/중지
STT 시작 — Agent Join
const requestBody = {
name: `stt-agent-${Date.now()}`,
preset: "v2vt_base", // Voice-to-Voice+Translation 프리셋properties: {
channel: channelName,
token: agentToken,
agent_rtc_uid: "88888",
remote_rtc_uids: [`${localUid}`], // 인식 대상 사용자idle_timeout: 300,
advanced_features: { enable_rtm: false },
parameters: { data_channel: "datastream" },
asr: { language: "ko-KR" }, // 음성 인식 언어translation: { language: "en-US" }, // 번역 대상 언어tts: { enable: false }, // TTS 비활성화 (텍스트만)
},
};
// 서버 프록시를 통해 ConvoAI API 호출const res = awaitfetch("/api/convoai", {
method: "POST",
body: JSON.stringify({ action: "join", requestBody }),
});
v2vt_base 프리셋: Voice-to-Voice Translation의 기본 설정. TTS를 끄면 STT + 번역 텍스트만 받을 수 있습니다.
ConvoAI는 JSON 메시지를 base64 인코딩 후 UDP 크기 제한(~1400B)에 맞게 분할하여 전송합니다.
청크 포맷
msgId|partIdx|partSum|base64Data
필드
타입
설명
msgId
string
메시지 고유 ID
partIdx
number
파트 인덱스 (1-based)
partSum
number | "???"
총 파트 수 (미확정이면 "???")
base64Data
string
base64 인코딩된 JSON 조각
3파트 메시지 예시
abc123|1|3|eyJvYmplY3QiOiJ1c2VyLnRyYW5z... ← part 1/3
abc123|2|3|Y3JpcHRpb24iLCJ0ZXh0Ijoi7JWI... ← part 2/3
abc123|3|3|64WV7ZWY7IS47JqUIiwiZmluYWwiOnRydWV9 ← part 3/3