Typecast TTS → LiveKit Agent → 게스트 → 모니터 오디오 흐름 아키텍처 시각화

마지막 업데이트 2026-08-20

작성일: 2026-08-20 대상: conversationMode=livekit의 Typecast TTS 출력 핵심: 두 SFU를 게스트 브라우저가 연결한다

한눈에 보는 전체 구조

Typecast 요청 주체는 게스트가 아니라 livekit-agent 서버다. Agent가 합성 음성을 LiveKit Room에 올리면 게스트가 직접 듣고, 게스트는 그 AI 오디오를 Mediasoup에 다시 publish하여 모니터에게 전달한다.
외부 TTSPPI AgentLiveKit게스트 브리지모니터
Typecast APIHTTP POST 1회
스트리밍 WAV 응답
WAV bytes
apps/livekit-agentWAV parser → PCM
AudioEmitter.push()
AudioFrame
LiveKit RoomAI 대화 전용 SFU
Agent게스트
게스트 브라우저LiveKit RemoteAudioTrack 직접 재생
AI 오디오를 Mediasoup producer로 재발행
WebRTC relay
모니터 브라우저Mediasoup consumer로
게스트 미디어 수신
중요: 모니터는 LiveKit Room에 들어가지 않는다. LiveKit 트랙 객체가 모니터로 직접 이동하는 것도 아니다. 게스트가 수신한 AI 오디오를 브라우저 내부에서 Mediasoup용 트랙으로 구성해 다시 송출한다.

각 Room의 역할과 참가자

구분LiveKit RoomSocket.IO / Mediasoup Room
목적게스트와 AI Agent의 실시간 음성 대화게스트 수업 미디어를 모니터에 공유
참가자LiveKit Agent + 게스트게스트 + 모니터
AI 오디오Agent가 publish, 게스트가 직접 subscribe게스트가 재발행, 모니터가 consume
모니터 입장입장하지 않음입장함
관리 서버LiveKit 서버apps/socket + Mediasoup
이 분리 덕분에 모니터 수가 늘어도 LiveKit Agent Room의 참가자·구독 수는 늘지 않는다. 대신 모니터 AI 오디오는 게스트의 LiveKit 수신과 Mediasoup 재송출 상태에 의존한다.

Typecast 응답이 LiveKit 트랙이 되기까지

1문장 단위 HTTP POST

client.stream("POST", ...)로 Typecast에 합성을 요청한다.

2응답 본문 반복 수신

resp.aiter_bytes(4096)가 열린 HTTP 응답에서 최대 4KB씩 읽는다. 4KB마다 새 POST를 보내는 것이 아니다.

3WAV → PCM

WavStreamParser.feed()가 WAV 컨테이너에서 재생 가능한 PCM payload를 추출한다.

4AudioEmitter 채널

output_emitter.push(pcm)는 스피커 재생이 아니라 LiveKit Agents 내부 비동기 채널에 PCM을 넣는다.

5AudioFrame 출력 큐

LiveKit이 PCM을 AudioFrame으로 만들고 RoomIO의 프레임 큐와 rtc.AudioSource에 전달한다.

6LocalAudioTrack publish

Agent의 LocalAudioTrack을 LiveKit Room에 publish하고 게스트가 RemoteAudioTrack으로 구독한다.

Typecast WAV bytes
  → WavStreamParser.feed(chunk)
  → output_emitter.push(pcm)
  → SynthesizedAudio / rtc.AudioFrame
  → RoomIO.capture_frame(frame)
  → rtc.AudioSource(queue_size_ms=200)
  → LocalAudioTrack.publish_track(...)
  → Guest RemoteAudioTrack

근거: apps/livekit-agent/typecast_tts.py · LiveKit Agents tts/tts.py · voice/generation.py · voice/room_io/_output.py

버퍼와 공급 지연을 정확히 구분하기

Typecast 공급HTTP 응답 본문의 다음 오디오 바이트
Agent 프레임 공급PCM → AudioEmitter → AudioFrame
LiveKit AudioSource설치 SDK 기준 출력 큐 용량 200ms

게스트와 모니터에서 동시에 이상할 때 보는 경계

① Typecast 원본 WAV여기부터 이상하면 합성 결과 또는 업체 응답 문제다.
② Agent 파싱 후 PCM①은 정상이고 ②부터 이상하면 WAV 파싱·PCM 경계 문제다.
③ 게스트 LiveKit 수신②는 정상이고 ③부터 이상하면 LiveKit 프레임화·송출·게스트 downlink를 본다.
④ 모니터 Mediasoup 수신게스트는 정상이고 모니터만 이상하면 게스트 재송출·Mediasoup 경로를 본다.
관측우선 조사 범위판정 강도
게스트·모니터 모두 같은 끊김/이상음Typecast → Agent → LiveKit → 게스트 수신까지의 공통 경로모니터 단독 재생 문제 가능성 낮음
게스트 정상, 모니터만 이상게스트 AI 오디오 브리지 → Mediasoup producer/consumerLiveKit Agent 원인 가능성 낮음
중간 무음 반복Typecast 청크 간격, Agent 이벤트 루프, AudioSource 큐 잔량언더런 후보지만 청크 로그 없으면 미확정
실제 드르륵 파형 출력①~③ 원본 오디오 단계별 저장·비교단순 언더런만으로 확정 불가
관측 한계: AI_SPEAKING_START/STOP과 오디오 레벨은 끊김을 보여주지만 Typecast 청크 도착 시각이나 실제 출력 큐 잔량을 직접 증명하지 않는다. 근본 위치를 확정하려면 ① Typecast WAV, ② Agent PCM, ③ 게스트 수신 오디오를 같은 응답 ID로 저장해야 한다.

관련 문서