이전에 참여했던 해커톤에서 사용자의 음성을 입력받아 실시간으로 화면에 텍스트화해 표기하는 STT 기능을 도입해야 했던 적이 있다.
다행히 react-speech-recognition 라이브러리를 발견해 짧은 시간내에 성공적으로 도입해냈었고, 무사히 프로젝트 완성을 마쳤다.
추후 생성형 ai 모델 여러 개를 프로젝트에 사용해보면서 해당 STT 기능 역시 ai 모델이 사용된 것임을 어렴풋이 유추할 수 있었는데, 실시간으로 STT를 지원하는 원리가 궁금해 해당 코드를 열어보기로 했다.
https://github.com/JamesBrill/react-speech-recognition
//react-speech-recognition/src/SpeechRecngition.js
import { useState, useEffect, useReducer, useCallback, useRef } from 'react'
import {
concatTranscripts,
commandToRegExp,
compareTwoStringsUsingDiceCoefficient,
browserSupportsPolyfills
} from './utils'
import { clearTranscript, appendTranscript } from './actions'
import { transcriptReducer } from './reducers'
import RecognitionManager from './RecognitionManager'
import isAndroid from './isAndroid'
import NativeSpeechRecognition from './NativeSpeechRecognition'
let _browserSupportsSpeechRecognition = !!NativeSpeechRecognition
let _browserSupportsContinuousListening = _browserSupportsSpeechRecognition && !isAndroid()
let recognitionManager
코드를 살펴보면 라이브러리 내외로 다양한 모듈들을 import 해오는 모습을 확인할 수 있다.
놀랐던 점은 해당 라이브러리 내에는 사용자의 음성을 처리하는 구현부가 없었다는 것이다. package.json
의 의존성 목록을 찾아봐도 babel 같은 컴파일러 외에는 추가로 설치하는 의존성이 없었기에 더 놀라웠다.
그렇다면 Web API에서 제공하는 기능을 사용하고 있다는 의미 아닌가?
// src/NativeSpeechRecognition.js
const NativeSpeechRecognition = typeof window !== 'undefined' && (
window.SpeechRecognition ||
window.webkitSpeechRecognition ||
window.mozSpeechRecognition ||
window.msSpeechRecognition ||
window.oSpeechRecognition
)
export const isNative = (SpeechRecognition) => SpeechRecognition === NativeSpeechRecognition
export default NativeSpeechRecognition
참조하는 NativeSpeechRecognition
을 살펴보니 window 객체의 브라우저 별 SpeechRecognition 객체를 사용하고 있음을 알 수 있었다.
SpeechRecognition은 Web Speech API에서 제공하는 인터페이스 중 하나다.
Web Speech API는 사용자의 음성 인식 및 합성을 브라우저에서 할 수 있도록 기능을 제공하는 JavaScript API이다.
이 API에서 제공하는 STT 기능 과정을 들여다보면,