更新记录
1.2.22(2026-09-06)
- 修复 uni-app x Android 示例的云端响应解析:统一读取
response.data,并兼容 JSON 文本、嵌套 data 和 URL 别名。
1.2.21(2026-08-13)
- Web 增加统一中文诊断日志,输出初始化、请求参数、实际音色、
localService、网络与页面状态、speechSynthesis状态及onstart / onend / onerror生命周期;日志不打印播报原文。 - 修复 Ubuntu 浏览器能够枚举
zh-CN / Google 普通话,但语音后端静默挂起时success / fail / complete均不触发的问题;按timeout分别监控等待开始和等待结束阶段,超时返回details.browserError = "speech-timeout"与details.phase,并取消挂起任务。 - Web
start事件和失败详情补充实际音色是否为本地服务等诊断字段;说明localService: false的在线音色出现在列表中不代表当前电脑一定能够连接合成服务。
1.2.20(2026-08-13)
- 修复 Web 端云端女声音色名在 Ubuntu 不存在时丢失性别偏好的问题;
Xiaoxiao / Jenny / Belinda / female / 女声会优先匹配同语言女性音色,Yunxi / Guy / male / 男声会优先匹配男性音色,无匹配时再回退基础同语言音色。 - Web 播报会把独立技术缩写
v2v归一化为V to V,避免 Ubuntu 普通话引擎读成“V 二 V”;不全局替换数字2,不影响普通数字、日期、数量和型号。 - Web
start事件增加selectedVoiceName / selectedVoiceLang,便于确认最终选中的浏览器音色。
平台兼容性
uni-app(4.84)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | √ | - | - | - | - | - | - | - | - | - | - |
uni-app x(4.84)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ |
lizhao-smart-tts
lizhao-smart-tts 是面向 uni-app / uni-app x 的文字转语音(TTS)插件。传入一段文字,插件就能把它读出来,适合订单提醒、消息通知、导航提示、课程朗读、小说听书等场景。
插件提供三条播报路线:直接使用手机或浏览器自带的系统 TTS、在 Android 设备上加载离线模型、调用云端服务生成高质量语音。第一次接入建议先用系统 TTS,确认基本播报正常后,再根据业务需要增加离线或云端能力。
这个插件能解决什么问题
- 把普通文字直接读出来,不需要自己处理原生语音 API。
- 查询并选择设备上已有的中文、英文等系统音色。
- 暂停、继续、停止播报,并管理多条播报任务。
- 在 Android 无网络环境中使用 Sherpa-ONNX 模型播报。
- 通过 Edge TTS、CosyVoice 或商业 TTS 服务获得固定音色和更自然的声音。
- 为小说、课程等长文本分段播报,并传递缓存键、角色和情绪信息。
- 同时提供纯 API 和 uni-app 内置按钮组件两种接入方式。
支持平台
| 平台 | 是否支持 | 默认方式 | 需要注意 |
|---|---|---|---|
| uni-app Android | 是 | 系统 TTS | 使用离线模型时需要 Android 自定义基座 |
| uni-app iOS | 是 | 系统 TTS | 可配置云端 TTS 作为其他路线 |
| uni-app Harmony | 是 | 云端音频 | 当前不提供系统原生 TTS 音色 |
| uni-app Web | 是 | 浏览器系统 TTS | 当前不会自动请求 cloud.endpoint |
| 微信小程序 | 是 | 云端音频 | 需要配置请求和音频下载合法域名 |
| 支付宝小程序 | 是 | 云端音频 | 需要配置请求和音频下载合法域名 |
| uni-app x Android | 是 | 系统 TTS | 使用离线模型时需要 Android 自定义基座 |
| uni-app x iOS | 是 | 系统 TTS | 与 iOS App 的系统 TTS 路线一致 |
| uni-app x Harmony | 是 | 云端音频 | 需要配置云端合成服务 |
| uni-app x Web | 是 | 浏览器系统 TTS | 当前不会自动请求 cloud.endpoint |
先选择接入方式
| 你的需求 | 推荐方式 | 是否联网 | 是否需要重新制作 Android 自定义基座 |
|---|---|---|---|
| 先快速播报一句话 | 系统 TTS | 否 | 否 |
| 订单、导航、设备状态等短提示 | 系统 TTS | 否 | 否 |
| Android 设备必须完全离线播报 | 离线 TTS | 否 | 是,首次加入或更换 AAR/SO 时需要 |
| 固定音色、高音质、不同设备声音一致 | 云端 TTS | 是 | 否 |
| Harmony 或小程序播报 | 云端 TTS | 是 | 否 |
| 小说、课程等长文本 | 云端 TTS 优先,系统 TTS 兜底 | 是 | 否 |
不确定时直接选择系统 TTS。它不需要模型和服务器,最适合先验证插件是否接入成功。
下载与导入
把插件放入项目的 uni_modules/lizhao-smart-tts 目录,然后只从插件根目录导入:
import {
initTTS,
speak,
pause,
resume,
stop,
getVoices,
getCapabilities,
onTtsEvent,
offTtsEvent
} from '@/uni_modules/lizhao-smart-tts'
不要直接导入 utssdk/index.uts 或某个平台目录中的文件。
按业务模块使用
下面从最简单的系统播报开始,再逐步介绍音色、播放控制、离线模型和云端服务。只使用其中一个模块也可以,不需要把所有能力都配置一遍。
模块一:用系统 TTS 播报一句话
系统 TTS 直接使用设备已经安装的语音引擎。Android 使用系统 TextToSpeech,iOS 使用 AVSpeechSynthesizer,Web 使用浏览器 SpeechSynthesis。
import { initTTS, speak } from '@/uni_modules/lizhao-smart-tts'
// 页面进入后先初始化一次。
initTTS({
lang: 'zh-CN',
fallbackChain: ['native'],
success(res) {
console.log('TTS 初始化成功', res.capabilities.adapter)
},
fail(err) {
console.log('TTS 初始化失败', err.errCode, err.errMsg)
}
})
// 初始化成功后,可以多次调用 speak。
speak({
text: '订单已完成,请及时处理',
rate: 1.0,
pitch: 1.0,
volume: 1.0,
success(res) {
console.log('播报完成', res.taskId)
},
fail(err) {
console.log('播报失败', err.errCode, err.errMsg)
},
complete(res) {
console.log('本次播报已结束', res)
}
})
调用顺序始终是:先执行 initTTS(),成功后再执行 speak()。如果页面会连续播报多句话,只需要初始化一次。
模块二:查询并选择系统音色
音色名称由操作系统或浏览器决定。先调用 getVoices() 获取真实列表,再把其中的 name 传给 voiceName。
import { getVoices, speak } from '@/uni_modules/lizhao-smart-tts'
getVoices({
success(voices) {
console.log('当前设备可用音色', voices)
if (voices.length === 0) {
return
}
speak({
text: '这是一段指定音色的播报',
lang: voices[0].lang,
voiceName: voices[0].name
})
}
})
Web 用户需要区分两个参数:
| 参数 | 用途 |
|---|---|
voiceName |
选择浏览器或系统真实音色,值来自 getVoices() 返回的 name |
voiceRole |
传给云端服务的业务角色,如旁白、男声、女声,不用于选择浏览器音色 |
Web 指定音色示例:
speak({
text: '你好,这是普通话测试',
lang: 'cmn',
voiceName: 'Chinese (Mandarin)+Belinda'
})
如果指定名称不存在,插件会按 lang 选择同语言音色;目标语言完全不可用时返回错误,不会偷偷换成其他语言。浏览器只能提供音色名称、语言和是否为本地音色等信息,不能判断哪一个声音最自然,最终仍应在目标电脑上逐个试听。
选择普通话音色时,可以按以下顺序处理:
- 优先筛选
zh-CN或cmn,它们表示普通话。 - 优先试听名称中明确写有普通话或中文语音引擎的音色。
- 确认满意后,保存完整的
name并传给voiceName。 - 如果不同设备必须保持相同声音,应改用云端 TTS。
模块三:暂停、继续、停止和监听进度
import {
pause,
resume,
stop,
onTtsEvent,
offTtsEvent
} from '@/uni_modules/lizhao-smart-tts'
const handleProgress = (event) => {
console.log('播报进度', event.taskId, event.progress)
}
onTtsEvent('progress', handleProgress)
pause({})
resume({})
// 停止当前任务,并清空还没有开始的任务。
stop({ clearQueue: true })
// 页面离开时使用同一个函数引用取消监听。
offTtsEvent('progress', handleProgress)
Android 系统 TTS 没有真正的暂停接口。插件采用 restart-segment 降级方式:暂停后继续时,会从当前分段开头重新读。
多次调用 speak() 时,任务会进入队列。常用控制规则如下:
| 配置 | 效果 |
|---|---|
priority |
数值越大,任务在待播队列中的优先级越高 |
interrupt: true |
让本次任务打断当前播报并优先执行 |
stop({ clearQueue: true }) |
停止当前任务并清空待播队列 |
maxSegmentLength |
把长文本拆成较短段落,默认每段最多 120 个字符 |
模块四:直接使用内置播报按钮
不想自己写按钮和状态文字时,uni-app Vue 页面可以直接使用内置组件:
<template>
<lizhao-smart-tts
text="欢迎使用智能语音播报"
button-text="开始播报"
:options="ttsOptions"
:disabled="false"
@ready="handleReady"
@success="handleSuccess"
@error="handleError"
/>
</template>
<script>
export default {
data() {
return {
ttsOptions: {
lang: 'zh-CN',
fallbackChain: ['native', 'cloud']
}
}
},
methods: {
handleReady(res) {
console.log('TTS 已就绪', res)
},
handleSuccess(res) {
console.log('播报完成', res)
},
handleError(err) {
console.log('播报失败', err)
}
}
}
</script>
组件本身提供按钮和状态展示;需要完全自定义界面,或使用 uni-app x 页面时,直接调用上面的纯 API。
模块五:Android 完全离线播报
离线 TTS 适合设备不能联网、但仍必须稳定播报的场景。默认插件包不包含 Sherpa-ONNX AAR、SO 和大模型,因此只使用系统 TTS 或云端 TTS 的项目可以跳过整个模块。
离线能力包含两类资源:
| 资源 | 什么时候准备 | 能否安装后下载 |
|---|---|---|
| Sherpa-ONNX Android AAR / SO | 制作 Android 自定义基座之前 | 否 |
| TTS 模型目录 | 可以随基座打包,也可以在 App 运行后下载 | 是 |
如果需要控制安装包体积,推荐采用“只把 arm64-v8a 运行库放进基座,模型在运行后下载”的方式。
方式一:模型随基座打包
下载并放置资源:
| 资源 | 下载地址 | 放置位置 |
|---|---|---|
| Android AAR | https://github.com/k2-fsa/sherpa-onnx/releases/download/v1.13.2/sherpa-onnx-1.13.2.aar |
utssdk/app-android/libs/sherpa-onnx-1.13.2.aar |
| 中文模型 | https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-melo-tts-zh_en.tar.bz2 |
utssdk/app-android/assets/sherpa-onnx/zh-pro/ |
| 西班牙语模型 | https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-piper-es_ES-miro-high.tar.bz2 |
utssdk/app-android/assets/sherpa-onnx/es-es-miro/ |
中文模型初始化示例:
import { initTTS, speak } from '@/uni_modules/lizhao-smart-tts'
initTTS({
lang: 'zh-CN',
fallbackChain: ['offline-ai', 'native'],
offline: {
engine: 'sherpa-onnx',
modelDir: 'sherpa-onnx/zh-pro',
speakerId: 0
}
})
speak({
text: '这是一段完全离线的语音播报'
})
模型会增加自定义基座体积。中文模型约 180MB 时,不适合有 60MB 左右包体限制的项目。
方式二:模型在 App 运行后下载
制作基座前,只把目标设备需要的原生运行库放入:
uni_modules/lizhao-smart-tts/utssdk/app-android/libs/sherpa-onnx-1.13.2-arm64-v8a.aar
App 运行后,把模型压缩包下载并解压到 App 私有目录,例如:
_doc/lizhao-smart-tts/sherpa-onnx/zh-pro
模型目录至少需要包含:
model.onnx 或其他 .onnx 文件
tokens.txt
lexicon.txt 或 espeak-ng-data/
模型自带的 dict/、phone.fst、date.fst、number.fst 等文件
把 _doc 路径转换成 Android 绝对路径后,传给 modelPath:
import { initTTS, speak } from '@/uni_modules/lizhao-smart-tts'
// 请替换为下载和解压工具返回的真实 Android 绝对目录。
const modelPath = '/data/user/0/你的包名/files/sherpa-onnx/zh-pro'
initTTS({
lang: 'zh-CN',
fallbackChain: ['offline-ai', 'native'],
offline: {
engine: 'sherpa-onnx',
modelPath,
speakerId: 0
},
success(res) {
console.log('离线模型加载成功', res.capabilities.details)
},
fail(err) {
console.log('离线模型加载失败', err.errCode, err.errMsg, err.details)
}
})
speak({
text: '模型下载完成后,不联网也可以播报'
})
可以使用 plus.io.convertLocalFileSystemURL() 把 _doc 路径转换为 Android 绝对路径。modelPath 必须指向已经解压的模型目录,不能指向 zip 或 .tar.bz2 压缩包。
放入或更换 AAR/SO 后,必须重新制作并安装 Android 自定义基座;只更换运行后下载的模型,而且当前基座已经包含正确的 AAR/SO 时,不需要重新制作基座。
模块六:使用云端 TTS 获得固定音色
云端 TTS 会把文字发送到你的服务端,服务端合成音频并返回一个可播放的 audioUrl。它适合固定音色、高音质、多端一致、Harmony、小程序和小说听书。
云端接口默认返回以下结构:
{
"audioUrl": "https://example.com/audio/demo.wav",
"cacheHit": false,
"durationMs": 1200,
"provider": "custom",
"voice": "zh-CN-XiaoxiaoNeural"
}
如果服务返回的音频地址字段不是 audioUrl,使用 cloud.responseField 指定真实字段名。
import { initTTS, speak } from '@/uni_modules/lizhao-smart-tts'
initTTS({
lang: 'zh-CN',
fallbackChain: ['cloud', 'native'],
cloudOnly: true,
cloud: {
provider: 'custom',
endpoint: 'https://你的域名/v1/tts',
method: 'POST',
responseField: 'audioUrl',
cache: {
enabled: true,
namespace: 'tts-demo',
maxAgeMs: 86400000,
maxItems: 100
}
}
})
speak({
text: '这是一段云端 TTS 测试',
voiceName: 'zh-CN-XiaoxiaoNeural',
cacheKey: 'demo:cloud:001',
cloudOnly: true
})
cloudOnly: true 表示本次只测试云端路线,避免系统 TTS 初始化结果影响排查。生产项目也可以移除它,并使用 fallbackChain: ['cloud', 'native'] 在云端失败时回退到系统 TTS。
密钥和 Token 必须保存在服务端,不能写在 App、Web 页面或插件配置中。
模块七:小说、课程和长文本播报
长文本建议先按章节或自然段拆分。每段使用稳定的 cacheKey,服务端就可以复用已经生成的音频;voiceRole、emotion 和 metadata 可用于区分旁白、角色或业务场景。
speak({
text: '雨声落在旧城的青石路上。',
scene: 'novel',
cacheKey: 'book-100:chapter-1:paragraph-1',
voiceRole: 'narrator',
emotion: 'calm',
metadata: {
bookId: 'book-100',
chapterId: 'chapter-1'
},
fallbackChain: ['cloud', 'native']
})
小说听书通常还需要在业务页面保存当前章节和段落位置。插件负责播报、队列和事件,章节列表、断点记录以及“上一段/下一段”界面由业务页面管理。完整实现可参考 小说听书示例。
模块八:选择一种云端服务
插件不绑定某一家云服务,只要求服务端最终返回可播放的音频地址。
| 方案 | 适合场景 | 特点 |
|---|---|---|
| Edge TTS uniCloud 模板 | 快速测试和演示 | 部署简单,但不建议作为长期商业核心链路 |
| CosyVoice Docker 服务 | 私有化部署、高音质 | 需要自己的服务器、模型和运维能力 |
| 第三方商业 TTS 代理 | 已有云厂商账号 | 服务端保存密钥,插件只调用统一代理地址 |
Edge TTS uniCloud 测试模板
模板位置:
uni_modules/lizhao-smart-tts/templates/uniCloud/cloudfunctions/edge-tts
使用步骤:
- 在 HBuilderX 中为项目创建或绑定 uniCloud 云空间。
- 把模板复制到项目根目录的
uniCloud/cloudfunctions/edge-tts。 - 在项目根
uniCloud视图中找到edge-tts,安装依赖并上传部署。 - 在 uniCloud 控制台开启云函数 URL 化。
- 把生成的 HTTPS 地址填入
cloud.endpoint。
插件提供的默认地址只用于测试,不应当作自己的长期生产服务:
https://env-00jxu7ha8amh.dev-hz.cloudbasefunction.cn/tts
CosyVoice Docker 服务
服务模板位置:
uni_modules/lizhao-smart-tts/static/server/cosyvoice-cloud-tts
启动示例:
cd uni_modules/lizhao-smart-tts/static/server/cosyvoice-cloud-tts
copy .env.example .env
powershell -ExecutionPolicy Bypass -File .\build-image.ps1
docker compose up -d
常用接口:
| 接口 | 作用 |
|---|---|
GET /health |
检查服务是否正常 |
GET /voices |
获取云端音色列表 |
POST /v1/tts |
合成语音并返回 audioUrl |
/audio/* |
访问已经生成的音频文件 |
真机不能通过 127.0.0.1 访问电脑上的服务。局域网测试时应改成电脑局域网 IP;正式环境应配置 HTTPS 域名,并确保返回的 audioUrl 能被 App 或小程序直接访问。
第三方商业 TTS 代理
服务端代理模板位置:
uni_modules/lizhao-smart-tts/static/server/commercial-tts-proxy
把云厂商密钥保存在代理服务中,再让业务统一请求自己的 cloud.endpoint。这样更换云厂商时,App 端调用方式不需要跟着改变。
常用 API 与配置
API 用途总览
| API | 作用 |
|---|---|
initTTS(options) |
初始化 TTS 运行时 |
speak(options) |
提交一条播报任务 |
pause(options) |
暂停当前播报 |
resume(options) |
继续已暂停的播报 |
stop(options) |
停止当前播报,可同时清空队列 |
getVoices(options) |
查询当前路线可以使用的音色 |
getCapabilities(options) |
查询当前平台和适配器能力 |
onTtsEvent(eventName, callback) |
订阅运行事件,推荐页面侧使用 |
offTtsEvent(eventName, callback) |
取消运行事件订阅 |
on(eventName, callback) |
onTtsEvent 的短名称别名 |
off(eventName, callback) |
offTtsEvent 的短名称别名 |
通用回调
异步 API 都支持以下回调:
| 回调 | 什么时候触发 |
|---|---|
success |
本次操作成功完成 |
fail |
参数、初始化、合成或播放失败 |
complete |
无论成功或失败都会触发 |
speak.success 表示整条播报任务已经完成,不只是进入了队列。发生失败时,建议同时记录 errCode、errMsg 和 details。
initTTS(options)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
lang |
string | 否 | zh-CN |
默认语言 |
rate |
number | 否 | 1.0 |
默认语速 |
pitch |
number | 否 | 1.0 |
默认音调 |
volume |
number | 否 | 1.0 |
默认音量,范围 0-1 |
timeout |
number | 否 | 30000 |
单阶段超时时间,单位毫秒 |
maxSegmentLength |
number | 否 | 120 |
长文本每段最大字符数 |
fallbackChain |
Array<string> | 否 | 按平台决定 | 路线顺序,可使用 native / web / offline-ai / cloud |
cloudOnly |
boolean | 否 | false |
是否强制只使用云端路线 |
scene |
string | 否 | 空 | 默认业务场景,如 novel / course / order |
voiceRole |
string | 否 | 空 | 默认云端角色标识 |
emotion |
string | 否 | 空 | 默认情绪标识 |
metadata |
any | 否 | 空 | 默认业务透传数据 |
offline |
SmartTtsOfflineOptions | 否 | 空 | 离线模型配置 |
cloud |
SmartTtsCloudOptions | 否 | 空 | 云端服务配置 |
success / fail / complete |
function | 否 | 无 | 通用回调 |
默认路线大致为:App 使用系统 TTS 后再考虑云端;Web 使用浏览器系统 TTS;Harmony 和小程序使用云端音频。Web 当前不会根据 cloud.endpoint 自动切换到云端。
speak(options)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
text |
string | 是 | 无 | 要播报的文字 |
taskId |
string | 否 | 自动生成 | 业务自定义任务 ID |
lang |
string | 否 | 继承初始化配置 | 本次播报语言 |
voiceName |
string | 否 | 继承初始化配置 | 系统、浏览器或云端音色名称 |
rate |
number | 否 | 继承初始化配置 | 语速 |
pitch |
number | 否 | 继承初始化配置 | 音调 |
volume |
number | 否 | 继承初始化配置 | 音量,范围 0-1 |
timeout |
number | 否 | 30000 |
等待开始或结束的单阶段超时,单位毫秒 |
priority |
number | 否 | 0 |
待播队列优先级 |
interrupt |
boolean | 否 | false |
是否打断当前任务 |
maxSegmentLength |
number | 否 | 继承初始化配置 | 本次长文本分段长度 |
fallbackChain |
Array<string> | 否 | 继承初始化配置 | 本次播报使用的路线顺序 |
cloudOnly |
boolean | 否 | 继承初始化配置 | 是否强制只使用云端路线 |
scene |
string | 否 | 继承初始化配置 | 业务场景,如 novel / news / course / order |
cacheKey |
string | 否 | 空 | 云端音频稳定缓存键 |
voiceRole |
string | 否 | 继承初始化配置 | 云端角色或音色路由标识 |
emotion |
string | 否 | 继承初始化配置 | 云端情绪标识 |
metadata |
any | 否 | 空 | 业务透传数据 |
offline |
SmartTtsOfflineOptions | 否 | 继承初始化配置 | 本次离线配置 |
cloud |
SmartTtsCloudOptions | 否 | 继承初始化配置 | 本次云端配置 |
success / fail / complete |
function | 否 | 无 | 通用回调 |
离线配置 SmartTtsOfflineOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
engine |
string | sherpa-onnx |
离线引擎名称 |
modelDir |
string | sherpa-onnx/zh-pro |
随基座打包的 assets 模型目录 |
modelPath |
string | 空 | 运行后下载模型的 Android 绝对目录,优先级高于 modelDir |
speakerId |
number | 0 |
多说话人模型的说话人编号 |
warmupText |
string | 空 | 初始化后用于预热的短文本 |
sampleRate |
number | 模型默认值 | 目标采样率 |
enableCache |
boolean | false |
是否缓存短句合成结果 |
云端配置 SmartTtsCloudOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
provider |
string | custom |
服务类型标识,如 custom / cosyvoice |
endpoint |
string | 空 | 云端合成接口地址 |
voicesEndpoint |
string | 自动推导 | 云端音色列表接口 |
method |
string | POST |
请求方法 |
headers |
object | 空 | 请求头,不要在前端放长期密钥 |
responseField |
string | audioUrl |
返回体中的音频地址字段 |
cache |
SmartTtsCloudCacheOptions | 空 | 插件端音频 URL 缓存配置 |
synthesize |
function | 空 | 自定义合成函数,可对接已有业务网关 |
cloud.synthesize 应返回可播放的音频地址或统一结果对象;异常会进入 fail 回调。
内置组件属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
text |
string | 空字符串 | 点击按钮时要播报的文字 |
options |
object | {} |
直接传给 initTTS() 和 speak() 的配置 |
buttonText |
string | 开始语音播报 |
按钮显示文字 |
disabled |
boolean | false |
是否禁用按钮 |
内置组件事件
| 事件 | 说明 |
|---|---|
ready |
TTS 初始化完成 |
start |
开始播报 |
progress |
播报进度变化 |
end |
播报结束 |
success |
本次组件播报成功完成 |
error |
初始化或播报失败 |
主要返回值
播报结果 SpeakResult
| 字段 | 类型 | 说明 |
|---|---|---|
taskId |
string | 播报任务 ID |
status |
string | 成功完成时为 completed |
adapter |
string | 实际使用的路线,如 native-android、offline-ai-android、cloud-audio-android |
cacheHit |
boolean | 是否命中云端或插件端缓存 |
audioUrl |
string | 云端音频地址 |
durationMs |
number | 音频时长,单位毫秒 |
provider |
string | 实际云端服务标识 |
voice |
string | 实际音色 |
segmentIndex / segmentCount |
number | 当前分段和总分段数 |
queueLength |
number | 当前待播队列长度 |
运行能力 SmartTtsCapabilities
| 字段 | 类型 | 说明 |
|---|---|---|
initialized |
boolean | 是否已经初始化 |
supported |
boolean | 当前路线是否可用 |
platform |
string | 当前平台 |
adapter |
string | 当前适配器 |
supportMatrix.offlineAi |
boolean | 当前是否支持离线 TTS |
supportMatrix.cloudAudio |
boolean | 当前是否支持云端音频 |
details.pauseMode |
string | 暂停语义,例如 Android 系统 TTS 的 restart-segment |
details.modelReady |
boolean | 离线模型是否已经准备好 |
运行事件
| 事件 | 说明 |
|---|---|
ready |
TTS 运行时已经就绪 |
start |
某个任务开始播报 |
progress |
播报分段或进度变化 |
end |
某个任务播报完成 |
error |
初始化、合成或播放失败 |
stateChanged |
运行状态变化 |
queueChanged |
待播队列发生变化 |
取消监听时,必须传入注册时的同一个回调函数。
错误码
| 错误码 | 含义 | 建议处理 |
|---|---|---|
9011001 |
当前平台没有可用路线 | 检查平台支持和 fallbackChain |
9011002 |
参数不合法 | 检查 text、cloud.endpoint 和数值范围 |
9011003 |
TTS 尚未初始化 | 先调用 initTTS(),并处理初始化失败 |
9011004 |
当前路线不支持该操作 | 查询 getCapabilities() 后隐藏不可用操作 |
9011005 |
运行过程失败 | 查看 details,检查浏览器、云端返回或音频播放 |
9011006 |
离线模型缺失 | 检查模型目录和必需文件 |
9011007 |
离线引擎初始化失败 | 检查 AAR/SO 是否进入当前基座,以及模型是否兼容 |
9011008 |
离线合成或播放失败 | 检查模型、文本和音频输出状态 |
完整示例
常见问题
第一次接入应该选择哪一种方式
先使用系统 TTS,也就是 fallbackChain: ['native']。它不需要服务器、模型或额外依赖。确认初始化和播报都成功后,再根据业务需要增加离线或云端路线。
Android 首次播报为什么弹出系统声明或条款
这是手机系统文字转语音引擎的行为,不是插件弹窗。同意系统条款后即可继续使用。不同品牌设备的界面可能不同。
Android 日志提示 textToSpeech init failed
通常是设备没有安装、启用或正确设置系统 TTS 引擎。进入系统的“文字转语音输出”设置,安装并选择可用引擎后重试。业务上也可以配置云端 TTS 作为回退路线。
Android 暂停后为什么从当前段落开头继续
Android 系统 TTS 没有真正的暂停接口。插件会停止当前分段,并在继续时从该分段开头重新播报。这是 restart-segment 的正常表现。
Web 指定音色为什么没有生效
先用 getVoices() 获取当前浏览器的音色列表,再把返回项的 name 传给 voiceName。不要把浏览器音色名称传给 voiceRole,后者只用于云端业务角色。
Ubuntu 音色列表中的 cmn / yue / hak 是什么
cmn 表示普通话,yue 表示粤语,hak 表示客家话。插件会把普通话 zh-* 尝试匹配到 cmn,把 zh-HK 尝试匹配到 yue。
Windows 是女声,Ubuntu 为什么变成男声
Web 音色由操作系统、浏览器和已经安装的语音引擎共同决定。插件会优先匹配同语言以及名称中带 Xiaoxiao / Jenny / Belinda / female / 女声 等标记的音色,但系统没有对应女声时只能使用可用音色。要求不同电脑声音一致时,应使用云端 TTS。
Ubuntu 把 v2v 读成“V 二 V”怎么办
Web 路线会把独立出现的 v2v 按 V to V 播报,不会替换普通数字 2。如果文本不是独立的 v2v,建议在业务侧按期望读法提供展示文本和播报文本。
能看到 Google 普通话音色,为什么一直没有声音
localService: false 表示该音色可能依赖浏览器在线语音服务。音色出现在列表中,不代表服务在当前网络一定可用。
排查顺序:
- 在站点设置中允许“声音”,它不是麦克风权限。
- 让用户第一次点击按钮时直接触发播报,不要在页面加载或无用户手势的定时器中自动播放。
- 确认标签页、系统音量和音频输出设备没有静音。
- 使用最新版 Chrome 或 Edge 测试。
- 打印完整失败对象和
[lizhao-smart-tts][Web]日志。
可以临时缩短超时时间,快速得到诊断结果:
speak({
text: '你好,这是普通话测试',
lang: 'zh-CN',
voiceName: 'Google 普通话(中国大陆)',
timeout: 10000,
fail(err) {
console.error('TTS 完整错误', err)
console.error('TTS 诊断详情', err.details)
}
})
details.browserError 为 voice-unavailable 表示目标语言音色不可用;speech-timeout 且 phase 为 waiting-start 表示浏览器没有开始播放;waiting-end 表示已经开始但没有在超时时间内结束。插件会取消静默挂起的任务,并触发 fail 和 complete。
发布到 Nginx 后还需要麦克风权限吗
不需要。浏览器系统 TTS 使用 window.speechSynthesis,不是录音功能。需要检查的是站点声音播放权限、用户手势和当前设备的浏览器音色。
购买插件后是否还需要云函数或服务器
只使用系统 TTS 时不需要。插件授权不包含 uniCloud 云空间、第三方 TTS 账号或持续运行的合成服务。只有固定音色、高音质、Harmony、小程序或跨设备一致等场景需要另外部署云端服务。
云端服务不限于 uniCloud,也可以使用自建 CosyVoice、商业 TTS 代理或其他能够返回 HTTPS audioUrl 的服务。
配置 cloud.endpoint 后,Web 会自动回退云端吗
不会。当前 Web 入口只使用浏览器 SpeechSynthesis,不会读取 cloud.endpoint。Web 需要云端声音时,应由业务层请求合成接口,拿到 HTTPS audioUrl 后使用 Web 音频播放器播放,并处理同源代理或 CORS。
Harmony 为什么查询不到系统音色
Harmony 当前走云端音频路线,不宣称支持系统原生 TTS 音色。请配置可访问的 cloud.endpoint,并确保返回的音频地址能在目标设备播放。
使用 offline-ai 为什么返回 9011006
默认插件包没有携带大体积离线模型。请确认已经准备 AAR/SO,并检查 modelDir 或 modelPath 指向的目录是否包含 .onnx、tokens.txt 以及 lexicon.txt 或 espeak-ng-data/。
下载模型后为什么仍然不能离线播报
模型文件可以在 App 运行后下载,AAR/SO 不可以。AAR/SO 必须在制作 Android 自定义基座之前放入插件目录,并参与原生联编。只更新 wgt 或 appResource 无法把原生运行库补进已有基座。
加入离线资源后是否需要重新制作 Android 自定义基座
加入或更换 AAR/SO 时必须重新制作并安装 Android 自定义基座。当前基座已经包含正确的 AAR/SO,仅替换运行后下载的模型文件时不需要重新制作。
云端接口已经返回成功,为什么还是播放失败
请确认返回体中的字段名与 cloud.responseField 一致,并且 audioUrl 是目标 App、小程序或浏览器可以直接访问的完整地址。真机不能访问电脑的 127.0.0.1;小程序还需要配置合法域名;正式环境建议使用 HTTPS。
Edge TTS 云函数出现 Unexpected server response: 403
通常是 Edge 在线接口握手参数发生变化,或者部署的云函数模板较旧。更新插件中的模板并重新上传部署,然后再次测试云函数日志和返回结果。
如何查看当前到底用了哪一种播报路线
调用 getCapabilities() 查看当前 adapter 和支持矩阵;播报成功后也可以查看 SpeakResult.adapter。例如 native-android 表示 Android 系统 TTS,offline-ai-android 表示 Android 离线模型,cloud-audio-android 表示 Android 云端音频路线。
注意事项
- 系统音色由设备决定,插件不能保证所有手机和电脑拥有相同声音。
- Web 首次发声最好由用户点击触发,避免浏览器自动播放策略拦截。
- 云端密钥、Token 和生产配置只能保存在服务端。
- 长文本应合理分段,并在页面销毁时取消事件监听。
- 只使用系统 TTS 或云端 TTS 时,不要额外加入 Sherpa-ONNX 大资源。
- 离线模型代码授权与模型授权需要分别确认。
- iOS 离线能力需要单独准备原生框架和模型;本文的离线资源步骤只适用于 Android。
联系方式
信-微:l-z-1-8-7-1512-5421(-去掉,不这样写会被和谐)
作者系列 UTS 插件
以下插件已在 DCloud 插件市场上架,可按业务需要组合使用。
| 插件 | 能力方向 | 插件市场 |
|---|---|---|
lizhao-nfc-pro |
NFC 标签读写、NDEF、IsoDep 与诊断 | 查看插件 |
lizhao-float-window |
悬浮窗、画中画、权限与诊断 | 查看插件 |
lizhao-device-id |
设备标识、隐私策略与诊断 | 查看插件 |
lizhao-scan-pro |
原生扫码、连续扫码、相册识别 | 查看插件 |
lizhao-choose-file |
原生文件选择、上传、进度与取消 | 查看插件 |
lizhao-bg-audio |
背景音频播放、队列、倍速与事件 | 查看插件 |
lizhao-smart-tts |
系统 TTS、云端合成、听书方案 | 查看插件 |
lizhao-share-plus |
系统分享、远程文件下载后分享 | 查看插件 |
lizhao-sqlite-pro |
原生 SQLite、迁移、备份与诊断 | 查看插件 |
lizhao-icon-pro |
SVG 图标组件、多主题与缓存 | 查看插件 |
lizhao-cast-screen |
DLNA 投屏、AirPlay 路由入口 | 查看插件 |
lizhao-call-kit |
电话、短信、通讯录原生能力 | 查看插件 |
lizhao-app-keepalive |
应用保活、唤醒、自愈与报告 | 查看插件 |
lizhao-doc-corrector |
文档扫描、矫正、增强与识别 | 查看插件 |
lizhao-emu-detect |
模拟器环境检测、风险评分与证据 | 查看插件 |
lizhao-gallery-pro |
相册媒体分页、筛选、缩略图与导出 | 查看插件 |
lizhao-video-thumb |
视频封面、批量取帧与 Base64 返回 | 查看插件 |
lizhao-ble |
BLE 扫描、连接、读写、通知与自动重连 | 查看插件 |
lizhao-sse-pro |
SSE、Line、JSONL 与 Raw 流式请求 | 查看插件 |
lizhao-pdf-pro |
PDF 阅读、签批、真实写回与页面处理 | 查看插件 |
lizhao-serial-port |
路径串口、USB 串口、多会话收发与诊断 | 查看插件 |
lizhao-wechat-kit |
微信登录、分享、支付、小程序与客服 | 查看插件 |
lizhao-video-editor |
视频裁剪、压缩、取帧与 FFmpeg/FFprobe | 查看插件 |
lizhao-vpn-pro |
企业 VPN、IKEv2、安全接入与脱敏诊断 | 查看插件 |

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 6486
赞赏 5
下载 12603070
赞赏 1949
赞赏
京公网安备:11010802035340号