笔记

浏览器原生语音合成(TTS)开发经验

最近先后在站点上线了两个纯前端的朗读工具:Read Aloud智能朗读阅读器。两者都基于浏览器的 Web Speech API 实现,没有后端、没有上传、没有第三方语音服务。开发过程中踩了一些坑,也积累了一些可复用的经验,记录如下。

一、Web Speech API 基础

浏览器 TTS 的入口非常简洁:

const synth = window.speechSynthesis;
const utterance = new SpeechSynthesisUtterance(text);
synth.speak(utterance);

window.speechSynthesis 负责全局的语音队列,SpeechSynthesisUtterance 则是每一次发音的单元。在真正可用之前,建议先做兼容性判断:

if (!window.speechSynthesis) {
  alert('当前浏览器不支持 Web Speech API,无法使用朗读功能。');
  return;
}

目前 Safari、Chrome、Edge 等现代浏览器都支持该 API,但不同浏览器在语音质量、语音名、事件触发等方面差异明显,后面会详细说。

二、语音列表是异步加载的

第一次调用 speechSynthesis.getVoices() 时,返回的数组经常为空。

笔记

调试二维码识别与生成工具的几点经验

下午折腾了两个纯前端二维码工具:一个识别器、一个生成器。记录下调试过程中踩过的几个坑,免得以后重复踩。

1. 中文二维码识别出来是空的

用的是 jsQR。识别英文二维码没问题,但中文二维码识别结果直接为空。

查了下,jsQR 返回的对象里有两个字段:

  • code.data:legacy 字符串,对多字节字符支持不好
  • code.binaryData:原始字节数组

正确做法是用 binaryData 配合 TextDecoder 按 UTF-8 解码:

function decodeQRData(code) {
  if (code.binaryData && code.binaryData.length) {
    const bytes = new Uint8Array(code.binaryData);
    return new TextDecoder('utf-8').decode(bytes);
  }
  return code.data || '';
}

图片识别和摄像头扫码两处都要走这个解码逻辑。

2. 中文二维码生成后扫描乱码

生成器中 qr.addData(value) 对中文支持不行,需要先做一次 UTF-16 到 UTF-8 的字节转换: