-
todo-list 음성인식으로 리스트 추가하기(feat.react-speech-recognition)프로젝트/개인프로젝트 2024. 1. 24. 11:32728x90
전에 구현해봤던 todo-list에 음성인식 기능을 추가해서 키보드와, 음성인식을 통해 입력창에 입력할수있도록 구현해보기로했다.
useSpeechToText
import SpeechRecognition, { useSpeechRecognition, } from "react-speech-recognition"; const useSpeechToText = () => { const { transcript, listening, resetTranscript } = useSpeechRecognition(); const toggleListening = () => { if (listening) { SpeechRecognition.stopListening(); resetTranscript(); // 음성 인식을 중지할 때 transcript를 초기화 } else { SpeechRecognition.startListening({ language: "ko-KR", continuous: true }); } }; return { transcript, listening, toggleListening, resetTranscript }; }; export default useSpeechToText;
transcript : 음성인식을 통해 텍스트로 변환된 값
listening : 음성인식의 상태 음성인식중 or 음성인식중지
resetTranscript : 음성인식 텍스트값을 초기화시켜준다.
toggleListening :
- listening의 상태에 따라 listening중일때 toggle 함수가 발생했다면, 음성인식을 중지시키고, transcript값을 초기화시켜준다
- listening의 상태에 따라 listening중지상태일때 toggle함수가 발생했다면 음성인식을 시작해준다.
이때, 옵션으로는 한국어, continuous:true로 사용자가 말을 멈출 때 까지 음성인식을 할지말지 여부를 설정해준다.마지막으로 return에 결과값, 음성인식 상태값, toggle함수, 결과값초기화함수를 내보내준다.
Todo-List
import React, { useEffect, useState } from "react"; import List from "../components/list.js"; import Myheader from "../components/Myheader.js"; import MyButton from "../components/MyButton.js"; import { useNavigate } from "react-router-dom"; import useSpeechToText from "../functions/usespeechtotext.js"; function TodoList() { const { transcript, listening, toggleListening, resetTranscript } = useSpeechToText(); const [micOn, setMicOn] = useState(false); const [inputValue, setInputValue] = useState(""); const [list, setList] = useState([]); const navigate = useNavigate(); //추가 const handleAddClick = () => { const newList = [...list, { text: inputValue, checked: false }]; setList(newList); localStorage.setItem("list", JSON.stringify(newList)); setInputValue(""); console.log("inputvalue 는 :", inputValue); toggleListening(); // 음성인식 중지 resetTranscript(); //transcript 초기화 }; //삭제 const handleDeleteClick = (item) => { const newList = list.filter((i) => i !== item); setList(newList); localStorage.setItem("list", JSON.stringify(newList)); }; //todo list클릭시 스타일변화 const handleCheckClick = (item) => { const newList = list.map((i) => i === item ? { ...i, checked: !i.checked } : i ); setList(newList); localStorage.setItem("list", JSON.stringify(newList)); }; //마이크 클릭상태 const micClickHandler = () => { //마이크가 켜져있을때 : 음성인식종료 if (micOn) { toggleListening(); //마이크가 꺼져있을때 : 마이크상태를 on으로 바꾸고 음성인식시작 } else { setMicOn(true); toggleListening(); } }; useEffect(() => { //음성인식 종료되면 transcript값을 초기화하고 마이크상태변경 if (!listening) { resetTranscript(); setMicOn(false); } }, [listening, resetTranscript]); useEffect(() => { setInputValue(transcript); }, [transcript]); //로컬스토리지 //앱이 마운트 될 때 실행 useEffect(() => { const savedList = JSON.parse(localStorage.getItem("list")) || []; setList(savedList); }, []); const env = process.env; env.PUBLIC_URL = env.PUBLIC_URL || ""; return ( <div className="todolist"> <Myheader headText={"Todo-List"} leftChild={ <MyButton text={"뒤로가기"} onClick={() => { navigate(-1); }} /> } /> <h1>Talk To Me</h1> <div className="todo-input-wrapper"> <input className="todo-input" type="text" placeholder="내용을 입력하세요" value={inputValue} onChange={(e) => { setInputValue(e.target.value); }} ></input> <div className="button-wrapper"> <button onClick={() => { handleAddClick(); }} > <img className="add-image" src={process.env.PUBLIC_URL + `assets/add.png`} alt="addimage" /> </button> <button onClick={micClickHandler}> {listening ? ( <img className="mic-image" src={process.env.PUBLIC_URL + `assets/onmic.png`} alt="micimage" /> ) : ( <img className="mic-image" src={process.env.PUBLIC_URL + `assets/offmic.png`} alt="micimage" /> )} </button> </div> </div> <div className="todo-content"> {list.map((item, index) => ( <List item={item} key={index} handleDeleteClick={() => { handleDeleteClick(item); }} handleCheckClick={handleCheckClick} /> ))} </div> </div> ); } export default React.memo(TodoList);
1. useSpeechToText함수를 import해준다.
2. useSpeechToText에서 return해주었던,
const { transcript, listening, toggleListening, resetTranscript } =useSpeechToText();을 가져온다.
3. 음성인식을통해 가져온값을 add버튼을 클릭했을 때 handleAddClick함수가 실행되고,
새로운 값을 로컬스토리지에 저장 후 toggleListening()함수를 실행해 음성인식을 중지,
reSetTranscript()함수를 실행하여 transcript값을 초기화시켜준다.4. 또한 listening상태에따라, 마이크이미지 버튼이 달라지고, 마이크버튼을 클릭 했을 때
micClickHandler함수를 통해 micOn의 상태를 if문으로 확인하여
마이크가 켜져있을때와 꺼져있을때 toggleListening()함수를 통해 조절해준다.
5.useEffect를 통해 listening과 resetTranscript가 호출될때 !listening 즉 음성인식 중지상태라면
if문이 실행되어 resetTransript로 음성인식 결과값을 리셋해주고, setMicOn(false)로 변경시켜
사용자에눈에 마이크 이미지가 꺼지도록 해준다.
결과물
마이크가 작동 될 때는 url 우측에 마이크표시와 브라우저 타이틀 옆에 빨간원으로 표시되는것을 볼 수 있다.
이분의 블로그를 통해 구현할수있었다..!!
출처
React - Web Speech API
Web Speech API 문서 홈페이지 :https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API웹 페이지나 웹 앱에서 음성 데이터를 인식하고 합성하는 기능
velog.io
728x90'프로젝트 > 개인프로젝트' 카테고리의 다른 글
장바구니 기능 간단하게 해보기(feat. Redux) (0) 2023.12.14 리엑트 i18 라이브러리를 이용한 다국어기능 찍먹해보기. (0) 2023.12.10 Todo_List(feat. React) (1) 2023.12.06 Todo_List 만들기. (4) 2023.12.05