gpt-realtime WebRTC 정적/버징 노이즈 — 6/12 발생 원인 분석 분석

마지막 업데이트 2026-07-22

작성일: 2026-06-14 상태: 🟡 원인 규명 — 프로젝트 코드 배제 · OpenAI측 회귀 1순위 관련 영역: OpenAI Realtime · WebRTC · 아동(guest) AI 오디오 재생

증상 VOC / 인시던트

2026-06-12 발생: 핑퐁이(AI) 발화 오디오에 간헐적으로 매우 큰 정적/크래클 노이즈가 섞임. "심한 마이크 클리핑, 전기 잡음, 손상된 오디오 프레임"에 가까운 소리.
지표
영향 범위라이브 수업의 약 50%
빈도20분 세션당 약 2회
모델 / 전송gpt-realtime v1.0 (gpt-realtime-2025-08-28) · WebRTC
발생 양상사전 징후 없이 6/12 갑자기 시작. OpenAI 배포 공지 없음
동일 증상이 OpenAI 개발자 포럼에 여러 팀에 의해 독립적으로 보고됨 (본 인시던트도 그중 하나 — #1383484). 본 문서는 "6/12 발생이 OpenAI측인지, 이 프로젝트 변경 때문인지"를 가린다.

배포 타임라인 — 무엇이 언제 운영에 올랐나

릴리즈 / 커밋날짜운영 배포오디오 관련 변경
ppi-web@1.83.0 / 1.83.16/106/10없음 (정적 발생 직전 기준선)
ppi-web@1.84.06/116/11, 6/12PPI-1006 #695 오디오 분석/MFCC (호스트측 마이크 녹음)
ppi-web@1.84.16/126/12 14:17"말하기 멈춤" 단축키만 — 오디오 품질 무관
ppi-web@1.84.3 (#709 RMS 포함)6/146/14 06:53PPI-1000 #709 아바타 RMS 립싱크 (AI 출력 Web Audio 탭)
핵심 사실: 6/12 정적 발생 시점의 운영본은 1.84.0 / 1.84.1. RMS 립싱크(#709)는 오늘 6/14에야 운영 배포됨 → 6/12 정적의 원인이 될 수 없다.

용의자 검토 — 프로젝트 코드 배제

① PPI-1000 #709 — 아바타 RMS 립싱크 배제 (미배포)

OpenAI 출력 스트림을 공유 AudioContext의 createMediaStreamSource로 탭하는 변경이라, 재생 중 원격 스트림을 Web Audio로 끌어들여 정적을 유발할 수 있는 구조는 맞다. 그러나 6/12엔 미배포 (git tag --contains 결과 최초 포함 릴리즈 = 1.84.3, 6/14 운영).

처음 이 변경을 1순위로 의심했으나 배포 타임라인으로 반증됨. 6/12 인시던트에 한해 무죄. (단 → 아래 "앞으로의 변수" 참고)

② PPI-1006 #695 — 오디오 분석 / MFCC 배제 (경로 불일치)

6/12 운영본(1.84.0)에 새로 들어간 유일한 오디오 관련 코드. use-guest-audio-capture.ts 신규 추가. 추적 결과:

항목실제 동작
방식MediaRecorder 녹음만 — Web Audio 탭/AudioContext/createMediaStreamSource 전혀 없음
녹음 대상아동의 마이크 스트림 (guestStream.audioStream) — AI 출력(aiAudioStream)과 별개의 MediaStream 객체
실행 위치host.tsx / session-card.tsx / monitor-dashboard = 치료사·모니터 측. 아동(client-guest) 재생 경로 아님
게이팅분석 에이전트가 DB에 존재 + localStorage 활성일 때만 분석 동작 (getActiveAgentId())
MediaRecorder는 소스 스트림을 수동 소비(녹음)만 하고 변형하지 않는다. 게다가 대상이 아동 마이크(호스트측)이지 아동이 듣는 AI 출력이 아니다. → 아동측 AI 정적과 경로가 다름.
// use-guest-audio-capture.ts:38-51 — 녹음 대상은 마이크/원격 스트림, MediaRecorder만
const rawStream = propStream ?? (remoteVideoRef?.current?.srcObject as MediaStream);
const audioStream = new MediaStream(rawStream.getAudioTracks());
const recorder = new MediaRecorder(audioStream, options);  // Web Audio 아님

③ 그 외 1.84.0/1.84.1 커밋 무관

회기 보고서(#708), 회차 종료 모달(#710), 임시개방 UI(#705), ffprobe 로그(#706), 말하기 멈춤 단축키 — 모두 아동 AI 오디오 재생 경로와 무관.

결론: 6/12 운영본에는 아동이 듣는 AI 오디오 재생 경로를 변경한 프로젝트 코드가 없다. 유일한 오디오 변경(#695)은 호스트측 마이크 녹음으로 경로가 다르다.

결론 — 가능성 순위

순위가설근거
1 OpenAI 서버측 gpt-realtime WebRTC 회귀 6/12 운영본에 아동 AI 재생 경로 변경 없음 / 같은 시기 타 팀들도 독립 보고(#1357298, #1360975, #1363490) / 증상 패턴(간헐·50%·세션당 2회)이 클라이언트 결정적 버그보다 서버측 산발 손상에 부합
2 #695 호스트측 MediaRecorder 확률 낮음. 영향 받아도 호스트/모니터의 녹음·재생이지 아동이 듣는 AI 오디오가 아님
3 TURN/ICE 설정(PPI-1007 #682, 6/4) + 망/릴레이 저하 6/4 변경이라 6/12 발생과 직접 인과는 약함. 인프라 상호작용 가능성만

한 가지로 갈리는 판별 질문 — "정적을 누가 들었나?"

아동(게스트)은 OpenAI에서 직접 오디오를 받고, 호스트는 게스트가 원시 트랙 그대로 릴레이한 것을 받는다 (use-guest-session-relay.ts — 재인코딩 없음). 따라서:

누가 들었나가리키는 원인
아동(게스트) — OpenAI 직접 수신OpenAI측 거의 확정 (#695는 아동 경로 무관)
호스트/모니터만 — 릴레이/녹음 경로#695 재검토 가치 있음
둘 다 동시에OpenAI측 패킷 손상 (릴레이가 원시 트랙 전달 → 같이 깨짐)

⚠️ 앞으로의 변수 — RMS(#709)가 6/14 운영 진입

6/12 원인은 아니지만, RMS 립싱크(#709)가 오늘 6/14 운영에 배포됨. 이 변경은 OpenAI 출력 스트림을 공유 AudioContext로 탭한다(use-avatar-rms.ts:110 createMediaStreamSource(audioStream)). 라이브 WebRTC 원격 스트림을 <audio> 재생 + 별도 AudioContext(시스템 48kHz)에 동시에 물리는 것은 Chromium에서 글리치/왜곡 유발로 알려진 패턴.
6/14 이후 정적은 OpenAI측 + RMS 두 요인이 겹칠 수 있으므로 6/12 건과 분리해서 봐야 한다. RMS는 아바타별 rmsLipSyncEnabled 플래그(/main/avatars)로 OFF 가능 — 코드/재배포 없이 DB 토글, 새 수업부터 적용. 전역 OFF 스위치는 없음(아바타별만).

검증 · 후속 권장

OpenAI 포럼 출처

관련 문서