Stream
WebSocket 기반 실시간 양방향 오디오 스트리밍 프로토콜. G.711 μ-law 오디오 사양, 메시지 형식, 사용 패턴.
개요
VoiceML의 <Connect><Stream> 동사를 사용하면 실시간 양방향 오디오 스트림을 WebSocket으로 연결할 수 있습니다.
AI 에이전트, 실시간 음성 분석, 보이스봇 등에 사용됩니다.
Stream 프로토콜은 현재 검증 전 상태입니다. 본 문서에 기술된 메시지 형식과 오디오 사양이 그대로 동작하는지 정식 검증이 완료되지 않았으며, 운영 적용 전에 자체 테스트가 필요합니다.
VoiceML 연결 예제
<Response>
<Connect>
<Stream url="wss://your-server.com/stream" track="inbound">
<Parameter name="userId" value="123"/>
</Stream>
</Connect>
</Response>현재 구현은 inbound 트랙(발신자 → ClawOps) 오디오만 전달합니다. outbound / both 등의 다른 값은
지원되지 않습니다. AI 응답 등 송신측 오디오는 별도 트랙으로 받지 않으며, 클라이언트가 보낸 오디오를
ClawOps 가 그대로 발신측에 재생합니다.
네트워크
Stream 연결은 ClawOps 플랫폼에서 고객의 WebSocket 서버로 발신됩니다. 방화벽 화이트리스트가 필요한 경우 아래 IP를 허용해 주세요.
| 항목 | 값 |
|---|---|
| Source IP | 34.47.65.45/32 |
| 리전 | GCP asia-northeast3 (서울) |
| 프로토콜 | WebSocket (TCP 443) |
고정 IP이며, 변경 시 사전 공지합니다.
인증 — Stream WebSocket 자체에는 X-Signature 등의 ClawOps 측 인증 서명이 적용되지 않습니다.
통화/계정 식별이 필요하면 VoiceML <Stream> 안의 <Parameter> 로 자체 토큰을 넘기거나,
start 메시지의 streamId / callId / accountId 와 미리 알고 있는 통화 정보를 대조해 검증하세요.
공개 엔드포인트는 위 Source IP 화이트리스트와 함께 사용하는 것을 권장합니다.
오디오 사양
오디오 포맷은 G.711 μ-law입니다. PCM16이 아닙니다. 인코딩/디코딩 시 반드시 μ-law 코덱을 사용하세요.
| 항목 | 값 |
|---|---|
| 인코딩 | G.711 μ-law |
| 샘플레이트 | 8000 Hz |
| 채널 | 1 (mono) |
| 프레임 크기 | 160 bytes (20ms) |
| 전송 형식 | base64 in JSON |
플랫폼 보장 사항
수신 오디오: Asterisk jitter buffer가 네트워크 jitter를 흡수하여 균일한 20ms 간격으로 전달합니다.
송신 오디오: 아무 타이밍으로 보내도 플랫폼이 20ms 간격으로 정규화하여 재생합니다.
SDK에서 pacing이나 jitter buffer를 구현할 필요가 없습니다.
3초간 무음이 지속되면 자동으로 페이싱이 중단됩니다.
서버 → 클라이언트 메시지
connected
WebSocket 연결 성공.
{
"event": "connected",
"protocol": "Call",
"version": "1.0.0"
}start
스트림 메타데이터. mediaFormat의 encoding이 audio/x-mulaw인 것을 확인하세요.
{
"event": "start",
"sequenceNumber": "1",
"start": {
"streamId": "MZ...",
"callId": "CA...",
"accountId": "AC...",
"tracks": ["inbound"],
"mediaFormat": {
"encoding": "audio/x-mulaw",
"sampleRate": 8000,
"channels": 1
},
"customParameters": { "userId": "123" }
}
}media
수신 오디오 (전화 → 클라이언트). 20ms 간격으로 전달됩니다.
{
"event": "media",
"sequenceNumber": "3",
"media": {
"track": "inbound",
"chunk": "1",
"timestamp": "5",
"payload": "<base64 G.711 μ-law>"
}
}mark
클라이언트가 보낸 mark의 재생 완료 알림. 해당 mark 이전의 모든 오디오가 재생 완료되었음을 의미합니다.
{
"event": "mark",
"sequenceNumber": "4",
"mark": { "name": "greeting_end" }
}dtmf
발신자가 통화 중 키패드를 누르면 전송됩니다. IVR/메뉴 선택, 본인 인증 코드 입력 등을 처리할 때 사용합니다.
{
"event": "dtmf",
"sequenceNumber": "5",
"dtmf": { "digit": "1", "track": "inbound_track" }
}| 필드 | 설명 |
|---|---|
digit | 입력된 키 (0-9, *, #) |
track | 입력 트랙 식별자 (inbound_track) |
stop
스트림 종료.
{
"event": "stop",
"sequenceNumber": "5",
"stop": { "accountId": "AC...", "callId": "CA..." }
}클라이언트 → 서버 메시지
media
송신 오디오 (클라이언트 → 전화). G.711 μ-law base64로 인코딩하여 전송합니다. 아무 타이밍으로 전송 가능 — 플랫폼이 20ms 간격으로 pacing 처리합니다.
{
"event": "media",
"media": { "payload": "<base64 G.711 μ-law>" }
}mark
오디오 재생 지점에 마커를 삽입합니다. media 전송 후 mark를 보내면, 해당 지점까지 오디오가 재생 완료될 때 서버가 동일한 mark를 돌려보냅니다.
{
"event": "mark",
"mark": { "name": "custom-identifier" }
}clear
송신 오디오 버퍼를 즉시 비웁니다 (barge-in). 대기 중인 mark가 있으면 모두 발화한 후 큐를 비웁니다.
{ "event": "clear" }dtmf
클라이언트가 발신자에게 DTMF 신호를 전송합니다. ARS 메뉴 탐색, 내선번호 입력 등 발신자 측 으로 키 톤을 보낼 때 사용합니다.
{
"event": "dtmf",
"dtmf": { "digit": "1" }
}| 필드 | 설명 |
|---|---|
digit | 보낼 키 (0-9, *, #) |
사용 패턴
기본 오디오 송수신
클라이언트 서버
| |
|<-- connected ----------------|
|<-- start --------------------|
|<-- media (수신 오디오) -------| (20ms 간격)
|--- media (송신 오디오) ------>| (아무 타이밍 OK)
|<-- media --------------------|
| ... |
|<-- stop ---------------------|Mark 기반 재생 추적
클라이언트 서버
| |
|--- media (TTS 청크 1) ------>|
|--- media (TTS 청크 2) ------>|
|--- mark("greeting") -------->| (greeting 끝 지점에 마커)
|--- media (TTS 청크 3) ------>|
|--- mark("question") -------->|
| ... |
|<-- mark("greeting") ---------| (greeting까지 재생 완료)
| ... |
|<-- mark("question") ---------| (question까지 재생 완료)Barge-in (clear)
클라이언트 서버
| |
|--- media (TTS 응답) -------->|
|--- media (TTS 응답) -------->|
|--- mark("response") -------->|
|--- media (TTS 응답) -------->|
| | (사용자가 말하기 시작)
|--- clear ------------------->| (버퍼 비움 요청)
|<-- mark("response") ---------| (대기 중이던 mark 발화)
| | (남은 TTS 오디오 즉시 중단)