更新记录

1.1.0(2026-07-04)

  • 新增 Android / iOS 双端系统音色列表查询与 voiceId 选音色能力
  • 优化 Android 初始化竞态处理,避免极端情况下初始化回调早到导致状态卡死
  • 优化 iOS 事件与初始化回调主线程分发,降低页面监听更新时的线程风险
  • 清理 iOS UTS 胶水层冗余转发代码,统一桥接结构
  • 调整插件元数据,正式声明支持 uni-app vue2 / vue3 App 工程
  • 完善 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 vue3 App 工程

  • Android 端基于系统 TextToSpeech

  • iOS 端基于系统 AVSpeechSynthesizer

  • 支持初始化、文本播报、队列追加、音色查询、音色选择、音调/语速/音量控制、状态查询和事件监听

适合需要“本地语音播报”的业务场景,例如扫码播报、设备状态提醒、窗口叫号、无障碍朗读、语音表单提示等。

插件亮点

  • 原生实现,直接调用系统 TTS,接入简单
  • 无需麦克风、相机、定位、存储等敏感权限
  • 支持 flush 立即播报和 add 队列追加两种模式
  • 支持 languagevoiceIdpitchspeechRatevolume
  • 支持查询系统可用音色,便于做男声/女声或发音人选择
  • 事件回调完整,支持监听 initstartdonestoperror
  • 内部已做单例资源管理、主线程事件分发和初始化竞态兜底,适合业务页长期复用

适用场景

  • 扫码结果自动播报
  • 医疗、政务、工厂等终端设备状态提示
  • 收银、排队、取号类语音通知
  • 智能硬件控制面板的语音反馈
  • 表单校验、老人模式、无障碍朗读
  • 需要“离线优先、系统级语音能力”的 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 vue2uni-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()
}

推荐调用顺序

  1. 调用 initTts() 初始化引擎
  2. 调用 onTtsEvent() 注册事件监听
  3. 如需选音色,调用 getTtsVoices() 获取当前系统可用音色
  4. 调用 speakTts() 开始播报
  5. 如需中断,调用 stopTts()
  6. 页面销毁或不再使用时调用 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-CNen-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' 会追加到当前队列尾部
  • languagevoiceIdpitchspeechRatevolume 仅对本次播报生效

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() 的音色 ID
  • voiceName:系统返回的音色名称
  • language:当前音色对应的语言标签
  • gender:根据系统音色名称推测出的提示值,常见为 malefemaleunknown
  • quality:Android 端 voice 质量等级;iOS 当前返回 null
  • latency:Android 端 voice 延迟等级;iOS 当前返回 null
  • requiresNetwork:是否依赖网络语音
  • 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 = falsenotInstalled = false 的本地音色
  • 用真机实际试听,不要只看 voice 名称

2. 为什么 initTts() 成功了,但 speakTts() 还是失败?

常见原因:

  • 刚初始化完成后立即切换了不支持的 voiceId
  • 当前语言或音色在系统引擎中不可用
  • 页面被销毁后还在继续调用旧实例

建议查看返回的 errCodeerrMsg,并结合 getTtsState() 判断当前状态。

3. 为什么 getTtsVoices() 返回为空?

常见原因:

  • 当前 TTS 引擎未初始化完成
  • 系统 TTS 能力异常或未安装完整语音包
  • 非 App 平台调用

建议在 initTts() 成功后再调用 getTtsVoices()

4. 支持暂停 / 继续吗?

当前版本不提供暂停 / 继续能力,如需中断请使用 stopTts()

5. 适合同时创建多套独立 TTS 会话吗?

不适合。插件内部采用单例管理模式,推荐在一个 App 进程内复用同一套 TTS 引擎。

注意事项

  • Android 依赖系统自带或用户已安装的 TTS 引擎
  • Android 和 iOS 的音色都来自系统 TTS 引擎,不同设备返回结果会有差异
  • 插件采用单例管理模式,不适合同一时刻维护多套独立 TTS 会话
  • 建议在页面卸载时调用 offTtsEvent()releaseTts() 清理监听和资源
  • 如果你的业务需要固定某个发音人,请在目标机型上先验收对应 voiceId

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无额外系统权限 本插件仅调用系统 TTS(文字转语音)能力进行语音播报,不涉及麦克风、相机、相册、定位、通讯录、文件存储等敏感权限。 Android 依赖系统已安装的 TTS 引擎;iOS 基于 AVSpeechSynthesizer 实现。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。