- Khả năng & giới hạn
- Luồng hoạt động cơ bản
- Demo trực tiếp
- Cấu hình
- Transcript
- JS Deep-Dive: Web Speech API từ A đến Z
- 1. Kiến trúc & vòng đời nhận diện
- 2. Cấu hình quan trọng
- 3. Xử lý onresult: phân tách interim vs final
- 4. Quản lý trạng thái & tự phục hồi
- 5. Bắt & phân loại lỗi thường gặp
- 6. Gộp câu, chấm câu & chuẩn hoá kết quả
- 7. Bảo mật & quyền riêng tư
- 8. Tương thích trình duyệt & fallback
- 9. Mẹo hiệu năng & UX
- 10. Skeleton tối giản để tái sử dụng
- Mẹo triển khai thực tế
- Kết luận
Khả năng & giới hạn
- Hỗ trợ trình duyệt: tốt nhất trên Chromium (Chrome, Edge, Opera) qua
webkitSpeechRecognition. Firefox/Safari thường chưa hỗ trợ ổn định. - Bảo mật: yêu cầu HTTPS và quyền microphone từ người dùng.
- Ngôn ngữ: đặt bằng
recognition.lang(ví dụ:vi-VN,en-US). - Tuỳ chọn:
continuous(nghe liên tục),interimResults(trả kết quả tạm thời).
Luồng hoạt động cơ bản
- Kiểm tra API:
window.SpeechRecognition || window.webkitSpeechRecognition. - Tạo instance, cấu hình ngôn ngữ, chế độ.
- Bắt đầu nghe (
start()) → xử lý sự kiệnonresult,onerror,onend. - Hiển thị transcript tạm thời & cuối cùng; lưu lịch sử nếu cần.
Demo trực tiếp
Cấu hình
Transcript
Sẵn sàng.
| Lần nhận kết quả | 0 |
| Độ tin cậy (confidence) | — |
| Trạng thái | idle |
| Lỗi gần nhất | — |
JS Deep-Dive: Web Speech API từ A đến Z
1. Kiến trúc & vòng đời nhận diện
SpeechRecognition (hoặc webkitSpeechRecognition) là wrapper của dịch vụ STT do trình duyệt cung cấp (Chrome dùng backend đám mây). Vòng đời cơ bản:
- Tạo instance → cấu hình
lang,continuous,interimResults. start()→ trình duyệt xin quyền mic →onstart.- Luồng kết quả qua
onresult(nhiều chunk, có thể lẫn interim & final). onerrorkhi có lỗi;onendkhi phiên nghe kết thúc.- Tùy UX: gọi lại
start()để “tái khởi động” nếu muốn nghe liên tục bền bỉ.
2. Cấu hình quan trọng
recognition.lang = 'vi-VN': chọn mô hình ngôn ngữ; nên bám theo ngôn ngữ UI.recognition.continuous = true: nghe nhiều câu/đợt; lưu ý vẫn có thểonenddo hệ thống tạm dừng.recognition.interimResults = true: bật kết quả tạm (gõ nháp) để UX “realtime”.
3. Xử lý onresult: phân tách interim vs final
recognition.onresult = (event) => {
let interim = '';
for (let i = event.resultIndex; i < event.results.length; i++) {
const res = event.results[i];
const txt = res[0].transcript;
if (res.isFinal) {
appendFinal(txt, res[0].confidence); // lưu kết quả cuối
} else {
interim += txt; // hiển thị tạm thời
}
}
showInterim(interim);
};
event.resultIndex: index của batch mới – duyệt từ đây để không lặp.res[0].confidence: gợi ý độ tin cậy; đừng xem như “sự thật tuyệt đối”.
4. Quản lý trạng thái & tự phục hồi
let isManuallyStopped = false;
recognition.onend = () => {
setUI('idle');
if (!isManuallyStopped && wantKeepAlive) {
// Auto-restart sau 200–500ms để tránh vòng lặp quá gắt
setTimeout(() => recognition.start(), 300);
}
};
function start() { isManuallyStopped = false; recognition.start(); }
function stop() { isManuallyStopped = true; recognition.stop(); }
Lưu ý: một số nền tảng sẽ tự onend sau vài chục giây im lặng; cơ chế tự khởi động lại giúp “continuous” thực sự bền.
5. Bắt & phân loại lỗi thường gặp
recognition.onerror = (e) => {
switch (e.error) {
case 'not-allowed': // user chặn quyền mic hoặc policy chặn
case 'service-not-allowed':
showErr('Chưa được cấp quyền micro.'); break;
case 'no-speech': // không phát hiện âm thanh
showWarn('Không nghe thấy giọng nói.'); break;
case 'audio-capture': // không tìm thấy thiết bị mic
showErr('Không tìm thấy thiết bị micro.'); break;
case 'network': // backend STT gặp sự cố mạng
showErr('Lỗi mạng khi nhận diện.'); break;
case 'aborted': // bị dừng bởi hệ thống/ứng dụng
showWarn('Phiên nghe bị dừng.'); break;
default:
showErr('Lỗi khác: ' + e.error);
}
};
UX tốt nên hiển thị trạng thái rõ ràng và hướng dẫn cách khắc phục (bật mic, đổi trình duyệt, dùng HTTPS).
6. Gộp câu, chấm câu & chuẩn hoá kết quả
function normalize(sentence) {
let s = sentence.trim();
if (!s) return '';
// Viết hoa chữ cái đầu
s = s.charAt(0).toUpperCase() + s.slice(1);
// Thêm dấu chấm nếu chưa có
if (!/[.!?…]$/.test(s)) s += '.';
return s + ' ';
}
function appendFinal(txt, conf) {
finalBox.value += normalize(txt);
confBox.textContent = (conf * 100).toFixed(1) + '%';
}
Web Speech API không luôn thêm dấu câu; bạn có thể hậu xử lý để transcript sạch hơn.
7. Bảo mật & quyền riêng tư
- Chỉ chạy trên HTTPS, và chỉ ghi âm khi người dùng chủ động bấm mic.
- Không gửi audio thô lên server trừ khi thật cần; tốt nhất chỉ gửi văn bản đã xác nhận.
- Hiển thị chỉ báo đang ghi âm (UI & icon mic trình duyệt) để minh bạch.
8. Tương thích trình duyệt & fallback
- Chromium (Chrome/Edge/Opera): hỗ trợ tốt qua
webkitSpeechRecognition. - Safari/Firefox: hỗ trợ hạn chế/không ổn định → ẩn nút mic và hiển thị hướng dẫn.
- Mobile: iOS có thể dừng khi tab nền; Android ổn hơn nhưng phụ thuộc quyền mic/hệ thống.
9. Mẹo hiệu năng & UX
- Tránh DOM reflow nặng trong
onresult; chỉ cập nhật text/đếm đơn giản. - Cho phép đổi ngôn ngữ nhanh (vi-VN <→ en-US) mà không reload toàn trang.
- Debounce thao tác UI (ví dụ đổi lang) trước khi
start()lại để không “giật”. - Ghi log nhẹ nhàng để debug (số chunk, lỗi cuối, trạng thái).
10. Skeleton tối giản để tái sử dụng
class STT {
constructor({ lang = 'vi-VN', continuous = true, interim = true } = {}) {
const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SR) throw new Error('SpeechRecognition not supported');
this.rec = new SR();
this.rec.lang = lang;
this.rec.continuous = continuous;
this.rec.interimResults = interim;
}
onstart(fn){ this.rec.onstart = fn; return this; }
onend(fn){ this.rec.onend = fn; return this; }
onerror(fn){ this.rec.onerror = fn; return this; }
onresult(fn){ this.rec.onresult = fn; return this; }
start(){ this.rec.start(); return this; }
stop(){ this.rec.stop(); return this; }
setLang(lang){ this.rec.lang = lang; return this; }
setContinuous(v){ this.rec.continuous = !!v; return this; }
setInterim(v){ this.rec.interimResults = !!v; return this; }
}
// Sử dụng
// new STT().onresult(handle).onerror(handle).start();
TL;DR: Nắm vòng đời (start → onresult/onerror → onend), phân tách interim/final, tự phục hồi phiên nghe, và xử lý UX/permission minh bạch — là bạn đã có voice-to-text chạy mượt trên web.
Mẹo triển khai thực tế
- UX: luôn hiển thị trạng thái “Đang nghe / Tạm dừng / Lỗi” rõ ràng.
- Fallback: nếu trình duyệt không hỗ trợ, ẩn nút mic và hiện hướng dẫn dùng Chrome/Edge.
- Ngữ cảnh: có thể gợi ý ngôn ngữ theo UI (ví dụ site tiếng Việt → mặc định
vi-VN). - Lưu trữ: nếu cần, đẩy transcript lên server sau khi user xác nhận (đừng gửi audio thô nếu không cần).
Kết luận
Web Speech API giúp mở khóa trải nghiệm nhập liệu rảnh tay ngay trên trình duyệt. Chỉ với vài chục dòng JS, bạn có thể có voice-to-text realtime cho form tìm kiếm, soạn thảo nội dung, hay chatbot — miễn là hiểu rõ giới hạn trình duyệt và quyền mic.
Bình luận