SpeechSynthesis는 주어진 텍스트를 소리로 바꿔주는 Web Speech API
이다.
우선, 텍스트를 말하기 위해서 보이스가 필요한데 window.speechSynthesis.getVoices()
를 이용하면 현재 이용가능한 음성 리스트를 가져올 수 있다.
const synth = window.speechSynthesis;
const voices = [];
function settingVoices() {
voices.push(...this.getVoices());
voicesDropdown.innerHTML = voices
.map(voice => `<option value="${voice.name}">${voice.name} (${voice.lang})</option>`)
.join('');
}
synth.addEventListener('voiceschanged', settingVoices);
여기서 바로 getVoices()
메서드를 호출하지 않고 'voiceschanged'
를 이벤트로 등록하여 음성리스트를 가져오는 이유는 음성 리스트를 비동기적으로 가져오기 때문이다. 그래서 바로 호출해주면 undefined
값을 보게된다.
SpeechSynthesisUtterance 인터페이스를 이용하여 음성 서비스가 이용 할 텍스트나 언어, 음높이, 볼륨등에 대한 속성을 설정 할 수 있다.
속성 종류는 다음과 같다.
SpeechSynthesisUtterance.lang:
언어 설정
SpeechSynthesisUtterance.pitch:
음높이 설정
SpeechSynthesisUtterance.rate:
말하는 속도 설정
SpeechSynthesisUtterance.text:
이용할 텍스트 설정
SpeechSynthesisUtterance.voice:
보이스 설정
SpeechSynthesisUtterance.volume:
볼륨 설정
const msg = new SpeechSynthesisUtterance();
msg.text = word.value;
msg.voice = voices.find(voice => voice.name === voicesDropdown.value);
msg[rate] = 1.5;
msg[pitch] = 1;
이용할 음성 리스트도 가져왔고 음성 서비스를 설정하는 방법도 알아봤다.
그렇다면, 어떻게 텍스트를 음성 서비스가 읽을 수 있을까?
정말 간단하게 speechSynthesis 메서드
를 이용하면 된다.
SpeechSynthesis.cancel()
SpeechSynthesis.getVoices()
SpeechSynthesis.pause()
SpeechSynthesis.resume()
SpeechSynthesis.speak()
const msg = new SpeechSynthesisUtterance();
const word = document.querySelector('[name="text"]');
msg.text = word.value;
msg.voice = voices.find(voice => voice.name === voicesDropdown.value);
현재 textarea 요소에 적혀있는 값을 가져와 SpeechSynthesisUtterance.text
에 할당 해준다. 그리고 위에서 받아온 음성 리스트 중 선택된 음성을 SpeechSynthesisUtterance.voice
에 할당해준다.
synth.speak(msg);
모든 설정이 끝난 후, window.speechSynthesis.speack 메서드
에 인자로 설정한 SpeechSynthesisUtterance
로 넣어주기만 하면 음성 서비스가 읽기 시작한다.
(function(){
const voicesDropdown = document.querySelector('[name="voice"]');
const synth = window.speechSynthesis;
const voices = [];
const msg = new SpeechSynthesisUtterance();
const speakButton = document.querySelector('#speak');
const stopButton = document.querySelector('#stop');
const options = document.querySelectorAll('[type="range"]');
function settingVoices() {
voices.push(...this.getVoices());
voicesDropdown.innerHTML = voices
.map(voice => `<option value="${voice.name}">${voice.name} (${voice.lang})</option>`)
.join('');
}
function startSpeak() {
// 이전에 말하고 있는 단어 취소
stopSpeak();
const word = document.querySelector('[name="text"]');
msg.text = word.value;
msg.voice = voices.find(voice => voice.name === voicesDropdown.value);
synth.speak(msg);
}
function stopSpeak() {
synth.cancel();
}
function setOption() {
msg[this.name] = this.value;
}
synth.addEventListener('voiceschanged', settingVoices);
speakButton.addEventListener('click', startSpeak);
stopButton.addEventListener('click', stopSpeak);
[...options].map(option => option.addEventListener('change', setOption));
})();