- Published on
WebRTC 미디어 인프라 2026 — LiveKit·Pion·Daily·100ms·mediasoup·Janus·Cloudflare Realtime와 WHIP/WHEP 심층 탐구
- Authors

- Name
- Youngju Kim
- @fjvbn20031
프롤로그 — WebRTC는 인프라 선택이 90%다
2018년 WebRTC는 "브라우저에서 P2P 영상통화를 어떻게 짜는가"의 문제였다. STUN/TURN 서버 한 대, RTCPeerConnection 코드 200줄, 그리고 영상 두 칸짜리 데모 페이지. 끝.
2026년의 WebRTC는 다른 문제다.
- 100명짜리 룸을 어떻게 굴리지? — SFU(Selective Forwarding Unit)가 답이다. P2P 메시는 N제곱이라 5명에서 무너진다.
- AI 음성 에이전트는 어떻게 붙이지? — LLM의 출력 토큰을 TTS로, 마이크 오디오를 STT로, 모두 200ms 지연 내에. WebRTC의 강점이다.
- 라이브 송출은 어떻게? — RTMP는 옛날 코덱(H.264만)에, 지연도 2~5초다. WHIP(WebRTC-HTTP Ingestion Protocol)/WHEP(WebRTC-HTTP Egress Protocol)가 새 표준으로 올라섰다.
- 우리는 매니지드(Daily·100ms·Twilio·Chime)를 쓸까, 자가 호스트(LiveKit OSS·mediasoup·Janus·Jitsi)를 쓸까?
이 글은 "WebRTC 코드 200줄"이 아니라 "프로덕션 미디어 인프라를 어디서 어떻게 굴리느냐"를 다룬다. 이 결정 한 번이 6개월 뒤의 인프라 비용·지연·운영 부담을 결정한다.
요약: 2026년 5월 기준 큰 그림은 이렇다.
- LiveKit이 AI 음성 에이전트 인프라의 사실상 표준이 됐다. LiveKit Agents 프레임워크는 OpenAI Realtime API·Deepgram·ElevenLabs와 일급으로 통합된다.
- Pion이 Go 진영의 WebRTC 엔진으로 굳어졌다. LiveKit 자체도 Pion 위에 올려져 있다.
- WHIP/WHEP가 RTMP를 대체하는 라이브 송출 표준으로 정착했다. OBS 30+이 WHIP 송출을 기본 지원한다.
- 매니지드 진영(Daily·100ms·Twilio Video·AWS Chime SDK)은 살아 있지만 가격 압박이 거세다. LiveKit Cloud가 1라운드 강자.
- Cloudflare Realtime이 엣지에서 WebRTC를 던지며 새 카테고리를 만들었다. Calls API + Realtime SFU.
자, 출발한다.
1장 · WebRTC 인프라의 풍경 — 2026년 지도
먼저 분류. 모두가 같은 자리에 있지 않다.
| 카테고리 | 대표 제품 | 한 줄 요약 |
|---|---|---|
| AI 음성·영상 인프라(매니지드+OSS) | LiveKit Cloud / LiveKit OSS | 2026년 음성 에이전트 표준. Agents 프레임워크. |
| 매니지드 비디오 API | Daily.co, 100ms, Twilio Video, AWS Chime SDK, Vonage | SDK·매니지드 SFU. 빠른 출시. |
| 엣지 WebRTC | Cloudflare Realtime / Calls | 글로벌 엣지 SFU. 새 카테고리. |
| 자가 호스트 SFU(Node.js) | mediasoup | 라이브러리 형태. 직접 시그널링 짠다. |
| 자가 호스트 SFU(C) | Janus | 플러그인 아키텍처. OG. |
| 풀스택 OSS | Jitsi (Meet/Videobridge) | 다운로드 후 쓰는 미팅 솔루션 + SFU. |
| WebRTC 엔진(Go) | Pion | Go에서 WebRTC를 짤 수 있게 한 라이브러리. |
| WebRTC 엔진(Rust) | webrtc-rs | Pion의 Rust 포팅. 성장 중. |
| 라이브 송출 표준 | WHIP / WHEP | HTTP 한 번에 WebRTC 세션 시작. RTMP 대체. |
이 글의 초점은 굵게 갈리는 LiveKit·Pion·Daily·100ms·mediasoup·Janus·Jitsi·Twilio·Chime·Cloudflare Realtime이다. WHIP/WHEP는 별도 장에서 따로 다룬다.
왜 LiveKit이 표준이 됐는가
- AI 음성 에이전트 시대의 1등 인프라. LiveKit Agents 프레임워크가 OpenAI Realtime·Deepgram STT·ElevenLabs TTS·Cartesia와 일급 통합.
- OSS와 클라우드(LiveKit Cloud) 양 진영을 동시에 굴린다. 자가 호스트로 시작해서 클라우드로 갈아탈 수 있다.
- Pion 위에 짜져서 Go 단일 바이너리. 쿠버네티스·도커 배포가 단순.
- LiveKit의 클라이언트 SDK(JS·Swift·Kotlin·Flutter·Unity·React Native)가 잘 정리돼 있다.
2장 · 7축으로 보는 비교 매트릭스
상세 분석으로 들어가기 전, 한눈에 보는 큰 그림.
| 축 | LiveKit | Daily | 100ms | mediasoup | Janus | Jitsi | Twilio Video | AWS Chime SDK | Cloudflare Realtime |
|---|---|---|---|---|---|---|---|---|---|
| 운영 모델 | 매니지드+OSS | 매니지드 | 매니지드 | OSS 라이브러리 | OSS 데몬 | OSS 풀스택 | 매니지드 | 매니지드 | 매니지드(엣지) |
| 언어 | Go(Pion) | 비공개 | 비공개 | Node.js+C++ | C | Java+C(libwebrtc) | 비공개 | 비공개 | 비공개 |
| AI 음성 통합 | 일급 (Agents) | 좋음 | 좋음 | 직접 | 직접 | 직접 | 보통 | 좋음 (Voice Focus) | 직접 |
| WHIP/WHEP | 일급 지원 | 지원 | 지원 | 플러그인 | 플러그인 | 외부 도구 | 미지원 | 미지원 | 일급 지원 |
| 글로벌 라우팅 | 클라우드에서 일급 | 일급 | 일급 | 직접 | 직접 | 직접 | 일급 | 일급 | 일급(엣지) |
| 가격 압박 | 강함(OSS+클라우드) | 보통 | 보통 | 인프라 비용만 | 인프라 비용만 | 인프라 비용만 | 비쌈 | 비쌈 | 새로움 |
| 신규 채택 추이 | 매우 강함 | 안정 | 강함(인도 시장) | 안정 | 감소 | 안정 | 감소 | 안정 | 빠른 성장 |
이 표만 보고 결정을 내려선 안 된다. 다음 장부터 각 도구를 정확히 무엇이 되고 안 되는지 짚는다.
3장 · LiveKit — 표준이 된 이유, 그리고 LiveKit Agents
LiveKit은 2021년 출범 이래 가장 빠르게 자리잡은 WebRTC 인프라다. OSS(Apache 2.0)와 LiveKit Cloud 양 진영을 동시에 굴린다. 2025~2026 사이 결정적인 사건이 둘이었다.
- LiveKit Agents 프레임워크 — Python/Node SDK로 LLM·STT·TTS·VAD를 묶어 음성 에이전트를 만든다. OpenAI Realtime API·Deepgram·AssemblyAI·ElevenLabs·Cartesia 등이 일급 통합.
- OpenAI가 LiveKit을 공식 채택 — ChatGPT 음성 모드 인프라가 LiveKit 위에 올라간다는 사실이 공개됐다. 사실상 산업 표준 도장.
왜 LiveKit이 강한가
- 단일 Go 바이너리 —
livekit-server한 개. Pion 기반. 도커 한 줄로 띄운다. - 클라이언트 SDK 풀 — JS, Swift, Kotlin, Flutter, Unity, React Native, Python. 모두 같은 추상화(
Room,Participant,Track). - Egress·Ingress 서비스 — 녹화(MP4·HLS), 스트림 추출(WHIP/WHEP 인제스트), 트랜스코드까지 모듈로 분리.
@livekit/components-react— 미팅 UI를 30분에 짤 수 있는 사전 빌트 컴포넌트.- LiveKit Cloud — 자가 호스트 운영이 부담스러우면 같은 API로 갈아탄다. SLA·글로벌 라우팅 포함.
LiveKit Agents 스켈레톤
음성 에이전트 한 개의 가장 단순한 모양. 이 코드는 마이크 입력을 OpenAI Realtime로 보내고, 모델의 응답 오디오를 룸으로 도로 송출한다.
# agent.py — LiveKit Agents 최소 스켈레톤
import asyncio
import os
from livekit import agents, rtc
from livekit.agents import AgentSession, Agent
from livekit.plugins import openai, deepgram, elevenlabs, silero
class VoiceAssistant(Agent):
def __init__(self) -> None:
super().__init__(
instructions=(
"You are a friendly voice assistant. "
"Answer in short, conversational sentences."
),
)
async def on_enter(self) -> None:
# 인사말 자동 송출
await self.session.say("안녕하세요. 무엇을 도와드릴까요?")
async def entrypoint(ctx: agents.JobContext) -> None:
await ctx.connect() # 룸에 합류
session = AgentSession(
# 1) STT — Deepgram nova-3
stt=deepgram.STT(model="nova-3"),
# 2) LLM — OpenAI Realtime(또는 일반 chat completions)
llm=openai.LLM(model="gpt-4o-mini"),
# 3) TTS — ElevenLabs
tts=elevenlabs.TTS(voice_id="Rachel"),
# 4) VAD — Silero 음성 활성 감지(턴 결정)
vad=silero.VAD.load(),
)
await session.start(
agent=VoiceAssistant(),
room=ctx.room,
)
if __name__ == "__main__":
agents.cli.run_app(
agents.WorkerOptions(entrypoint_fnc=entrypoint),
)
배포는 python agent.py dev로 로컬에서 띄우고, 그대로 python agent.py start로 프로덕션 모드. LiveKit 서버가 새 룸을 만들면 Agents 워커가 자동으로 매칭되어 합류한다.
OpenAI Realtime + WebRTC 직결 모드
OpenAI Realtime API는 2024년 출시 당시 WebSocket 전용이었다. 2025년 WebRTC 연결 모드가 추가됐다. 클라이언트가 SDP를 만들어 OpenAI 엔드포인트에 직접 던지면, 모델이 SFU처럼 응답한다. 지연이 200~400ms로 떨어진다.
LiveKit Agents는 이 두 가지를 모두 추상화한다.
# OpenAI Realtime을 WebRTC 직결로 쓰는 모양
from livekit.plugins import openai
session = AgentSession(
llm=openai.realtime.RealtimeModel(
model="gpt-4o-realtime-preview",
voice="alloy",
# WebRTC 모드 — 별도 STT/TTS 필요 없음
modalities=["audio", "text"],
),
)
이 모드에선 STT/TTS가 따로 필요 없다. 모델이 직접 오디오 입출력을 처리한다. 단점은 가격이 높고, 모델 선택이 OpenAI Realtime 계열로 제한된다는 것.
LiveKit의 약점
- 매니지드 진영에 비해 클라이언트 사이드 분석(품질 측정·세션 리플레이)이 약하다. Daily가 이 영역에서 앞선다.
- 자가 호스트로 가면 TURN·로드 밸런서·녹화 스토리지 등 부속을 모두 직접 굴려야 한다.
- 라우팅 토폴로지(노드 클러스터링)는 강력하지만 학습 곡선이 있다.
4장 · Pion — Go의 WebRTC 엔진
Pion은 Go로 짜인 WebRTC 풀 구현이다. 2018년 처음 공개됐고, LiveKit·Galene·ion-sfu·OBS WHIP 송출까지 모두 Pion 위에 올라가 있다. Go의 단일 바이너리·동시성·크로스 컴파일 장점이 미디어 서버 운영에 잘 맞는다.
왜 Pion인가
- libwebrtc(구글의 C++ WebRTC)는 빌드와 임베드가 악명 높게 어렵다. Pion은
go get으로 끝. - Go의 goroutine이 다수 피어 관리에 자연스럽게 맞는다.
- 모든 WebRTC 부속(SDP·DTLS·SRTP·ICE·SCTP)이 분리된 라이브러리로 제공돼 부분만 가져다 쓸 수 있다.
Pion으로 짠 가장 단순한 SFU 피어 한 조각
피어 하나가 한 명의 발신자 트랙을 받아 다른 참가자에게 그대로 흘려보내는 코드의 최소형. 실제 SFU 구축은 트랙 라우팅·시뮬캐스트·DataChannel·재연결 처리가 추가로 들어간다.
// sfu_peer.go — Pion으로 짠 1대1 트랙 포워딩 한 조각
package main
import (
"fmt"
"github.com/pion/webrtc/v4"
)
func newPeer() (*webrtc.PeerConnection, error) {
api := webrtc.NewAPI()
pc, err := api.NewPeerConnection(webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
{URLs: []string{"stun:stun.l.google.com:19302"}},
},
})
if err != nil {
return nil, err
}
// 인입 트랙을 받아서 그대로 outgoing 트랙으로 송출
pc.OnTrack(func(remote *webrtc.TrackRemote, _ *webrtc.RTPReceiver) {
// outgoing 트랙 생성(VP8 가정)
local, err := webrtc.NewTrackLocalStaticRTP(
remote.Codec().RTPCodecCapability,
"video",
"pion-sfu",
)
if err != nil {
return
}
if _, err := pc.AddTrack(local); err != nil {
return
}
// RTP 패킷 그대로 포워딩
buf := make([]byte, 1500)
for {
n, _, readErr := remote.Read(buf)
if readErr != nil {
return
}
if _, writeErr := local.Write(buf[:n]); writeErr != nil {
return
}
}
})
pc.OnICEConnectionStateChange(func(s webrtc.ICEConnectionState) {
fmt.Println("ICE state:", s.String())
})
return pc, nil
}
이 코드의 한계는 명확하다. 1대1만 처리하고, 시뮬캐스트(다중 해상도 트랙)는 안 받고, 시그널링은 안 들어있다. 그래도 Pion이 얼마나 직관적인지는 잘 보여준다.
Pion 기반 프로젝트들
- LiveKit
- Galene — 1인 운영을 가정한 가벼운 SFU. 강의·소규모 회의에 좋다.
- ion-sfu — 풀 SFU. 시뮬캐스트·녹화·라우팅.
- OBS Studio의 WHIP 송출 — Pion 클라이언트 모듈.
5장 · mediasoup — Node.js의 표준 SFU 라이브러리
mediasoup은 Node.js 진영의 SFU 라이브러리다. 자체 데몬이 아니라 Node 프로세스에서 임포트하는 라이브러리 형태라는 점이 중요하다. Worker는 C++로 짜져 있고, JS는 그걸 조종한다.
왜 mediasoup인가
- 라이브러리 형태라 시그널링·인증·룸 관리를 완전히 자유롭게 설계한다.
- 시뮬캐스트·SVC·녹화·트랜스코드·서버 라우팅을 모두 지원.
- discord·Microsoft Mesh 같은 큰 곳이 mediasoup을 기반으로 짰다는 사례가 있다.
mediasoup의 단점
- 시그널링부터 룸 관리·인증·재연결까지 전부 직접 짜야 한다. LiveKit/Janus가 끝에 끝까지 묶어주는 것과 정반대.
- 학습 곡선이 가장 가파르다. 라우터·트랜스포트·프로듀서·컨슈머의 추상이 다단계.
- Node 진영 외의 클라이언트 SDK는 커뮤니티가 굴린다.
mediasoup은 "팀에 미디어 인프라를 깊게 이해하는 엔지니어가 있다"는 전제일 때만 권한다. 사실상 매니지드/LiveKit이 채울 자리에 mediasoup을 직접 짜면 6개월 정도가 비용으로 나간다.
6장 · Janus — C로 짠 OG SFU
Janus는 2014년 출시된 C 기반 SFU다. WebRTC 인프라의 OG이고, 플러그인 아키텍처가 트레이드마크다.
- VideoRoom 플러그인 — 전형적인 다자간 미팅.
- Streaming 플러그인 — RTP·RTSP를 WebRTC로 전환.
- AudioBridge 플러그인 — 다자간 오디오 믹싱.
- WHIP 플러그인 — 표준 WHIP 송출 수신.
Janus의 위치
- 매우 오래되고 안정적이다. 작은 코어·낮은 메모리 사용·C의 성능.
- 플러그인 모델이 라이브 스트리밍·통화·믹싱 등 다양한 시나리오를 한 데몬에서 굴리게 한다.
- 단점: 시그널링 프로토콜이 독자적(REST·WebSocket Janus API). 클라이언트 SDK가 매니지드만큼 풍부하진 않다.
- 신규 채택은 LiveKit/매니지드로 옮겨가는 추세지만, 살아있고 활발하다.
7장 · Jitsi — 풀스택 OSS 미팅 솔루션
Jitsi는 OSS 풀스택 미팅 솔루션이다. 한 번 다운로드하면 Jitsi Meet(웹 UI) + Videobridge(SFU) + Jicofo(시그널링) + Prosody(XMPP) 묶음이 통째로 굴러간다.
- 8x8(Jitsi 인수)이 메인 메인테이너.
- 자가 호스트로 "회사 내부 미팅 솔루션"을 빠르게 띄울 때 1순위.
- API 통합은 약하다 — Jitsi는 "솔루션"이지 "라이브러리"가 아니다.
대안 사용 사례
- 회사 내부 미팅 솔루션 자가 호스트 → Jitsi.
- 우리 제품 안에 비디오를 넣어야 함 → LiveKit / mediasoup / 매니지드.
- 둘이 헷갈리는 일이 잦다. 목표가 다르다.
8장 · 매니지드 진영 — Daily, 100ms, Twilio Video, AWS Chime SDK
매니지드 비디오 API의 큰 패턴은 비슷하다. SDK + 서버 SDK + 매니지드 SFU + 녹화 + 분석. 다만 강점이 갈린다.
Daily.co
- 가장 깔끔한 DX. 한 줄짜리
prebuilt임베드(call-frame)와 풀 SDK 양쪽 다 강함. - 분석·세션 리플레이가 가장 깊다. 어떤 사용자의 어떤 통화가 어떻게 망가졌는지 가장 잘 보여줌.
- 가격: 분당 비용. 1000명 이내 규모에선 합리적.
100ms
- 인도 기반. RoomKit이라는 사전 빌트 미팅 UI 패키지.
- 인도·동남아 시장 점유율이 강함. 라이브 스트리밍 RoomKit이 따로 있어 라이브 송출도 한 묶음.
- 가격 경쟁력이 강점.
Twilio Video
- 기업 진영의 표준이었지만 2024년 신규 가입을 닫고 2026년 EOL로 가는 중. Twilio 음성·SMS는 살아 있다.
- 현재 시점에서 Twilio Video를 신규로 고르는 이유는 거의 없다.
AWS Chime SDK
- AWS 진영에서 영상 통화를 짤 때 1순위. IAM·CloudWatch·S3 녹화 등 AWS 생태계 통합이 강점.
- Voice Focus(잡음 제거), Echo Reduction 같은 부속이 일급으로 들어 있음.
- 단점: 가격이 비싸고, 클라이언트 SDK가 LiveKit·Daily만큼 매끈하진 않다.
Cloudflare Realtime / Calls
- 2024년 등장. Cloudflare의 엣지 네트워크 위에 WebRTC SFU를 던졌다는 새 카테고리.
- 글로벌 분산이 일급이고, WHIP/WHEP 표준 지원이 강력.
- 가격 모델이 새로워서 트래픽 패턴에 따라 큰 차이가 난다. 검토 가치는 충분.
- 단점: 아직 생태계가 어리다. SDK·문서가 LiveKit·Daily에 못 미친다. 그래도 빠르게 따라잡는 중.
9장 · WHIP/WHEP — RTMP를 대체하는 새 표준
라이브 송출은 오래 RTMP의 자리였다. 2002년 어도비가 만든 프로토콜. H.264 코덱·Flash 시대에 만들어졌고, 결정적인 약점이 셋이었다.
- 코덱이 H.264로 사실상 고정. AV1·VP9·HEVC 못 함.
- 지연이 2
5초로 큼. WebRTC는 200500ms. - TCP 기반이라 패킷 손실 회복이 굼뜸.
WHIP(WebRTC-HTTP Ingestion Protocol)와 WHEP(WebRTC-HTTP Egress Protocol)이 답이다. IETF 표준 절차.
WHIP의 작동 흐름
- 송출자가 SDP offer를 HTTP POST로 서버에 던진다.
- 서버가 SDP answer를 200 OK로 돌려준다.
- DTLS·SRTP 협상이 끝나면 미디어가 흐르기 시작.
이게 전부다. 시그널링이 HTTP 한 번. WebSocket·시그널링 서버 별도 구축이 필요 없다.
WHIP 송출 클라이언트 — 가장 단순한 fetch 한 줄
// whip-publisher.js — 마이크/카메라를 WHIP으로 송출
async function publishWHIP(endpoint, token) {
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
});
// 로컬 미디어 추가
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: { width: 1280, height: 720 },
});
stream.getTracks().forEach((track) => pc.addTrack(track, stream));
// SDP offer 생성
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// ICE gathering 완료까지 대기(간소화)
await new Promise((resolve) => {
if (pc.iceGatheringState === 'complete') return resolve(null);
pc.addEventListener('icegatheringstatechange', () => {
if (pc.iceGatheringState === 'complete') resolve(null);
});
});
// WHIP 엔드포인트로 SDP POST
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/sdp',
Authorization: `Bearer ${token}`,
},
body: pc.localDescription.sdp,
});
if (!response.ok) {
throw new Error(`WHIP failed: HTTP ${response.status}`);
}
// 서버의 answer로 RemoteDescription 설정
const answer = await response.text();
await pc.setRemoteDescription({ type: 'answer', sdp: answer });
return pc;
}
// 사용
const pc = await publishWHIP(
'https://ingest.example.com/whip/my-stream',
'my-token',
);
WHIP/WHEP가 채택된 곳
- OBS Studio 30+ — WHIP 송출이 기본 옵션으로 들어옴.
- LiveKit Ingress — WHIP·RTMP·SRT를 모두 받는 입구.
- Cloudflare Realtime — WHIP/WHEP 일급 지원.
- Twitch·YouTube Live — 시험 중(2026년 5월 기준).
- mediasoup·Janus — 플러그인.
WHIP/WHEP가 RTMP를 대체하는 이유
- 코덱 자유(VP9·AV1·H.264·Opus 등 SDP 협상으로 결정).
- 지연이 한 자릿수 초 → 0.5초.
- HTTPS POST 한 번이라 방화벽 통과가 쉽다(443).
- WebRTC 표준 위라 디버깅 도구가 그대로 쓰임.
10장 · SFU vs MCU vs P2P — 토폴로지 결정
WebRTC 인프라의 토폴로지가 결정의 큰 축이다.
| 토폴로지 | 어떻게 굴러가는가 | 적합 상황 |
|---|---|---|
| P2P 메시 | 모든 참가자가 다른 모두에게 직접 연결 | 2~3인. 매우 작음. |
| P2P 스타 | 호스트 하나가 다른 참가자에게 송출 | 1대N 스트리밍. 호스트 업로드 비대. |
| SFU | 서버가 인입 스트림을 받아 다른 참가자에게 그대로 포워딩 | 미팅·웨비나·라이브. 사실상 표준. |
| MCU | 서버가 모든 스트림을 디코드·믹스·재인코드해서 하나로 송출 | 전화 컨퍼런스. 클라이언트 부하 최저. |
SFU가 표준이 된 이유
- 서버 CPU 비용이 낮다. 디코드·인코드를 안 함. RTP 패킷을 그대로 라우팅만.
- 시뮬캐스트(다중 해상도) 지원. 수신자의 대역에 맞춰 적절한 해상도 트랙을 선택.
- SVC(스케일러블 비디오 코딩) 지원. 한 트랙에 다중 레이어가 들어가 더 효율적.
MCU의 자리
- 전화 컨퍼런스(PSTN 게이트웨이) — 모두를 하나로 믹스해야 함.
- 매우 약한 클라이언트(임베디드·구형 단말) — 한 트랙만 받으면 되니까.
- 녹화의 최종 산물(단일 합성 비디오).
P2P의 자리
- 1대1 영상통화 — STUN으로 직접 연결되면 서버 비용 0.
- 작은 가족·친구용 앱. 3인 이상이면 SFU로 가는 게 맞다.
11장 · 코덱 풍경 — Opus, VP8, VP9, AV1, H.264, H.265
WebRTC의 의무 코덱은 오디오 Opus, 비디오 VP8·H.264다. 나머지는 선택.
오디오
- Opus — 사실상 유일한 선택. 8~510kbps 가변. 음악·음성 양쪽 다 잘함. 모든 WebRTC 구현이 지원.
- G.711·G.722 — PSTN 게이트웨이에서 가끔 쓰인다. WebRTC 내부는 거의 안 씀.
비디오
- VP8 — WebRTC 초창기부터 의무. 가장 호환성 높음.
- H.264 — 의무. iOS Safari에서 하드웨어 가속 일급. 미국 시장에서 선호.
- VP9 — 선택. AV1 전 단계의 효율 좋은 코덱. Chrome·Firefox 지원.
- AV1 — 선택. 가장 효율적(VP9보다 30% 더). 인코딩 비용이 비싸 모든 시나리오에 맞진 않음. 2026년 들어 데스크톱 하드웨어 가속이 보편화되며 빠르게 채택 중.
- H.265(HEVC) — WebRTC에선 거의 안 씀. 라이선스 부담.
시뮬캐스트와 SVC
- 시뮬캐스트 — 송출자가 같은 영상을 여러 해상도/비트레이트로 동시에 송출. SFU가 수신자에 맞춰 하나를 선택.
- SVC — 한 스트림 안에 베이스 레이어 + 인핸스먼트 레이어가 묶여 있음. SFU가 레이어를 깎아 보냄. AV1·VP9에서 강함.
결정
- 시작은 VP8 + Opus로. 모든 곳에서 호환.
- iOS 일급 지원 → H.264도 함께.
- 대역폭 절약·고화질 → AV1 추가, 인코딩 비용 감안.
- 시뮬캐스트는 무조건 켜라. SFU 입장에서 수신자별 적응이 안 되면 큰 룸에서 무너진다.
12장 · 매니지드 vs 자가 호스트 결정 매트릭스
큰 결정 한 번. 이 매트릭스가 가이드.
| 상황 | 추천 | 이유 |
|---|---|---|
| MVP, 6개월 안에 출시 | 매니지드 (LiveKit Cloud, Daily, 100ms) | 미디어 인프라에 시간을 쓰지 마라 |
| 음성 에이전트 중심(LLM·STT·TTS) | LiveKit (Cloud 또는 OSS) | Agents 프레임워크가 기다리고 있음 |
| 회사 내부 미팅 솔루션 | Jitsi 자가 호스트 | "솔루션" 그대로 떨어짐 |
| WHIP 라이브 송출 | LiveKit Ingress 또는 Cloudflare Realtime | WHIP 일급 지원 |
| 글로벌 분산, 엣지 라우팅 | Cloudflare Realtime 또는 LiveKit Cloud | 엣지 위 SFU |
| 인프라 비용 최소화(중간 규모) | LiveKit OSS 자가 호스트 | 매니지드 분당 비용 안 냄 |
| 시그널링·라우팅을 완전 통제 | mediasoup | 라이브러리 형태, 모든 결정이 내 것 |
| AWS 생태계 깊게 통합 | AWS Chime SDK | IAM·S3·CloudWatch 동기화 |
| 전화 게이트웨이(PSTN) 통합 | Twilio Voice + LiveKit SIP | Twilio Voice는 살아있음 |
| 인도·동남아 시장 가격 | 100ms | 가격 경쟁력 |
매니지드 → 자가 호스트로 이주 시그널
- 매니지드 비용이 월 USD 5천을 넘기 시작 → 자가 호스트 인프라 + DevOps 1명의 비용을 넘어선다.
- 데이터 주권·HIPAA·온프레미스 요구사항 → 매니지드는 어렵다.
- 미디어 파이프라인을 깊게 만져야 함(맞춤 트랜스코드·맞춤 라우팅) → 매니지드의 추상이 막힌다.
자가 호스트의 숨은 비용
- TURN 서버 — 회사 방화벽 뒤 사용자 비율만큼 트래픽을 떠안는다. 트래픽 비싸다.
- 로드 밸런서·노드 클러스터링.
- 녹화 스토리지·트랜스코드 워커.
- 모니터링·관측성(WebRTC 통계가 가장 까다로움).
- 비상 대응 — 미디어 서버는 다른 서버보다 까다롭다.
13장 · 클라이언트 사이드 라이브러리
서버만큼이나 클라이언트가 결정의 절반이다.
표준 RTCPeerConnection
- 브라우저가 기본으로 주는 API. 가장 가볍지만 가장 시그널링을 직접 짜야 함.
- 작은 P2P 데모·WHIP 송출·매우 가벼운 상황에 맞다.
LiveKit Client SDK
Room,Participant,Track추상화. 자동 재연결·시뮬캐스트·DataChannel.@livekit/components-react— 미팅 UI를 즉시 만든다.
Daily의 call-frame
- 한 줄 iframe 임베드. 가장 단순. 풀 SDK도 따로 있다.
mediasoup-client
- mediasoup 서버와 짝. 트랜스포트·프로듀서·컨슈머 추상.
Janus의 JS 어댑터
- Janus 서버와 짝. REST/WebSocket 시그널링.
simple-peer
- 가장 단순한 P2P 라이브러리. 시그널링을 직접 굴리는 모드.
14장 · 운영 — TURN, NAT, 모니터링
운영의 절반은 시그널링·NAT·관측성에 들어간다.
STUN과 TURN
- STUN — 클라이언트가 자기 공인 IP/포트를 알아내는 서버. UDP 한 패킷 RTT.
- TURN — STUN으로 안 되는 NAT(대칭 NAT, 방화벽) 뒤 사용자를 위한 미디어 릴레이. 트래픽이 TURN을 지나가므로 비싸다.
coturn— TURN 서버의 사실상 표준 OSS 구현.- TURN 트래픽 비율은 보통 5~20%. 회사 네트워크가 많으면 50%까지도.
getStats()로 보는 WebRTC 관측성
- 표준
RTCPeerConnection.getStats()가 RTT·jitter·패킷 손실·코덱·해상도 등을 준다. - 1분당 한 번 수집해서 데이터 웨어하우스로 흘려라.
- 매니지드(Daily·LiveKit Cloud)는 이를 대시보드로 떨어뜨려 준다.
통화 품질 지표
- MOS(Mean Opinion Score) — 1~5의 통화 품질 점수. RTT·패킷 손실·jitter에서 추정.
- 시작 실패율 — 룸 입장까지 도달 못한 비율. 핵심 SLI.
- 재연결 빈도 — 한 통화당 재연결 횟수.
- 비디오 동결 시간 — 비디오가 멈춰 있던 누적 시간.
15장 · 라이브 스트리밍 시나리오
라이브 송출은 WebRTC 인프라의 별도 영역으로 굳어졌다. 시나리오별 권장.
| 시나리오 | 송출 | 라우팅 | 수신 |
|---|---|---|---|
| 강연자 한 명 → 1만 명 시청 | OBS WHIP 송출 | LiveKit/Cloudflare Realtime SFU | HLS 트랜스코드 후 HLS 시청자 |
| 강연자 한 명 → 100명 인터랙티브 | OBS WHIP 송출 | LiveKit SFU | WHEP 수신 |
| 다자간 미팅 녹화 → 시청자에 송출 | LiveKit Room | LiveKit Egress | HLS 트랜스코드 |
| 게임 플레이 송출 → 인터랙티브 채팅 | OBS WHIP | Cloudflare Realtime | WHEP 또는 HLS |
WebRTC 라이브가 RTMP 라이브를 대체하는 한계
- 시청자 규모가 매우 큼(10만+) → CDN 거리는 HLS·DASH가 여전히 표준. WebRTC는 5만 이내가 합리적.
- 광고 삽입·DRM 같은 방송 기능은 HLS 진영이 깊다.
- WebRTC 라이브는 "낮은 지연 + 양방향 인터랙션"이 강점인 영역에서 우위.
16장 · 보안·DRM·E2EE
WebRTC는 기본적으로 DTLS-SRTP 암호화다. 미디어 패킷은 클라이언트와 서버 간에 항상 암호화된다. 다만 SFU 모드에선 SFU가 평문으로 라우팅 결정을 한다(코덱 정보·시뮬캐스트 레이어 선택 등).
E2EE — Insertable Streams
- 진정한 종단간 암호화가 필요하면 Insertable Streams로 SFU도 평문을 못 보게 한다.
- LiveKit·Jitsi·Google Meet이 채택. 매니지드 키 관리가 핵심.
- 비용은 시뮬캐스트 효율이 떨어지고, 서버 사이드 녹화·트랜스코드가 어려워진다는 것.
DRM
- WebRTC는 DRM과 잘 안 맞는다. DRM은 콘텐츠 보호가 목표인데 WebRTC는 실시간성이 목표.
- 라이브 송출 DRM이 필요하면 HLS + Widevine 같은 조합으로 가야 한다.
17장 · 케이스 스터디 — AI 음성 에이전트 한 개 풀스택
위 도구들이 한 데 모이면 어떻게 굴러가는가. 가장 보편적인 시나리오.
[사용자 브라우저]
|
| WebRTC 오디오 송수신
v
[LiveKit Server]
|
| LiveKit Agents Worker가 룸에 자동 합류
v
[Agents Worker (Python)]
|
+-- Deepgram STT(스트리밍)
+-- OpenAI gpt-4o-mini(LLM)
+-- ElevenLabs TTS(스트리밍)
+-- Silero VAD(턴 결정)
|
| TTS 오디오를 LiveKit 룸으로 송출
v
[사용자 브라우저 — 즉시 재생]
지연 분해(목표 700ms 미만)
- 사용자가 말 끝남 → VAD가 턴 결정: 100~200ms
- 마지막 STT 결과 확정: 50~100ms
- LLM 첫 토큰까지: 200~400ms
- 첫 TTS 오디오 청크까지: 100~200ms
- WebRTC 전송 지연: 50~150ms
합계: 500~1000ms. 사람이 "대화처럼 느끼는" 한계가 이 정도다.
OpenAI Realtime + WebRTC 직결 모드
위 그림에서 Deepgram·OpenAI·ElevenLabs가 한 모델로 합쳐진다. 지연 200~400ms.
[사용자 브라우저]
|
| WebRTC 오디오 직결
v
[OpenAI Realtime 엔드포인트]
|
| 모델이 오디오 입출력 자체를 처리
v
[사용자 브라우저 — 응답 오디오]
이 모드의 트레이드오프
- 장점: 지연 매우 낮음. 모델이 음성의 뉘앙스를 직접 봄(웃음·끼어들기).
- 단점: 가격 높음. 모델이 OpenAI 진영으로 고정. STT/TTS의 자유도 잃음.
대다수 프로덕션은 둘을 함께 굴린다. 빠른 대화는 Realtime, 도구 호출·맞춤 TTS는 일반 LLM + 별도 STT/TTS.
18장 · 흔한 안티 패턴
운영에서 자주 봤다.
- P2P 메시로 4인 이상을 굴리려 함 — 5명에서 무너진다. 처음부터 SFU로 가라.
- TURN 서버 없이 출시 — 회사 네트워크 뒤 사용자가 들어오는 순간 통화 실패율이 30% 찍힌다.
- 시뮬캐스트를 끄고 한 해상도만 송출 — 10명 룸에서 누군가 모바일 4G면 모두가 끊긴다.
getUserMedia권한을 한 번 받고 끝났다고 생각 — 권한은 페이지·세션 단위로 바뀐다. 매번 다시 확인.- WebSocket 시그널링 한 개로 SFU 자체를 굴리려 함 — 시그널링은 시그널링이고 미디어는 미디어다. 한 프로세스로 묶지 마라.
- WebRTC 통계 수집을 안 함 — 사용자 한 명이 "끊겨요" 신고하면 재현 못 한다.
getStats()1분당 1회 수집. - 녹화·트랜스코드를 SFU 같은 프로세스에 박음 — 인코딩 1개가 SFU 전체를 멈춘다. 별도 워커로 분리.
- AI 음성 에이전트에서 VAD를 약하게 잡음 — 사용자 말이 끝나기 전 모델이 끼어든다. 또는 끝났는데 모델이 안 답한다.
- WHIP·RTMP·SRT 중에서 RTMP만 받는다 — 2026년에 AV1·VP9 송출은 RTMP로 못 한다. WHIP를 옵션으로 넣어라.
- 자가 호스트인데 모니터링이 PromQL 메트릭 5개로 끝 — 미디어 서버의 관측성은 일반 웹 서버보다 한 단계 더 깊다.
19장 · 큰 그림 — 무엇이 표준이 됐는가
2026년 5월 기준 정리.
- LiveKit이 AI 음성 에이전트 인프라의 표준 — Agents 프레임워크·OpenAI 채택·OSS+클라우드 양 갈래.
- Pion이 Go 진영의 WebRTC 엔진 — LiveKit·Galene·OBS WHIP 모두 Pion 위.
- WHIP/WHEP가 RTMP의 자리를 빠르게 가져가는 중 — OBS 30+이 기본 지원.
- OpenAI Realtime이 WebRTC 직결 모드 추가 — 음성 에이전트 지연이 사람 대화 수준.
- Cloudflare Realtime이 엣지 SFU라는 새 카테고리 — 글로벌 분산이 일급.
- 매니지드 진영은 여전히 강함 — Daily·100ms·AWS Chime SDK. 다만 가격 압박.
- Twilio Video는 사실상 사라짐 — 신규 가입 중단. EOL 진행 중.
- mediasoup·Janus·Jitsi는 자가 호스트 진영의 세 갈래로 굳어짐.
결정 체크리스트
- AI 음성 에이전트가 핵심인가? — LiveKit + LiveKit Agents.
- 회사 내부 미팅 솔루션이 필요한가? — Jitsi 자가 호스트.
- 라이브 스트리밍 송출이 핵심인가? — WHIP + LiveKit Ingress 또는 Cloudflare Realtime.
- 글로벌 분산 엣지가 우선인가? — Cloudflare Realtime 또는 LiveKit Cloud.
- 매니지드의 일급 분석이 필요한가? — Daily.
- 인도·동남아 가격 경쟁력이 필요한가? — 100ms.
- AWS 깊은 통합이 필요한가? — AWS Chime SDK.
- Go로 짠 작은 SFU 한 조각을 깊게 만져야 하나? — Pion 직접.
- Node.js로 시그널링·라우팅을 직접 통제하려면? — mediasoup.
- 매우 안정적이고 오래된 C 데몬을 원하나? — Janus.
안티 패턴 요약
- P2P 메시로 4인 이상.
- TURN 없이 출시.
- 시뮬캐스트 끔.
- WebRTC
getStats()미수집. - 한 프로세스에서 시그널링·SFU·녹화·트랜스코드.
- AI 에이전트에서 VAD 약함.
- RTMP만 받음(WHIP 미지원).
- 큰 룸에 MCU 강제.
- 매니지드와 자가 호스트 결정 없이 둘을 섞음.
- E2EE를 켰는데 서버 사이드 녹화를 기대.
다음 글 예고
다음 글 후보: LiveKit Agents 깊게 — 토큰 단위 스트리밍·도구 호출·인터럽션 처리, WHIP/WHEP 인제스트 한 달 운영기 — OBS·Cloudflare·LiveKit 비교, WebRTC getStats() 100개 메트릭 — 무엇을 보고 무엇을 무시할까.
"WebRTC는 표준이 아니라 표준들의 묶음이다. 묶음을 운영할 줄 아는 팀만큼 멀리 간다."
— WebRTC 미디어 인프라 2026, 끝.
참고 / References
- LiveKit 공식
- LiveKit GitHub — livekit/livekit
- LiveKit Agents 프레임워크 문서
- LiveKit Agents GitHub — livekit/agents
- LiveKit Cloud 가격
- Pion 공식
- Pion WebRTC GitHub
- Daily.co 공식
- 100ms 공식
- mediasoup 공식
- Janus Gateway 공식
- Jitsi Meet 공식
- Twilio Video 문서
- AWS Chime SDK 문서
- Cloudflare Realtime 공식
- Cloudflare Calls 발표
- WHIP IETF 표준 RFC 9725
- WHEP IETF 드래프트
- OBS Studio — WHIP 송출 지원
- OpenAI Realtime API 문서
- OpenAI Realtime + WebRTC 가이드
- Deepgram Nova 모델
- ElevenLabs TTS 문서
- Cartesia TTS
- Silero VAD GitHub
- coturn GitHub — TURN 서버 OSS 표준
- WebRTC
getStats()MDN - Insertable Streams MDN
- Opus 코덱
- AV1 코덱
- Galene SFU GitHub
- ion-sfu GitHub
- webrtc-rs GitHub