在日常生活裡,我們早就習慣跟「會說話、能聽懂」的科技互動:Siri、Google 助理、YouTube/Meet 自動字幕…… 這些熟悉的功能,其實在瀏覽器裡也能做到。靠著 Web Speech API,我們可以用幾行 JavaScript 讓網頁「開口說話」甚至「聽懂你說的話」 ✨
這個 API 分成兩大功能:
雖然瀏覽器支援度不算完美,但在 Chrome 上已經能玩出很有趣的應用。
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)
這樣就能客製化「機器人聲音」的感覺。
小提醒:不同平台的語音庫不同,實際聲音會有差異。
⚠️ 注意:目前主要只有 Chrome / Edge 支援 STT。Safari、Firefox 支援有限。
語音辨識目前在 Chromium 系列瀏覽器(Chrome/Edge)以 webkitSpeechRecognition
為主;部份版本也掛在標準名稱 SpeechRecognition
。為了相容,常見的寫法會兩個都試。
呼叫 recog.start()
之後瀏覽器會跳出麥克風權限提示,一定要按允許喔!
lang
:設定辨識語言,例如 zh-TW
、en-US
。continuous
:是否持續監聽。預設為 false
(說完一次就停止),設為 true
則會持續辨識直到手動停止。interimResults
:是否回傳暫時結果。預設為 false
(只給最終結果),設為 true
可即時顯示尚未校正的語音文字。maxAlternatives
:回傳幾組候選結果,預設為 1。語音辨識的流程會經過下列事件:
start
:開始偵測語音。audiostart
/ audioend
:開始/結束接收音訊串流。soundstart
/ soundend
:偵測到聲音開始/結束(不限於語音)。speechstart
/ speechend
:偵測到語音開始/結束(有人說話)。result
:收到辨識結果;若 interimResults=true
,會不斷送出暫時結果,最後一次 isFinal=true
為最終結果。nomatch
:有聲音,但無法辨識成語音內容。error
:錯誤事件(如 not-allowed
、no-speech
、aborted
、network
)。end
:整體流程結束(可視需求於此自動 start()
)。常見錯誤對照:
not-allowed
→ 未授權麥克風或未經使用者操作。no-speech
→ 收不到語音(麥克風沒聲音或環境太安靜)。aborted
→ 主動結束辨識(使用者或程式),stop()
。
在 開發者工具 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);
}
如果你希望 持續監聽、且在使用者說話過程中就看到即時文字:
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);
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);
}
Demo 偷偷夾帶我的心聲哈哈哈
這樣就能「對網頁講話 → 網頁再把你的話唸出來」。是不是很像在跟電腦聊天? 🤖
interimResults=true
做逐字顯示;isFinal
為 true 時替換成校正後文字。你講話的時候,網頁會一邊把你說的話即時顯示出來,像是 YouTube 影片下方的字幕一樣。過去我們介紹了相機、麥克風、螢幕錄影,讓網頁能「看」也能「聽」。今天更進一步,讓網頁能「說」還能「聽懂你說的話」✨
本篇的範例都可以直接貼在開發者工具 console 上呈現,一定要玩玩看喔 🤗
👉 歡迎追蹤這個系列,我會從 Canvas 開始,一步步帶你認識更多 Web API 🎯