Day 23 - Speech Synthesis

지난 Day 20의 주제가 STT(Speech To Text)였다면, 이번 과제의 주제는 **TTS(Text To Speech)**이다. 자바스크립트 자체에서 STT를 지원하듯이 TTS도 브라우저에 내장된 SpeechSynthesis를 사용하면 된다. 사용법은 간단하다.

먼저 TTS의 정보가 들어간 객체인 msg 를 선언한다.

1
const msg = new SpeechSynthesisUtterance();

음성의 목록을 나타내는 populateVoices() 작성하기

1
2
3
4
5
6
7
8
9
10
function populateVoices() {
voices = this.getVoices();
voicesDropdown.innerHTML = voices
.filter((voice) => voice.lang.includes("en"))
.map(
(voice) =>
`<option value="${voice.name}">${voice.name} (${voice.lang})</option>`
)
.join("");
}

speechSynthesis 객체에서 voicechanged 이벤트가 일어났을 때 이 함수를 실행한다.

목소리를 설정하는 setVoice() 작성하기

1
2
3
4
function setVoice() {
msg.voice = voices.find((voice) => voice.name === this.value);
toggle();
}

음성 목록에 change 이벤트를 목소리를 설정하는 이 함수로 걸어준다. TTS 정보를 관리하는 msg 객체의 voice 값을 바꿔준 후 직접 작성한 toggle() 함수로 목소리를 다시 재생한다.

음성을 재생하는 toggle() 작성하기

1
2
3
4
5
6
function toggle(startOver = true) {
speechSynthesis.cancel();
if (startOver) {
speechSynthesis.speak(msg);
}
}

인자로 startOver를 넘기고, 기본 설정 인자인 true인 경우 이전 음성을 취소하고 새로운 음성을 재생하며, false를 인자로 주면 음성만 취소한다.

다른 설정을 바꿀 수 있는 setOption() 작성하기

1
2
3
4
5
function setOption() {
console.log(this.name, this.value);
msg[this.name] = this.value;
toggle();
}

이전 과제에서 많이 보던 옵션 변경 함수인데, input 객체의 name을 변경할 속성의 이름과 일치시키면 input 객체의 value로 별도로 옵션을 구별하여 작성할 필요없이 한번에 사용할 수 있다.

이제 이 함수들을 이벤트로 걸어준다.

1
2
3
4
5
6
speechSynthesis.addEventListener("voiceschanged", populateVoices);
voicesDropdown.addEventListener("change", setVoice);
options.forEach((option) => option.addEventListener("change", setOption));
speakButton.addEventListener("click", toggle);
stopButton.addEventListener("click", () => toggle(false));
// same with toggle.bind(null, false);