Dev/JavaScript30

23. Speech Synthesis ( JavaScript30 )

takeU 2021. 7. 10. 21:53
반응형

Speech Synthsis

목표

자바스크립트 SpeechSynthesisUtterance API로 글을 읽어주는 도구 구현

 

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Speech Synthesis</title>
  <link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet' type='text/css'>
  <link rel="stylesheet" href="style.css">
</head>
<body>

    <div class="voiceinator">

      <h1>The Voiceinator 5000</h1>

      <select name="voice" id="voices">
        <option value="">Select A Voice</option>
      </select>

      <label for="rate">Rate:</label>
      <input name="rate" type="range" min="0" max="3" value="1" step="0.1">

      <label for="pitch">Pitch:</label>

      <input name="pitch" type="range" min="0" max="2" step="0.1">
      <textarea name="text">Hello! I love JavaScript 👍</textarea>
      <button id="stop">Stop!</button>
      <button id="speak">Speak</button>
    </div>
<script>
</script>
</body>
</html>

 

과정

  1. 사용 가능한 목소리 리스트 출력
  2. 재생, 정지 버튼 생성
  3. 목소리 설정
  4. 옵션 설정

 

코드 분석

0. 기능을 구현하기 위한 변수, 상수 설정

const msg = new SpeechSynthesisUtterance();
let voices = [];

const voicesDropdown = document.querySelector('[name="voice"]');
const options = document.querySelectorAll('[type="range"], [name="text"]');
const speakButton = document.querySelector('#speak');
const stopButton = document.querySelector('#stop');
msg.text = document.querySelector('[name="text"]).value;

1. 사용 가능한 목소리 리스트 출력

const populateVoices = e => {
 voices = e.target.getVoices();
 voicesDropdown.innerHTML = voices
     .filter(voice => voice.lang.includes('en'))
     .map(voice => `<option value="${voice.name}">${voice.name} (${voice.lang})</option>`)
     .join('');
}
speechSynthesis.addEventListener('voiceschanged', populateVoices);

voices에 사용 가능한 모든 목소리들을 담고, en즉, 영어를 지원하는 목소리들만 option으로 걸러내 HTML에 출력하는 함수 populateVoices에 담음
getVoices가 변경되면 populateVoices를 실행

2. 재생, 정지 버튼 생성

const toggle = (startOver =true) => {
 speechSynthesis.cancel();
 if(startOver) {
     speechSynthesis.speak(msg);
 }
}
speakButton.addEventListener('click', toggle);
stopButton.addEventListener('click', () => toggle(false));

toggle함수로 메세지를 읽을 수 있도록 함. 이때 이미 speechSynthesis가 실행, 즉 음성이 재생중이면 종료하고 재시작함.
speak 버튼으로 실행, stop 버튼으로 정지함.

3. 목소리 설정

const setVoice = e => {
 msg.voice = voices.find(voice => voice.name === e.target.value);
 toggle();
}
voicesDropdown.addEventListener('change', setVoice)

setVoice에 메세지의 목소리를 선택한 이름에 따라서 선택할 수 있도록 함수 생성.
목소리 선택 후에 자동으로 toggle() 함수 실행으로 글을 읽을 수 있도록 함

4. 옵션 설정

const setOption = e => {
  msg[e.target.name] = e.target.value;
    toggle();
}
options.forEach(option => option.addEventListener('change', setOption));

options 레인지바에서 값을 조정하면 바뀐 값으로 글을 한번 읽어줌