iT邦幫忙

2025 iThome 鐵人賽

DAY 16
0
Modern Web

從 Canvas 到各式各樣的 Web API 之旅系列 第 16

Day 16 - 讓網頁能說能聽,語音互動一把罩!Web Speech API

  • 分享至 

  • xImage
  •  

在日常生活裡,我們早就習慣跟「會說話、能聽懂」的科技互動:Siri、Google 助理、YouTube/Meet 自動字幕…… 這些熟悉的功能,其實在瀏覽器裡也能做到。靠著 Web Speech API,我們可以用幾行 JavaScript 讓網頁「開口說話」甚至「聽懂你說的話」 ✨

這個 API 分成兩大功能:

  • Speech Synthesis (Text‑to‑Speech, TTS):把文字轉成語音,讓網頁「講話」。
  • Speech Recognition (Speech‑to‑Text, STT):把語音轉成文字,讓網頁「聽懂」。

雖然瀏覽器支援度不算完美,但在 Chrome 上已經能玩出很有趣的應用。


讓網頁開口說話(TTS)

window.speechSynthesis 就是文字轉語音的入口:

const utter = new SpeechSynthesisUtterance("哈囉,我是你的網頁小助理!");
speechSynthesis.speak(utter);

開發者工具 console 貼上這段,馬上就能聽到瀏覽器講話。

也可以改 utter.text 成其他內容,甚至指定 語言、因ㄌㄧㄤ、語速、音高

utter.lang = "zh-TW"; // 語言
utter.volume = 0.8;   // 音量 (0 - 1)
utter.rate = 1.2;     // 語速 (0.1 - 10)
utter.pitch = 1.5;    // 音高 (0 - 2)

這樣就能客製化「機器人聲音」的感覺。

小提醒:不同平台的語音庫不同,實際聲音會有差異。


讓網頁聽你說話(STT)

⚠️ 注意:目前主要只有 Chrome / Edge 支援 STT。Safari、Firefox 支援有限。

語音辨識目前在 Chromium 系列瀏覽器(Chrome/Edge)以 webkitSpeechRecognition 為主;部份版本也掛在標準名稱 SpeechRecognition。為了相容,常見的寫法會兩個都試。

呼叫 recog.start() 之後瀏覽器會跳出麥克風權限提示,一定要按允許喔!

語音辨識權限

SpeechRecognition API 的常用屬性

  • lang:設定辨識語言,例如 zh-TWen-US
  • continuous:是否持續監聽。預設為 false(說完一次就停止),設為 true 則會持續辨識直到手動停止。
  • interimResults:是否回傳暫時結果。預設為 false(只給最終結果),設為 true 可即時顯示尚未校正的語音文字。
  • maxAlternatives:回傳幾組候選結果,預設為 1。

SpeechRecognition API 的常見事件

語音辨識的流程會經過下列事件:

  • start:開始偵測語音。
  • audiostart / audioend:開始/結束接收音訊串流。
  • soundstart / soundend:偵測到聲音開始/結束(不限於語音)。
  • speechstart / speechend:偵測到語音開始/結束(有人說話)。
  • result:收到辨識結果;若 interimResults=true,會不斷送出暫時結果,最後一次 ‎isFinal=true 為最終結果。
  • nomatch:有聲音,但無法辨識成語音內容。
  • error:錯誤事件(如 not-allowedno-speechabortednetwork)。
  • end:整體流程結束(可視需求於此自動 start())。

常見錯誤對照:

  • not-allowed → 未授權麥克風或未經使用者操作。
  • no-speech → 收不到語音(麥克風沒聲音或環境太安靜)。
  • aborted → 主動結束辨識(使用者或程式),stop()

Demo 1:最精簡的辨識(語音辨識 demo)

開發者工具 console 貼上這段,就能做個「語音辨識 demo」:

為了符合權限/手勢要求,下面程式會在頁面右上角插一顆按鈕。
按下去才開始辨識。

const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SR) {
  console.warn("此瀏覽器不支援 SpeechRecognition");
}

// 建立語音辨識物件
const recog = SR ? new SR() : null;
if (recog) {
  recog.lang = "zh-TW";

  // 當辨識到語音結果時觸發
  recog.onresult = (e) => {
    console.log("我聽到:", e.results[0][0].transcript);
  };


  // 建立一個按鈕,讓使用者點擊開始辨識
  const btn = document.createElement("button");
  btn.textContent = "🎙️ 點我開始辨識 Demo";
  Object.assign(btn.style, {
      position: "fixed",
      top: "10px",
      right: "12px",
      zIndex: 999999,
      padding: "8px 12px",
      borderRadius: "8px",
  });
    
  // 按下按鈕時開始語音辨識
  btn.onclick = () => {
    try {
      recog.start();
    } catch (err) {
      console.warn("啟動失敗:", err);
    }
  };
    
  // 把按鈕加到網頁上
  document.body.appendChild(btn);
}

讓網頁聽你說話(STT) 1

Demo 2:持續監聽 + 即時字幕(連續模式的語音辨識 demo)

如果你希望 持續監聽、且在使用者說話過程中就看到即時文字

  • continuous = true:一次開始後持續監聽,不會因為停頓就自動永久關閉(注意:仍有可能在長時間靜默後觸發 onend,可在 onend 裡自行 start() 續命)。
  • interimResults = true:回傳「暫時結果」(非最終校正前),可做即時字幕。

開發者工具 console 貼上這段,就能做個「連續模式的語音辨識 demo」:

const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SR) {
  console.warn("此瀏覽器不支援 SpeechRecognition");
}

const recog = new SR();
recog.lang = "zh-TW";
recog.continuous = true; // 持續監聽,不會因停頓自動停止
recog.interimResults = true; // 開啟暫時結果,可即時顯示尚未校正的語音文字
recog.maxAlternatives = 1; // 只回傳一組候選結果

recog.onresult = (e) => {
  let finalText = "";
  let interimText = "";
  for (let i = e.resultIndex; i < e.results.length; i++) {
    const r = e.results[i];
    if (r.isFinal) finalText += r[0].transcript;
    else interimText += r[0].transcript;
  }
  console.log({ finalText, interimText });
};

let autoRestart = true;
recog.onend = () => {
  if (autoRestart) {
    try {
      recog.start();
    } catch {}
  }
};

// 建立一個按鈕來觸發辨識
const btn = document.createElement("button");
btn.textContent = "🎙️ 點我開始即時字幕 Demo";
Object.assign(btn.style, {
  position: "fixed",
  top: "60px", // 避開第一個 demo 的按鈕
  right: "12px",
  zIndex: 999999,
  padding: "8px 12px",
  borderRadius: "8px",
});
btn.onclick = () => {
  try {
    recog.start();
  } catch (err) {
    console.warn("啟動失敗:", err);
  }
};
document.body.appendChild(btn);

讓網頁聽你說話(STT) 2

Demo 偷偷夾帶崩潰的抱怨哈哈哈


兩個 API 結合:網頁會聽也會回(對話 demo)

開發者工具 console 貼上這段,就能做個「對話 demo」:

const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SR) {
  console.warn("此瀏覽器不支援 SpeechRecognition");
}

const recog = SR ? new SR() : null;
if (recog) {
  recog.lang = "zh-TW";

  recog.onresult = (e) => {
    const msg = e.results[0][0].transcript;
    console.log("你說:", msg);

    // 若正在講話,先中止,避免疊音
    speechSynthesis.cancel();
    const u = new SpeechSynthesisUtterance("你剛剛說的是:" + msg);
    u.lang = "zh-TW";
    speechSynthesis.speak(u);
  };

  recog.onerror = (e) => console.warn("辨識錯誤:", e.error);
  recog.onend = () => console.log("辨識結束");

  // 建立一個按鈕,讓使用者點擊開始辨識
  const btn = document.createElement("button");
  btn.textContent = "🎙️ 點我開始辨識及對話 Demo";
  Object.assign(btn.style, {
    position: "fixed",
    top: "110px", // 避開第一、二個 demo 的按鈕
    right: "12px",
    zIndex: 999999,
    padding: "8px 12px",
    borderRadius: "8px",
  });

  btn.onclick = () => {
    try {
      recog.start();
    } catch (err) {
      console.warn("啟動失敗:", err);
    }
  };

  document.body.appendChild(btn);
}

讓網頁聽你說話(STT) 3

Demo 偷偷夾帶我的心聲哈哈哈

這樣就能「對網頁講話 → 網頁再把你的話唸出來」。是不是很像在跟電腦聊天? 🤖


注意事項

  • 支援度
    • Text-to-Speech 大部分瀏覽器都有支援
    • Speech-to-Text 目前主要是 Chrome。Safari/Firefox 支援有限。
  • 使用情境
    • 朗讀文章(輔助工具)。
    • 語音輸入(免打字)。
    • 做一個小小語音助理(聊天 Demo)。
  • 隱私與權限:記得語音辨識需要使用者允許麥克風。

延伸可以做什麼

  • 語音搜尋:你只要對著網頁說「搜尋貓咪咖啡廳」,網站就能自動抓出「貓咪咖啡廳」這幾個字,幫你跳到搜尋結果頁,不用再打字。
  • 即時字幕interimResults=true 做逐字顯示;isFinal 為 true 時替換成校正後文字。你講話的時候,網頁會一邊把你說的話即時顯示出來,像是 YouTube 影片下方的字幕一樣。
  • 語音表單填寫:只要說「姓名王小明」、「Email xx@example.com」,網頁就會自動幫你把資料填進表格,省去手動輸入。
  • 語音控制網站:說「打開設定」、「下一頁」、「返回首頁」這類指令,網站就會自動幫你切換頁面或開啟功能,像聲控遙控器一樣。
  • 無障礙輔助:網頁可以朗讀畫面上的內容給你聽(TTS),也能聽你說話並把回饋轉成文字(STT),幫助看不方便或手不方便的使用者更容易操作網站。
  • Kiosk/智慧裝置:在自助點餐機、導覽機等全螢幕網頁,只要用說的就能完成點餐、查詢或導覽,不需要觸控螢幕。
  • 語言學習:你說一句外語,網頁會把你說的內容轉成文字,再比對你是不是講對了,幫助練習發音和句型。

小結

過去我們介紹了相機、麥克風、螢幕錄影,讓網頁能「看」也能「聽」。今天更進一步,讓網頁能「說」還能「聽懂你說的話」✨

本篇的範例都可以直接貼在開發者工具 console 上呈現,一定要玩玩看喔 🤗


👉 歡迎追蹤這個系列,我會從 Canvas 開始,一步步帶你認識更多 Web API 🎯


上一篇
Day 15 - 用 Notification API 讓網頁也能推播作業系統級通知
系列文
從 Canvas 到各式各樣的 Web API 之旅16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言