STT 폴백 (Web Speech API) — 코드레벨 동작 흐름 P2코드레벨

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

STT 폴백 (Web Speech API) — 코드레벨 동작 흐름 P2 코…: 입력: 개요 · 범위, 주요 처리 단계: 결과 처리 setupSpeechRecognition onresult L95, 결과: 파일 · 라인 레퍼런스 흐름
동작 흐름 요약
  1. 입력: 개요 · 범위
  2. 주요 처리 단계: 결과 처리 setupSpeechRecognition onresult L95
  3. 결과: 파일 · 라인 레퍼런스
문서 읽는 법 · 설명식

이 문서는 이렇게 읽으면 됩니다

STT 폴백 (Web Speech API) — 코드레벨 동작 흐름의 핵심을 설명식으로 먼저 안내합니다. 기술적 결론과 원문 근거는 아래 본문에 보존되어 있습니다.

핵심 흐름 펼쳐 보기
  1. 비유와 핵심 질문으로 먼저 전체 구조를 잡습니다.
  2. 실제 컴포넌트·파일·데이터 흐름을 따라 내려갑니다.
  3. 코드 라인과 주의사항에서 구현 근거를 확인합니다.
  • 개요 · 범위
  • SpeechRecognition 설정 initializeSpeechRecognition L36
  • 결과 처리 setupSpeechRecognition onresult L95
작성일: 2026-06-14 대상: 개발자 — 브라우저 네이티브 폴백 전사 파악 핵심 파일: hooks/use-stt-fallback.ts

개요 · 범위

3계층 STT 중 최후 폴백. OpenAI Realtime 내장 전사·External STT(#4/#9)가 결과를 못 줄 때 브라우저 네이티브 Web Speech API(SpeechRecognition, ko-KR)로 아동 발화를 텍스트화해 핑퐁이에 입력한다.

세션 매니저(#1)가 구동: fallbackTranscriptionEnabled일 때 활성. 전사 결과는 onTranscriptionsendMessage(transcript)로 텍스트 입력 전송. 데이터채널 이벤트(speech_started/output_audio_buffer)에 맞춰 start/stop이 토글된다.

SpeechRecognition 설정 initializeSpeechRecognition L36

recognition.continuous = true;
recognition.interimResults = true;   // 중간 결과로 빠른 처리
recognition.lang = "ko-KR";
recognition.maxAlternatives = 3;       // 다중 후보 중 최고 confidence 선택
// 가능 시 Google Speech API serviceURI 선호

미지원 브라우저(webkitSpeechRecognition/SpeechRecognition 둘 다 없음)면 null 반환 → 폴백 비활성.

결과 처리 setupSpeechRecognition onresult L95

  • final 결과: 최대 3개 alternative 중 최고 confidence 선택 → handleFallbackTranscription.
  • interim 결과: 최신 interim을 보관하고 1500ms 타임아웃 설정 → 그 안에 final이 안 오면 best interim을 결과로 사용(빠른 응답성 ↔ 정확성 타협).
  • final 도착 시 pending interim 타임아웃 취소.

전사 게이트 (에코 방지) handleFallbackTranscription L65

아래 조건을 모두 통과해야만 전사를 내보낸다:

audioInputEnabled && sessionActive && enabled
  && !isUserTalking && !isPeerTalking
  && recognitionId === currentRecognitionId
  • !isPeerTalking: 핑퐁이 발화 중에는 막아 AI 음성이 마이크로 들어가 전사되는 에코를 차단. 세션 매니저가 output_audio_buffer 이벤트에 맞춰 start/stop도 한다(#1).
  • recognitionId 매칭: start마다 id 증가. stop 시 0으로 무효화 → 옛 인식 인스턴스의 stale 타임아웃/결과가 새 세션에 끼어드는 것 방지.

생명주기 · 에러 start/stop/onend/onerror

  • start: enabled+audioInputEnabled일 때만. 새 recognitionId 발급 → 인스턴스 생성·setup·start.
  • onend 자동 재시작: continuous가 끊기면(브라우저가 주기적으로 종료) session/enabled/audioInput 활성 시 100ms 후 재시작.
  • stop: recognition.stop + id=0 무효화 + interim 타임아웃 정리.
  • onerror: no-speech/audio-capture/network는 일시 오류(무시), not-allowed/service-not-allowed는 권한 거부 로깅, aborted는 의도적 정지(재시작 안 함), 그 외 unknown은 안전상 폴백 비활성.

함정 · 주의

  • 폴백은 보조: 정확도·언어 지원이 External STT/OpenAI보다 낮다. 주 경로가 동작하면 쓰지 않는다.
  • recognitionId 무효화 필수: stop 시 id=0으로 안 바꾸면 옛 interim 타임아웃 결과가 새 발화에 섞임.
  • isPeerTalking 게이트: 빠지면 AI 음성이 폴백으로 다시 전사되는 에코 루프. 세션 매니저의 start/stop 토글과 이중 방어.
  • 브라우저 의존: Web Speech API 미지원(일부 인앱 브라우저)이면 폴백 자체가 없음 → 주 경로 장애 시 무전사.
  • onend 재시작 루프: 조건(session/enabled/audioInput)이 잘못 유지되면 stop 후에도 재시작될 수 있음 → updateEnabled(false)가 stop을 호출하는 구조에 의존.

파일 · 라인 레퍼런스

파일/심볼역할
use-stt-fallback.tsWeb Speech API 래퍼
initializeSpeechRecognition (L36)설정·미지원 가드
setupSpeechRecognition (L91) / handleFallbackTranscription (L65)결과 처리·게이트
use-session-manager.ts (sttFallback)구동·start/stop 토글