Day 20 - Speech Detection

이번 과제는 Day 19의 웹캠 사용에 이어 연속으로 신기했는데, 바로 음성 인식이다.

사용해보니 유튜브 자동 자막처럼 완벽에 가까운 음성 인식은 아니지만 그래도 또박또박 말하면 90% 정도는 알아먹는 것 같다. 이 모듈은 로컬에서 npm 없이 테스트하면 계속 마이크 권한 창이 떠서 사용이 힘들고 Wesbos의 말대로 패키지 설치 후 npm start로 테스트해야 한다.

window.SpeechRecognition

음성인식 객체는 Window DOM의 최상단에 위치한다고 한다. 선언해서 사용하는 방법은 매우 간단하다.

먼저 선언하고, 변수에 음성인식 객체를 할당한다.

1
2
3
4
window.SpeechRecognition =
window.SpeechRecognition || window.webkitSpeechRecognition;

const recognition = new SpeechRecognition();

그리고 대화가 끝날때까지 한 문장으로 입력받는 속성을 설정하고, 언어를 설정한다. 언어는 한국어 ko-KR을 지원하는 것을 봐서 거의 모든 언어를 지원하는 것 같다. (영어는 en-US)

1
2
recognition.interimResults = true;
recognition.lang = "ko-KR"; //en-US

이제 음성인식된 스크립트를 p 객체를 appendChild()하여 div 객체에 넣어주면 된다.

1
2
3
let p = document.createElement("p");
const words = document.querySelector(".words");
words.appendChild(p);

p 객체를 먼저 만들어주고 textContent를 음성인식 스크립트로 넣어주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
recognition.addEventListener("result", (e) => {
const transcript = [...e.results]
.map((result) => result[0])
.map((result) => result.transcript)
.join("");

p.textContent = transcript;

if (e.results[0].isFinal) {
p = document.createElement("p");
words.appendChild(p);
}
});

isFinal을 검사하는 이유는 문장이 끝나면 새로운 p 객체를 만들어주어야 계속 p를 추가할 수 있기 때문이다.

이제 음성 인식을 실행해보자.

1
recognition.start();

그런데 위에서 짠 코드까지만 넣으면 한 문장만 입력되고 더 이상 입력되지 않는데, 음성인식이 종료되기 때문에 recognitionend 이벤트를 걸어주고, 음성인식이 종료되면 다시 recognition.start를 실행하면 된다.

1
recognition.addEventListener("end", recognition.start);

Full Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
window.SpeechRecognition =
window.SpeechRecognition || window.webkitSpeechRecognition;

const recognition = new SpeechRecognition();
recognition.interimResults = true;
recognition.lang = "ko-KR"; //en-US

let p = document.createElement("p");
const words = document.querySelector(".words");
words.appendChild(p);

recognition.addEventListener("result", (e) => {
const transcript = [...e.results]
.map((result) => result[0])
.map((result) => result.transcript)
.join("");

p.textContent = transcript;

if (e.results[0].isFinal) {
p = document.createElement("p");
words.appendChild(p);
}
});
recognition.addEventListener("end", recognition.start);

recognition.start();

활용

음성 인식을 활용해서 특정 단어가 포함되었을 때 로직을 추가할 수도 있다. 나는 날씨라는 말이 포함되었을 때 구글 날씨를 띄워봤는데, 작동해보니 매우 잘된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
recognition.addEventListener("result", (e) => {
const transcript = [...e.results]
.map((result) => result[0])
.map((result) => result.transcript)
.join("");

// 날씨 추가한 부분
if (transcript.includes("날씨")) {
window.open(
"https://www.google.com/search?q=%EB%82%A0%EC%94%A8&oq=%EB%82%A0%EC%94%A8&aqs=chrome..69i57j35i39l2j0j69i61j69i65j69i61l2.1234j0j7&sourceid=chrome&ie=UTF-8"
);
}

p.textContent = transcript;

if (e.results[0].isFinal) {
p = document.createElement("p");
words.appendChild(p);
}
});