Agora SDK는 Opus 패킷을 수신하여 내부에서 PCM으로 디코딩한다
·수정 2026.04.26·수정 1회
요약
- Agora SD-RTN에서 ECS/로컬로 들어오는 UDP 패킷은 Opus 인코딩 상태(평균 130B/pkt)이며, SDK 내부에서 PCM으로 디코딩하여 콜백에 전달한다
RTCConnConfig.audio_recv_encoded_frame=0이 이 동작을 결정하며, tcpdump 캡처로 네트워크 레벨에서 실증했다- VPC ingress ~23kbps/user 역산은 Opus 기준이 맞다
- kbps 는 killo bit per second
본문
배경
connecting-call-recording-service에서 코드의 audio_recv_encoded_frame=0 필드명을 보고 "SDK 내부에서 Opus→PCM 디코딩한다"고 추론했지만, 문서에서 정확한 동작을 확인하지 못해 네트워크 레벨에서 직접 검증했다.
검증 방법: tcpdump + test-web
sudo tcpdump -i en0 udp -c 1000 -w /tmp/agora_capture.pcap로 UDP 패킷 캡처test_web.py로 브라우저 마이크 → Agora 채널 → 서버 녹음 파이프라인 구동- 캡처된 패킷에서 Agora 서버(NAT64
64:ff9b::프리픽스) → 로컬 방향의 수신 패킷만 필터 - payload 크기 분포로 코덱 판별
수신 패킷 크기 분포 (Agora SD-RTN → SDK)
| 구간 | 패킷 수 | 비율 | 의미 |
|---|---|---|---|
| 0-50B | 63 | 16% | 시그널링/제어 |
| 51-200B | 301 | 76% | Opus 인코딩 오디오 |
| 201-500B | 21 | 5% | 번들된 Opus / 제어 |
| 501B+ | 12 | 3% | FEC / 핸드셰이크 |
평균 130B/packet. PCM이었다면 ~960B 이상이 대다수여야 하나, 1001B 이상은 0.7%뿐.
판별 기준
Opus 프레임 크기 (20ms 기준, VBR)
- 48kbps: 48000 × 0.02 / 8 = 120 bytes (payload)
- 24kbps: 24000 × 0.02 / 8 = 60 bytes (payload)
-
- RTP 헤더(12B) + Agora 프로토콜 헤더
PCM 프레임 크기 (코드에서 도출)
- 48000Hz × 2B × 1ch × 0.01s = 960 bytes (10ms)
- 48000Hz × 2B × 1ch × 0.02s = 1,920 bytes (20ms)
SDK 콜백 로그로 PCM 디코딩 확인
AudioFrame info for uid=2526: bytes_per_sample=2, samples_per_sec=48000,
channels=1, samples_per_channel=480, buffer_len=960
samples_per_channel=480 = 48000Hz × 0.01s → SDK가 10ms PCM 프레임으로 디코딩하여 전달.
결정하는 코드
# agora_base.py - RTCConnConfig
audio_recv_encoded_frame: int = 0 # 0=SDK가 디코딩, 1=인코딩된 채로 전달
# recording_service.py - 이 필드를 설정하지 않으므로 기본값 0 사용
self._conn_config = RTCConnConfig(
auto_subscribe_audio=1,
client_role_type=ClientRoleType.CLIENT_ROLE_BROADCASTER
)
agoraapi.log에서도 recvType:(audio: 0, video: 0)으로 확인.
확정된 파이프라인
모바일(Opus) → Agora SD-RTN → UDP(Opus, ~130B/pkt)
↓
SDK 내부 Opus→PCM 디코딩
(audio_recv_encoded_frame=0)
↓
PCM s16le, 48kHz, mono (960B/10ms frame)
↓
FFmpeg → AAC 48k → HLS (.ts) → S3
참고
Opus VBR은 오디오 복잡도에 따라 bitrate를 실시간으로 조절한다 Opus DTX(Discontinuous Transmission)은 무음 구간을 더 낮의 비트레이트로 인코딩해 대역폭을 절감한다.