3주 동안 조원이 여러 음성 인식에 대한 인공지능 모델을 찾아보고, 적용을 하던 와중에.. 이미 브라우저에서 음성인식을 지원하는 것을 발견하게 되었습니다. 심지어 성능과 속도가 너무 좋아서 조원이 해온 결과물들이 쓸모가 없어져서 아쉽지만 SpeechRecognition을 사용하게 되었습니다.
Web Speech API
웹 앱으로 음성 데이터를 핸들링 할수 있게 한다고 합니다. 이 API 안에는 2개의 구성이 있습니다.
- SpeechRecognition - 음성인식
- SpeechSynthesis - 음성합성(발화)
Instance properties
- SpeechRecognition.lang: 언어 선택 ("ko-KR")
- SpeechRecognition.continuous: 단일 / 연속 결과 선택 (false)
- SpeechRecognition.interimResults: 중간 결과 반환 유무 (false)
- SpeechRecognition.maxAlternatives: 결과 당 최대 SpeechRecognitionAlternatives 수 (1) 숫자가 클수록 문장의 적합도에 맞게 반환
Instance methods
- SpeechRecognition.abort(): 음성인식 강제 종료. SpeechRecognitionResult 반환 x
- SpeechRecognition.start(): 음성인식 시작
- SpeechRecognition.stop(): 음성인식 종료. SpeechRecognitionResult 반환
Events
addEventListener()를 사용하거나 이 인터페이스의 oneventname 속성에 이벤트 리스너를 할당하여 이벤트를 듣습니다.
- audiostart, audioend, end, error, nomatch, result, soundstart, soundend, speechstart, speechend, start
구현 코드
export default async function speechRecogFn(
updateCallback: (text: string | null) => void
) {
const SpeechRecognition =
window.SpeechRecognition || window.webkitSpeechRecognition;
if (!("webkitSpeechRecognition" in window)) {
alert("음성인식을 지원하지 않는 브라우저 입니다!");
updateCallback(null);
} else {
const recognition = new SpeechRecognition();
recognition.interimResults = false; // true: 연속적 음절 인식 / false: 연속적 음절 인식 x
recognition.lang = "ko-KR"; // 값이 없으면 HTML의 <html lang="en">을 참고합니다. ko-KR, en-US
recognition.continuous = false; // true: 연속 결과 반환 / false: 단일 결과 반환
recognition.maxAlternatives = 20000; // maxAlternatives가 숫자가 작을수록 발음대로 적고, 크면 문장의 적합도에 따라 알맞은 단어로 대체
// 말이 멈췄을 때
recognition.onspeechend = () => {
recognition.stop(); // 음성인식 종료
};
// 음성 인식 서비스 결과 반환
recognition.onresult = (e: SpeechRecognitionEvent) => {
const text = Array.from(e.results)
.map((result) => result[0].transcript)
.join("")
.replaceAll(" ", "");
updateCallback(wordToCommand(text));
};
// 음성인식 시작
recognition.start();
}
}
export function wordToCommand(text: string) {
const speechWord = text.replace(" ", "");
// 다음, 한번더, 종료가 포함되어 있으면 해당 키워드를 반환
if (speechWord.includes("다음")) {
return "다음";
} else if (speechWord.includes("한번더")) {
return "한번더";
} else if (speechWord.includes("종료")) {
return "종료";
} else if (speechWord.includes("완료")) {
return "완료";
} else {
return speechWord;
}
}
function updateCallback(text: string | null) {
if (text === null) {
setIsMicrophone(false);
return;
}
// 음성 인식 결과 출력
setTranscript(text);
setIsListening(false);
// 명령어 처리
if (text === "완료" && playIndex === selectedSections.length - 1)
handleMoveNextStep();
if (text === "다음" && playIndex < selectedSections.length - 1)
handleMoveNextSection();
if (text === "한번더") dispatch(practiceActions.showSectionPlay());
if (text === "종료") router.replace("/");
return;
}
위 코드를 설명드리면 updateCallback 함수를 따로 만들어서 SpeechRecogFn에 인자로 넣어주었습니다. 이렇게 함수로 인자를 넣어주면 함수 내부 로직이 간단하게 바뀌기 때문에 updateCallback으로 함수명을 정했습니다.
참고
https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API
https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition
'Experience > - KT AIVLE School' 카테고리의 다른 글
KT AIVLE School 빅프로젝트 - event loop, call stack, callback queue 학습 (0) | 2023.07.25 |
---|---|
KT AIVLE School 빅프로젝트 - 텍스트 입력 Debounce 처리 (0) | 2023.07.20 |
KT AIVLE School 빅프로젝트 - shadcn/ui 사용 후기 (0) | 2023.07.20 |
KT AIVLE School 빅프로젝트 - 웹캠 녹화 구현 (0) | 2023.07.19 |
KT AIVLE School 빅프로젝트 - 웹캠 영상 녹화 시 에러 경험 (0) | 2023.07.19 |
KT AIVLE School 빅프로젝트 - 프론트에서 S3의 GET요청을 대기하는 로직 (0) | 2023.07.19 |
댓글