更新记录
1.0.0(2026-06-16) 下载此版本
第一次上传
平台兼容性
uni-app
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(5.07)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | √ | √ | 1.0.0 | - |
apex-gu-cheng-tts 操作说明
跨平台 TTS(Text-to-Speech)语音合成 UTS 模块,支持 Android、iOS 和 HarmonyOS。
目录
快速开始
导入
import {
ttsInit,
ttsSpeak,
ttsStop,
ttsIsSpeaking,
} from '@/uni_modules/apex-gu-cheng-tts'
最小示例
// 1. 初始化
ttsInit({
language: 'zh-CN',
success: () => console.log('就绪'),
fail: (err) => console.error('初始化失败', err.errMsg),
})
// 2. 朗读
ttsSpeak({
text: '你好,世界',
success: () => console.log('开始朗读'),
fail: (err) => console.error('朗读失败', err.errMsg),
})
// 3. 停止
ttsStop({
success: () => console.log('已停止'),
})
// 4. 查询状态
if (ttsIsSpeaking()) {
console.log('正在朗读中...')
}
API 参考
ttsInit(options)
初始化 TTS 引擎。必须先调用此方法,后续的 ttsSpeak / ttsStop 才可用。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
rate |
number |
否 | 1.0 |
语速,范围 0.5 ~ 2.0 |
pitch |
number |
否 | 1.0 |
音调,范围 0.5 ~ 2.0 |
volume |
number |
否 | 1.0 |
音量,范围 0.0 ~ 1.0 |
language |
string |
否 | 'zh-CN' |
语言代码 |
success |
(res: TTSInitResult) => void |
否 | — | 初始化成功回调 |
fail |
(res: TTSFail) => void |
否 | — | 初始化失败回调 |
complete |
(res: any) => void |
否 | — | 完成回调(成功/失败都会触发) |
注意:重复调用
ttsInit会自动销毁旧引擎再创建新的(Android / HarmonyOS 平台)。
ttsSpeak(options)
朗读指定文本。调用前需确保 TTS 已初始化成功。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
text |
string |
是 | — | 要朗读的文本内容 |
speed |
number |
否 | 1.0 |
语速,范围 0.5 ~ 2.0 |
pitch |
number |
否 | 1.0 |
音调,范围 0.5 ~ 2.0 |
volume |
number |
否 | 1.0 |
音量,范围 0.0 ~ 1.0 |
language |
string |
否 | 'zh-CN' |
语言代码 |
success |
(res: TTSSpeakResult) => void |
否 | — | 提交成功回调 |
fail |
(res: TTSFail) => void |
否 | — | 朗读失败回调 |
complete |
(res: any) => void |
否 | — | 完成回调 |
注意:
success仅表示朗读请求已提交到引擎,不代表朗读已结束。朗读是否完成需通过轮询ttsIsSpeaking()判断。
ttsStop(options)
立即停止当前朗读。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
success |
(res: TTSStopResult) => void |
否 | 停止成功回调 |
fail |
(res: TTSFail) => void |
否 | 停止失败回调 |
complete |
(res: any) => void |
否 | 完成回调 |
ttsIsSpeaking()
同步查询当前是否正在朗读。
- 返回值:
boolean true— 正在朗读中false— 空闲状态
ttsShutdown() (平台内部方法)
停止朗读并释放 TTS 引擎资源。Android / iOS / HarmonyOS 平台均有导出,可用于页面销毁时清理。
// 页面 onUnload 时清理
export function ttsShutdown(): void
类型定义
TTSInitResult
type TTSInitResult = {
success: boolean // 是否初始化成功
message: string // 描述信息
}
TTSSpeakResult
type TTSSpeakResult = {
success: boolean // 是否成功提交朗读请求
message: string // 描述信息
}
TTSStopResult
type TTSStopResult = {
success: boolean // 是否停止成功
message: string // 描述信息
}
TTSFail
interface TTSFail extends IUniError {
errCode: TTSErrorCode // 错误码
errMsg: string // 错误描述
}
错误码
| 错误码 | 常量含义 | 说明 |
|---|---|---|
9020001 |
初始化失败 | 引擎创建失败,可能设备不支持 TTS |
9020002 |
朗读失败 | 提交朗读请求时出错 |
9020003 |
停止失败 | 停止朗读时出错 |
9020004 |
未初始化 | 在 TTS 未就绪时调用了 speak 或 stop |
平台差异
Android
- 底层使用系统
android.speech.tts.TextToSpeechAPI - 语言解析支持
语言-地区格式(如zh-CN、en-US、ja-JP) ttsIsSpeaking()直接调用TextToSpeech.isSpeaking(),实时准确- 需要 Activity 上下文,请确保在 uni-app 页面生命周期内初始化
iOS
- 底层使用
AVFoundation.AVSpeechSynthesizer - 语速映射:接口
speed范围0.5~2.0,映射到 iOS 原生rate范围0.0~1.0,公式:iosRate = speed × 0.5 - 音调使用
pitchMultiplier,范围与接口一致(0.5~2.0) - 初始化是同步的,不会失败(除非内存不足)
ttsIsSpeaking()通过synthesizer.isSpeaking属性获取
HarmonyOS
- 底层使用
@kit.CoreSpeechKit的textToSpeechAPI - 需要在线模式(
online: 1),需设备联网 - 引擎创建是异步的(
createEngine返回 Promise) - 支持完整的播报生命周期回调:
onStart、onComplete、onStop、onError ttsIsSpeaking()通过内部标志位维护,非原生查询
完整示例
以下示例来自 pages/index/index.uvue,展示了完整的 TTS 使用流程:
1. 页面初始化时启动 TTS
import { ref } from 'vue'
import { ttsInit, ttsSpeak, ttsStop, ttsIsSpeaking } from '@/uni_modules/apex-gu-cheng-tts'
const ttsReady = ref(false)
const speaking = ref(false)
ttsInit({
rate: 1.0,
pitch: 1.0,
volume: 1.0,
language: 'zh-CN',
success: (res) => {
ttsReady.value = true
console.log('TTS初始化成功')
},
fail: (err) => {
console.error('TTS初始化失败: ' + err.errMsg)
},
})
2. 朗读文本(含轮询完成检测)
const textContent = ref('你好,欢迎使用TTS语音合成测试功能')
const curLang = ref('zh-CN')
const speed = ref(1.0)
const pitch = ref(1.0)
const volume = ref(1.0)
let pollTimer: number = 0
function handleSpeak(): void {
const txt = textContent.value.trim()
if (txt.length === 0) return
ttsSpeak({
text: txt,
speed: speed.value,
pitch: pitch.value,
volume: volume.value,
language: curLang.value,
success: (res) => {
speaking.value = true
},
fail: (err) => {
console.error('朗读失败: ' + err.errMsg)
},
complete: () => {
// 轮询检测朗读是否结束
pollTimer = setInterval(() => {
if (!ttsIsSpeaking()) {
speaking.value = false
console.log('朗读完成')
clearInterval(pollTimer)
}
}, 300)
// 30 秒超时保护
setTimeout(() => {
clearInterval(pollTimer)
}, 30000)
},
})
}
3. 停止朗读
function handleStop(): void {
ttsStop({
success: () => {
speaking.value = false
console.log('已停止朗读')
},
fail: (err) => {
console.error('停止失败: ' + err.errMsg)
},
})
}
4. 页面销毁时清理
// 在页面 onUnload 中调用
import { ttsShutdown } from '@/uni_modules/apex-gu-cheng-tts'
// 如果需要在页面销毁时释放引擎资源
// ttsShutdown()
注意事项
-
初始化顺序:必须先调用
ttsInit并等待success回调后,才能调用ttsSpeak/ttsStop,否则会收到9020004(未初始化)错误。 -
朗读完成检测:
ttsSpeak的success回调仅表示请求已提交。判断朗读是否真正结束,需要通过轮询ttsIsSpeaking()实现,建议间隔 300ms,并设置超时保护(如 30 秒)。 -
语言代码格式:使用 BCP-47 格式,常见值: 语言 代码 中文(简体) zh-CN英文(美国) en-US日文 ja-JP -
参数范围: 参数 范围 默认值 说明 语速 (speed/rate) 0.5 ~ 2.0 1.0 1.0 = 正常语速 音调 (pitch) 0.5 ~ 2.0 1.0 1.0 = 正常音调 音量 (volume) 0.0 ~ 1.0 1.0 0.0 = 静音,1.0 = 最大 -
HarmonyOS 平台需要网络连接(使用在线 TTS 服务),Android 和 iOS 使用本地引擎,可离线使用。
-
Android 平台重复调用
ttsInit会自动关闭旧引擎;如果需要在页面切换时彻底释放资源,可调用ttsShutdown()。 -
线程安全:所有 TTS 操作应在主线程调用,UTS 模块内部未做线程调度。
-
正常调用模板
<template> <view class="page-container"> <NavBar title="TTS测试" :showBack="true" /> <scroll-view scroll-y class="scroll-content"> <view class="content-wrapper"> <!-- 状态指示 --> <view class="status-bar"> <view class="status-item"> <view class="status-dot" :class="ttsReady ? 'dot-green' : 'dot-red'" /> <text class="status-text">{{ ttsReady ? 'TTS已就绪' : 'TTS未就绪' }}</text> </view> <view class="status-item"> <view class="status-dot" :class="speaking ? 'dot-blue' : 'dot-gray'" /> <text class="status-text">{{ speaking ? '正在朗读' : '空闲' }}</text> </view> </view> <!-- 文本输入 --> <view class="section"> <text class="section-label">朗读文本</text> <textarea v-model="textContent" class="text-input" placeholder="输入要朗读的文字..." :maxlength="500" /> </view> <!-- 语言选择 --> <view class="section"> <text class="section-label">语言</text> <view class="lang-group"> <view v-for="lang in langList" :key="lang.value" class="lang-chip" :class="curLang === lang.value ? 'lang-chip-active' : ''" @click="curLang = (lang.value as string)" > <text class="lang-chip-text">{{ lang.label }}</text> </view> </view> </view> <!-- 参数滑块 --> <view class="section"> <text class="section-label">语速: {{ speed.toFixed(1) }}</text> <slider class="param-slider" :value="speed" :min="0.5" :max="2.0" :step="0.1" @change="onSpeedChange" /> </view> <view class="section"> <text class="section-label">音调: {{ pitch.toFixed(1) }}</text> <slider class="param-slider" :value="pitch" :min="0.5" :max="2.0" :step="0.1" @change="onPitchChange" /> </view> <view class="section"> <text class="section-label">音量: {{ volume.toFixed(1) }}</text> <slider class="param-slider" :value="volume" :min="0.0" :max="1.0" :step="0.1" @change="" /> </view> <!-- 操作按钮 --> <view class="btn-group"> <button class="btn-speak" :class="!ttsReady ? 'btn-disabled' : ''" :disabled="!ttsReady" @click="handleSpeak"> 朗读 </button> <button class="btn-stop" :class="!ttsReady ? 'btn-disabled' : ''" :disabled="!ttsReady" @click="handleStop"> 停止 </button> </view> <!-- 快捷文本 --> <view class="section"> <text class="section-label">快捷文本</text> <view class="quick-group"> <view v-for="qt in quickTexts" :key="qt" class="quick-chip" @click="textContent = qt" > <text class="quick-chip-text">{{ qt }}</text> </view> </view> </view> <!-- 日志 --> <view class="section"> <text class="section-label">运行日志</text> <view class="log-box"> <text v-for="(log, i) in logs" :key="i" class="log-line" >{{ log }}</text> <text v-if="logs.length === 0" class="log-empty">暂无日志</text> </view> </view> <view class="bottom-space" /> </view> </scroll-view> </view> </template>

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 7
赞赏 0
下载 12267886
赞赏 1922
赞赏
京公网安备:11010802035340号