iT邦幫忙

2024 iThome 鐵人賽

DAY 19
2
JavaScript

可愛又迷人的 Web API系列 第 19

Day19. 使用 Web Speech API 讓網頁開口說話

  • 分享至 

  • xImage
  •  

上一篇文章,我們提到 SpeechRecognition,他是用來識別使用者的語音內容,而 Web Speech API 的另外一個重點:SpeechSynthesis,則是提供了讓網頁開口說話的能力,也就是將文字轉成語音的功能,當網頁能說話,互動性感覺也增強了,是個能提升使用者體驗的強大功能。

基本的實作

使用 SpeechSynthesisUtterance 物件放入文字後,再使用 speechSynthesis.speak() 方法來播放語音,就是那麼簡單!

唯一要注意的是,有的瀏覽器會因為安全問題,阻止自動播放語音,所以我們可用加入使用者的互動,例如點選按鈕後才播放:

<button id="speakButton">點擊播放</button>
document.getElementById('speakButton').onclick = function () {
  // 創建 SpeechSynthesisUtterance 物件
  const utterance = new SpeechSynthesisUtterance('哈囉你好,很高興見到你');
  // 播放語音
  window.speechSynthesis.speak(utterance);
};

SpeechSynthesis 提供了控制語音播放的方法,在前面的範例我們用到了 speak() 方法來播放語音,其他方法包括暫停、停止和恢復播放:

// 暫停語音播放
window.speechSynthesis.pause();

// 恢復語音播放
window.speechSynthesis.resume();

// 停止語音播放
window.speechSynthesis.cancel();

SpeechSynthesisUtterance 屬性介紹

SpeechSynthesisUtterance 是 Web Speech API 中用於語音合成的物件,它包含多個屬性,可以用來設定語音合成的各種參數。以下是 SpeechSynthesisUtterance 的主要屬性以及它們的介紹

text

text 就是我們要放入的文字:

const utterance = new SpeechSynthesisUtterance();
utterance.text = '哈囉你好,很高興見到你';

// 也可以在建立時直接傳入
const utterance = new SpeechSynthesisUtterance('哈囉你好,很高興見到你');

lang

我們可以設定 lang 屬性來選擇不同的語音和口音

utterance.lang = 'zh-TW';
utterance.lang = 'en-US';
utterance.lang = 'ja-JP';

voice

使用 voice 來設定播放語音的聲音,我們先從 speechSynthesis.getVoices() 取得語音列表

console.log(window.speechSynthesis.getVoices())

以下是可用的語音清單:

https://mukiwu.github.io/web-api-demo/img/18-1.png

如果想要找繁體中文的口音,可以先找到第一筆 voice.langzh-TW 的語音,再指定到 voice

  let voices = [];
  
  // 當語音列表變更時觸發
  window.speechSynthesis.onvoiceschanged = function () {
    voices = window.speechSynthesis.getVoices();
  };

  document.getElementById('speakButton').onclick = function () {
    if (voices.length > 0) {
      const utterance = new SpeechSynthesisUtterance('哈囉你好,很高興見到你');
      utterance.voice = voices.find(voice => voice.lang === 'zh-TW');
      window.speechSynthesis.speak(utterance);
    } else {
      console.log('語音列表尚未準備好');
    }
  };

volume

這個是用來設定語音的音量,範圍從 0 到 1。0 代表靜音,1 代表最大音量。

utterance.volume = 0.8; // 設定音量為 80%

rate

這是設定語音說話的速度,範圍從 0.1101 是正常速度,數值越小語速越慢,數值越大語速越快。

pitch

設定語音的音調高低,範圍從 021 是正常音調,數值越小音調越低,數值越大音調越高。

SpeechSynthesisUtterance 事件介紹

語音事件有三個:語音開始、結束以及錯誤處理:

  • onstart:語音開始播放時觸發。
  • onend:語音播放結束時觸發。
  • onerror:語音播放錯誤時觸發。
const utterance = new SpeechSynthesisUtterance('哈囉你好,很高興見到你');

utterance.onstart = function() {
    console.log('語音播放開始');
};

utterance.onend = function() {
    console.log('語音播放結束');
};

utterance.onerror = function(event) {
    console.error('語音播放錯誤:', event.error);
};

實作動態選擇語音的功能

最後我們來做一個動態選擇語音的功能吧,使用者可以根據語言偏好選擇要播放的語音,還能在網頁上直接選擇語音的大小、音調,說話速度 ... 等等,還能暫停與恢復播放,也能輸入要讓語音說的話

<label for="voiceSelect">選擇語音:</label>
<select id="voiceSelect"></select><br><br>

<label for="volumeRange">音量:</label>
<input type="range" id="volumeRange" min="0" max="1" step="0.1" value="1"><br><br>

<label for="pitchRange">音調:</label>
<input type="range" id="pitchRange" min="0" max="2" step="0.1" value="1"><br><br>

<label for="rateRange">語速:</label>
<input type="range" id="rateRange" min="0.1" max="2" step="0.1" value="1"><br><br>

<label for="textToSpeak">要說的話:</label><br>
<textarea id="textToSpeak" rows="4" cols="50">你好,歡迎使用我們的網站</textarea><br><br>

<button id="speakButton">播放語音</button>
<button id="pauseButton">暫停播放</button>
<button id="resumeButton">恢復播放</button>
let voices = [];

// 更新語音選項
function populateVoiceList() {
  voices = window.speechSynthesis.getVoices();
  const voiceSelect = document.getElementById('voiceSelect');
  voiceSelect.innerHTML = '';

  voices.forEach((voice, index) => {
    const option = document.createElement('option');
    option.textContent = `${voice.name} (${voice.lang})`;
    option.value = index;
    voiceSelect.appendChild(option);
  });
}

// 當語音列表變更時更新語音選項
window.speechSynthesis.onvoiceschanged = populateVoiceList;

// 播放語音
document.getElementById('speakButton').onclick = function () {
  const textToSpeak = document.getElementById('textToSpeak').value;
  const utterance = new SpeechSynthesisUtterance(textToSpeak);

  // 設定語音選擇
  const selectedVoiceIndex = document.getElementById('voiceSelect').value;
  utterance.voice = voices[selectedVoiceIndex];

  // 設定音量、音調、語速
  utterance.volume = document.getElementById('volumeRange').value;
  utterance.pitch = document.getElementById('pitchRange').value;
  utterance.rate = document.getElementById('rateRange').value;

  // 播放語音
  window.speechSynthesis.speak(utterance);
};

// 暫停播放
document.getElementById('pauseButton').onclick = function () {
  window.speechSynthesis.pause();
};

// 恢復播放
document.getElementById('resumeButton').onclick = function () {
  window.speechSynthesis.resume();
};

範例程式碼

範例程式碼網址:https://mukiwu.github.io/web-api-demo/speech1.html

小結

最後的實作,是把前面提到的屬性、方法,事件全部融合在一起,讓使用者可以一次設定好語音的參數並送出。

透過這兩篇文章,相信大家對 Web Speech API 有更進一步的認識,應該也發現其實做一個會說話的助理遠比想像中的簡單,希望大家都能做出自己心目中的語音助理唷。

以上有任何問題,都歡迎留言討論。


上一篇
Day18. 使用 Web Speech API 讓網頁聽得懂我們說的話
下一篇
Day20. 用 Web Speech API 與你的 AI 朋友互動聊天
系列文
可愛又迷人的 Web API20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
connieleung
iT邦新手 5 級 ‧ 2024-09-27 14:52:30

有趣。粵語聽起來就像我在香港接到的詐騙電話。

我要留言

立即登入留言