본문 바로가기

개발/JavaScript 30

23. Speech Synthesis

반응형

기본 코드

<!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>
  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');
</script>

</body>
</html>

목표

적어놓은 멘트를 지정된 웹 API를 이용하여 여러가지 나라의 언어로 바꾸어 들을 수 있도록 해보자.

코드 분석

  msg.text = document.querySelector('[name="text"]').value;

  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('');
  }

msg text값은 텍스트 값으로 연결해준 다음
그 아래의 내용은 voiceDropdown의 내용을 지정해주는 것인데 voices에 연결이 된 .getVoices()부터 보면 이것은 웹 API인데 사용 가능한 모든 음성을 나타내는 개체를 SpeechSynthesis목록을 반환해 주는 것이다.
따라서 voices에서 먼저 'en'이 있는 것만 골라낸 다음 .map을 사용하여 배열을 새로 만들고, 이 내용들을 .join으로 연결한다.

  function setVoice() {
    msg.voice = voices.find(voice =>  voice.name === this.value);
    toggle();
  }
  function toggle(startOver = true) {
    speechSynthesis.cancel();
    if(startOver) {
    speechSynthesis.speak(msg);
    }
  }
  function setOption() {
    console.log(this.name, this.value);
    msg[this.name] = this.value;
    toggle(); 
  }

.find는 배열에서 원하는 값을 하나 리턴해주는 것인데 리턴한 값을 msg.voice에 넣어준 다음 toggle에 따라 언어를 바꾸면 실행을 그만둔 다음 바로 바뀐 언어로 다시 음성이 나오도록 한다.
그리고 setOption msg의 이름에 값을 넣어주고 토글함수를 사용하는 것이다.

  speechSynthesis.addEventListener('voiceschanged', populateVoices);
  voicesDropdown.addEventListener('change', setVoice);
  options.forEach(option => option.addEventListener('change', setOption));
  speakButton.addEventListener('click', toggle);
  stopButton.addEventListener('click', () => toggle(false));

정리를 해보면, 목소리가 바뀌면 populateVoices를 적용, 목소리의 값(국가)를 바꾸어 주면 setVoice를 적용, 값이 바뀌면 각각에 setOption을 적용한다.
이렇게 적용해놓으면 값을 변화시켜줄 때 목소리도 변해서 나오고 가지고있는 원소에서의 값도 그에 맞춰지게 되는 것이다.

마무리

음성송출에 대한 웹 API가 있다는 걸 알게된게 가장 신기했다.
내용은 크게 어렵지 않았음
끝.

반응형

'개발 > JavaScript 30' 카테고리의 다른 글

25. Event Capture, Propagation, Bubbling and Once  (0) 2017.04.26
24. Sticky Nav  (0) 2017.04.26
22. Follow Along Link Highlighter  (0) 2017.04.26
21. Geolocation  (0) 2017.04.26
20. Speech Detection  (0) 2017.04.24