Web Speech API: Chuyển giọng nói thành text ngay trên web

Web Speech API cho phép trình duyệt nhận diện giọng nói và trả về văn bản theo thời gian thực. Bạn có thể build tính năng voice search, nhập liệu bằng giọng nói, hay trợ lý ảo trực tiếp trên web — không cần cài app.

Web Speech API: Chuyển giọng nói thành text ngay trên web

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 HTTPSquyề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

  1. Kiểm tra API: window.SpeechRecognition || window.webkitSpeechRecognition.
  2. Tạo instance, cấu hình ngôn ngữ, chế độ.
  3. Bắt đầu nghe (start()) → xử lý sự kiện onresult, onerror, onend.
  4. 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

Yêu cầu HTTPS và quyền microphone. Hỗ trợ tốt nhất trên Chrome/Edge.

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:

  1. Tạo instance → cấu hình lang, continuous, interimResults.
  2. start() → trình duyệt xin quyền mic → onstart.
  3. Luồng kết quả qua onresult (nhiều chunk, có thể lẫn interim & final).
  4. onerror khi có lỗi; onend khi phiên nghe kết thúc.
  5. 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ể onend do 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 (startonresult/onerroronend), 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


  • Không có bình luận.

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...