更新记录
1.1.0(2026-07-04)
- 新增 Android / iOS 双端系统音色列表查询与
voiceId选音色能力 - 优化 Android 初始化竞态处理,避免极端情况下初始化回调早到导致状态卡死
- 优化 iOS 事件与初始化回调主线程分发,降低页面监听更新时的线程风险
- 清理 iOS UTS 胶水层冗余转发代码,统一桥接结构
- 调整插件元数据,正式声明支持
uni-app vue2/vue3App 工程 - 完善 README、错误码、音色说明和插件市场使用文档
平台兼容性
uni-app(4.0)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-vue插件版本 | app-nvue | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.1.0 | √ | 1.1.0 | × | × | √ | 1.1.0 | - | 5.0 | 1.1.0 | 12 | 1.1.0 | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
yzj-tts
yzj-tts 是一个面向 uni-app 的原生 TTS UTS 插件,提供稳定、轻量、无额外敏感权限的系统语音播报能力。
-
适用于
uni-app vue2/uni-app vue3App 工程 -
Android 端基于系统
TextToSpeech -
iOS 端基于系统
AVSpeechSynthesizer -
支持初始化、文本播报、队列追加、音色查询、音色选择、音调/语速/音量控制、状态查询和事件监听
适合需要“本地语音播报”的业务场景,例如扫码播报、设备状态提醒、窗口叫号、无障碍朗读、语音表单提示等。
插件亮点
- 原生实现,直接调用系统 TTS,接入简单
- 无需麦克风、相机、定位、存储等敏感权限
- 支持
flush立即播报和add队列追加两种模式 - 支持
language、voiceId、pitch、speechRate、volume - 支持查询系统可用音色,便于做男声/女声或发音人选择
- 事件回调完整,支持监听
init、start、done、stop、error - 内部已做单例资源管理、主线程事件分发和初始化竞态兜底,适合业务页长期复用
适用场景
- 扫码结果自动播报
- 医疗、政务、工厂等终端设备状态提示
- 收银、排队、取号类语音通知
- 智能硬件控制面板的语音反馈
- 表单校验、老人模式、无障碍朗读
- 需要“离线优先、系统级语音能力”的 App 场景
支持平台
| 平台 | 支持情况 |
|---|---|
App-Android |
支持,Android 21+ |
App-iOS |
支持,iOS 12.0+ |
H5 |
不支持 |
小程序 |
不支持 |
非 App 平台调用时会返回 9031002。
兼容性说明
| 类型 | 支持情况 |
|---|---|
uni-app vue2 |
支持 |
uni-app vue3 |
支持 |
nvue |
不支持 |
H5 |
不支持 |
小程序 |
不支持 |
说明:
- 本插件是纯 API 型 UTS 插件,不提供页面组件,也不依赖
vue3独占的组合式组件能力 - 插件主要运行在原生 Android / iOS 层,因此可用于
uni-app vue2和uni-app vue3的 App 项目调用 - 当前不支持
nvue
效果说明
本插件调用的是系统自带或系统可用的 TTS 引擎,因此最终播报效果取决于以下因素:
- 手机品牌和系统版本
- 系统当前启用的 TTS 引擎
- 是否安装了对应语言的语音包
- 当前音色是否依赖网络
- 厂商是否提供了多个真正不同的人声
这意味着:
- 同样的代码,在不同 Android 设备上音色数量和效果可能不同
- 某些 Android 设备虽然返回多个音色,但听感可能非常接近
- iOS 音色通常更稳定,但仍受系统语言包影响
如果业务需要“固定某个男声/女声”,建议先调用 getTtsVoices() 获取当前设备实际可用音色,再让用户选择或在你的业务里做映射。
快速开始
import {
getTtsVoices,
initTts,
offTtsEvent,
onTtsEvent,
releaseTts,
speakTts,
stopTts
} from '@/uni_modules/yzj-tts'
let ttsListenerId: number | null = null
export async function startTtsDemo() {
if (ttsListenerId == null) {
ttsListenerId = onTtsEvent((event) => {
console.log('[tts:event]', event)
})
}
const initResult = await initTts({
language: 'zh-CN',
pitch: 1,
speechRate: 1,
volume: 1
})
console.log('[tts:init]', initResult)
const voices = getTtsVoices()
console.log('[tts:voices]', voices)
const selectedVoiceId = voices.length > 0 ? voices[0].voiceId : ''
const speakResult = await speakTts({
text: '你好,这是第一段播报',
queueMode: 'flush',
voiceId: selectedVoiceId
})
console.log('[tts:speak]', speakResult)
}
export async function stopTtsDemo() {
await stopTts()
}
export function destroyTtsDemo() {
if (ttsListenerId != null) {
offTtsEvent(ttsListenerId)
ttsListenerId = null
}
releaseTts()
}
推荐调用顺序
- 调用
initTts()初始化引擎 - 调用
onTtsEvent()注册事件监听 - 如需选音色,调用
getTtsVoices()获取当前系统可用音色 - 调用
speakTts()开始播报 - 如需中断,调用
stopTts() - 页面销毁或不再使用时调用
offTtsEvent()/releaseTts()
API
initTts
初始化 TTS 引擎。
initTts(options?: {
language?: string
voiceId?: string
pitch?: number
speechRate?: number
volume?: number
}): Promise<{
ok: boolean
errCode: number | null
errMsg: string | null
initialized: boolean
language: string | null
voiceId: string | null
voiceName: string | null
pitch: number
speechRate: number
volume: number
enginePackage: string | null
timestamp: number
}>
| 参数 | 含义 | 默认值 | 说明 |
|---|---|---|---|
language |
语言标签 | 系统默认语言 | 建议使用 BCP-47 格式,如 zh-CN、en-US |
voiceId |
音色 ID | 空字符串 | 传空字符串时跟随系统当前默认音色 |
pitch |
音调倍率 | 1 |
必须大于 0,建议 0.5 ~ 2.0 |
speechRate |
语速倍率 | 1 |
必须大于 0,建议 0.5 ~ 2.0 |
volume |
音量 | 1 |
取值范围 0 ~ 1,超出会自动裁剪 |
补充说明:
- Android 端依赖系统 TTS 引擎和语音包是否支持该语言
- iOS 端会优先匹配你传入的
voiceId,未传时再按language选择 voice - Android 端建议在
initTts()成功后再调用getTtsVoices(),这样可以拿到当前引擎返回的完整音色列表
speakTts
提交一段文本进行播报。
speakTts(options: {
text: string
utteranceId?: string
queueMode?: 'flush' | 'add'
language?: string
voiceId?: string
pitch?: number
speechRate?: number
volume?: number
onStart?: (event) => void
onDone?: (event) => void
onStop?: (event) => void
onError?: (event) => void
}): Promise<{
ok: boolean
errCode: number | null
errMsg: string | null
accepted: boolean
utteranceId: string
queueMode: 'flush' | 'add'
text: string
timestamp: number
}>
text不能为空queueMode: 'flush'会打断当前播报并立即播放新文本queueMode: 'add'会追加到当前队列尾部language、voiceId、pitch、speechRate、volume仅对本次播报生效
stopTts
停止当前播报。
stopTts(): Promise<{
ok: boolean
errCode: number | null
errMsg: string | null
stopped: boolean
timestamp: number
}>
getTtsState
获取当前状态。
getTtsState(): {
initialized: boolean
speaking: boolean
language: string | null
voiceId: string | null
voiceName: string | null
pitch: number
speechRate: number
volume: number
enginePackage: string | null
lastUtteranceId: string | null
}
getTtsVoices
获取当前系统 TTS 引擎可用的音色列表。
getTtsVoices(): Array<{
voiceId: string
voiceName: string
language: string | null
gender: string
quality: number | null
latency: number | null
requiresNetwork: boolean
notInstalled: boolean
featuresText: string | null
selected: boolean
}>
字段说明:
voiceId:传给initTts()/speakTts()的音色 IDvoiceName:系统返回的音色名称language:当前音色对应的语言标签gender:根据系统音色名称推测出的提示值,常见为male、female、unknownquality:Android 端 voice 质量等级;iOS 当前返回nulllatency:Android 端 voice 延迟等级;iOS 当前返回nullrequiresNetwork:是否依赖网络语音notInstalled:当前语音包是否未安装featuresText:Android 端 voice features 的拼接文本selected:当前是否为已选中音色
onTtsEvent
注册插件级事件监听。
onTtsEvent(listener: (event: {
type: 'init' | 'start' | 'done' | 'stop' | 'error'
utteranceId: string | null
errCode: number | null
errMsg: string | null
timestamp: number
}) => void): number
offTtsEvent
取消事件监听。
offTtsEvent(listenerId?: number): void
- 传
listenerId:移除指定监听器 - 不传参数:清空全部监听器
releaseTts
释放 TTS 引擎和监听器。
releaseTts(): void
事件说明
| 事件 | 说明 |
|---|---|
init |
初始化成功 |
start |
开始播报 |
done |
当前播报完成 |
stop |
当前播报被停止 |
error |
初始化或播报失败 |
错误码
| 错误码 | 含义 |
|---|---|
9031001 |
当前页面上下文不可用,无法初始化 TTS |
9031002 |
当前平台暂不支持当前 TTS 插件 |
9031003 |
初始化 TTS 失败 |
9031004 |
TTS 引擎尚未初始化完成 |
9031005 |
TTS 参数非法 |
9031006 |
当前语言在系统 TTS 引擎中不可用 |
9031007 |
提交语音合成任务失败 |
9031008 |
停止语音播放失败 |
9031009 |
指定的 TTS 音色不存在或当前系统不可用 |
9031099 |
未知 TTS 错误 |
FAQ
1. 为什么切了多个音色,听起来还是差不多?
这通常不是插件切换失败,而是系统 TTS 引擎本身提供的多个 voice 听感很接近。尤其在部分 Android 设备上,很多 voice 更像“同一发音人的不同变体”,而不是真正不同的男声/女声。
建议:
- 先调用
getTtsVoices()查看当前设备实际返回的音色列表 - 优先选择
requiresNetwork = false、notInstalled = false的本地音色 - 用真机实际试听,不要只看 voice 名称
2. 为什么 initTts() 成功了,但 speakTts() 还是失败?
常见原因:
- 刚初始化完成后立即切换了不支持的
voiceId - 当前语言或音色在系统引擎中不可用
- 页面被销毁后还在继续调用旧实例
建议查看返回的 errCode 和 errMsg,并结合 getTtsState() 判断当前状态。
3. 为什么 getTtsVoices() 返回为空?
常见原因:
- 当前 TTS 引擎未初始化完成
- 系统 TTS 能力异常或未安装完整语音包
- 非 App 平台调用
建议在 initTts() 成功后再调用 getTtsVoices()。
4. 支持暂停 / 继续吗?
当前版本不提供暂停 / 继续能力,如需中断请使用 stopTts()。
5. 适合同时创建多套独立 TTS 会话吗?
不适合。插件内部采用单例管理模式,推荐在一个 App 进程内复用同一套 TTS 引擎。
注意事项
- Android 依赖系统自带或用户已安装的 TTS 引擎
- Android 和 iOS 的音色都来自系统 TTS 引擎,不同设备返回结果会有差异
- 插件采用单例管理模式,不适合同一时刻维护多套独立 TTS 会话
- 建议在页面卸载时调用
offTtsEvent()或releaseTts()清理监听和资源 - 如果你的业务需要固定某个发音人,请在目标机型上先验收对应
voiceId

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 7
赞赏 0
下载 12388281
赞赏 1928
赞赏
京公网安备:11010802035340号