uni.getSystemInfoSync().platform 必须为"ios"或"android"才支持TTS,H5端不可用;应使用uni.startSpeek()而非Web Speech API,注意平台语言码差异、rate范围及text纯文本要求。

uni-app 里 uni.getSystemInfoSync() 返回的 platform 值决定 TTS 可用性
iOS 和 Android 对 Web Speech API 支持极差,uni-app 的 H5 端基本没法用 SpeechSynthesis;真机必须走原生层。所以第一步不是写播放逻辑,而是确认当前环境能否调用系统 TTS——uni.getSystemInfoSync().platform 必须是 "ios" 或 "android",H5 端直接放弃。
常见错误现象:uni.createInnerAudioContext() 播放空文件、静音、或报 "createInnerAudioContext:fail not support",本质是误把 TTS 当成普通音频加载。
- Android 端依赖系统已安装 TTS 引擎(如 Google TTS),若用户没装或未启用,默认语音可能无声
- iOS 13+ 原生支持,但需在
manifest.json中勾选「语音合成(TTS)」权限,否则uni.startSpeek()静默失败 - 调试时别只看模拟器——iOS 模拟器不支持 TTS,Android 模拟器多数也不支持,必须真机测试
用 uni.startSpeek() 而不是自己封装 Web Speech API
uni-app 官方在 3.90+ 版本提供了 uni.startSpeek()(注意拼写是 Speek,不是 Speak),这是目前最稳的跨端方案。它底层自动桥接 iOS 的 AVSpeechSynthesizer 和 Android 的 TextToSpeech 类,不用写原生插件。
参数差异很关键:lang 不是 BCP-47 标准(如 "zh-CN"),而是平台约定值:
- iOS:用
"zh-CN"、"en-US"等,大小写敏感 - Android:部分旧机型只认
"zh"、"en",建议 fallback 到两字符语言码 -
rate范围是 0.5–2.0,但 Android 实际生效区间常为 0.6–1.8,设 2.0 可能卡顿或跳字 - 必须传
text字符串,不能是 HTML 标签或富文本,"<b>你好</b>"会被逐字读出来
示例:
uni.startSpeek({
text: '订单已提交成功',
lang: uni.getSystemInfoSync().platform === 'ios' ? 'zh-CN' : 'zh',
rate: 1.0,
success: () => console.log('开始朗读'),
fail: (err) => console.error('朗读失败', err)
});
uni.pauseSpeek() 和 uni.stopSpeek() 行为差异大
这两个 API 看似相似,但底层机制完全不同,容易误用导致状态混乱。
-
uni.pauseSpeek():仅 iOS 支持,Android 调用无反应(不报错也不暂停);暂停后可调用uni.resumeSpeek()继续 -
uni.stopSpeek():全平台支持,但会彻底终止当前语音任务,再调用startSpeek()是全新一轮,无法“从中断处继续” - 没有“获取当前朗读进度”的 API,所以无法做精准暂停/恢复,适合场景只有:全局静音(stop)、或 iOS 用户手动控制播放节奏(pause/resume)
- 连续快速调用
startSpeek()多次,旧任务不会自动 cancel,可能堆积并发语音,建议每次前先uni.stopSpeek()
Android 上 TTS 初始化失败的典型表现和绕过方式
Android 端首次调用 uni.startSpeek() 时,如果系统 TTS 引擎未就绪,会出现延迟数秒、静音、或直接 fail 回调且 err.errMsg 为空字符串——这是最隐蔽的坑。
根本原因是 Android 的 TextToSpeech 是异步初始化的,uni-app 封装层没暴露初始化状态监听。可行的绕过方式:
- 提前在页面
onLoad里调一次空文本朗读(如text: ' '),触发初始化,后续正式朗读更可靠 - 加个简单重试:
fail后延时 300ms 再试一次,成功率明显提升 - 检测是否支持:调用
uni.getProvider({service: 'speech'}),返回{service: "speech", provider: ["tts"]}才代表可用;H5 端该接口返回空数组 - 不要依赖
onReady或mounted时机,TTS 就绪和 Vue 生命周期无关
复杂点在于:TTS 引擎本身可被用户关闭、更换、甚至卸载,运行时状态不可靠。上线后要埋点记录 fail 频次,而不是假设“一次配好就永远行”。

















