更新记录

1.0.0(2026-09-07)

  • 首次发布
  • 支持离线语音合成(内置度小宇/度小美/度逍遥/度丫丫 4 个发音人模型)
  • 支持在线语音合成(永久 iamKey 鉴权)
  • 支持 speak/synthesize/pause/resume/stop/release 完整控制接口
  • 支持合成事件回调:开始/进度/音频数据/完成/错误
  • 支持引擎与模型信息查询(getTTSInfo)

平台兼容性

uni-app(4.27)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× × 6.0 × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × - × ×

uni-app x(3.8.5)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 6.0 × - -

zy-baidutts 百度离线语音合成

基于百度语音合成 Android SDK 6.4.0(tts_1.0.3-9c93a23)封装的 UTS 插件(原生混编实现),支持纯离线语音合成在线语音合成,内置 4 个离线发音人模型,无需联网即可完成语音播报。

功能特性

  • 离线合成:插件内置 4 个发音人声学模型 + 中文文本模型,首次启动自动复制到应用私有目录,断网可用
  • 在线合成:支持永久 iamKey 鉴权,一次配置长期使用
  • 混合模式(mix):离线引擎与在线引擎同时加载,单次合成可指定模式
  • 完整控制:speak(合成并播放)、synthesize(仅合成不播放)、pause(暂停)、resume(继续)、stop(停止)、release(释放资源)
  • 按次切换发音人:单次合成可临时指定发音人,无需重新初始化
  • 单次合成参数:语速/音量/音调可按次覆盖
  • 音频数据回调:可获取合成音频(16K 16bits 单声道 PCM 的 Base64),用于保存文件或自定义播放
  • 事件回调:合成开始、合成数据、播放进度、播放完成、错误等全流程事件

平台支持

平台 支持
Android ✔(minSdkVersion 21,Android 5.0+)
iOS
Web / 小程序 / Harmony

环境要求

  • HBuilderX 4.27 及以上版本(回调 keepAlive 特性依赖 4.27+)
  • uni-app 项目(vue2 / vue3 均可)
  • 必须打云端自定义基座:插件包含三方原生 SDK(AAR 约 10MB)与离线模型(约 55MB),标准基座不包含,本地标准基座运行无法生效

集成方式

  1. 将插件放入项目 uni_modules 目录(或通过插件市场导入)
  2. 在 HBuilderX 中选择「运行 → 运行到手机或模拟器 → 制作自定义调试基座」或「发行 → 原生 App-云打包」,勾选自定义基座
  3. 代码中导入使用:
import { initTTS, speak, synthesize, pauseTTS, resumeTTS, stopTTS, releaseTTS, getTTSInfo } from "@/uni_modules/zy-baidutts";

快速上手

import { initTTS, speak } from "@/uni_modules/zy-baidutts";

// 1. 初始化引擎(离线模式需要 appId + 序列号 SN)
initTTS({
  mode: "offline",
  appId: "您的AppId",
  authSn: "您的序列号SN",
  speaker: "duxiaomei",
  speed: "5",
  enableLog: false,
  success: (res) => {
    console.log("初始化成功,引擎版本=" + res.engineVersion);
    console.log("文本模型:" + res.textModelPath);
    console.log("声学模型:" + res.speechModelPath);
  },
  fail: (err) => {
    console.log("初始化失败:" + err.errMsg + " (errCode=" + err.errCode + ")");
  }
});

// 2. 合成并播放
speak({
  text: "你好,世界",
  onStart: (res) => {
    console.log("合成开始,utteranceId=" + res.utteranceId);
  },
  : (res) => {
    console.log("播放进度:" + res.progress + "%");
  },
  onFinish: (res) => {
    console.log("播放完成,engineType=" + (res.engineType === 0 ? "在线" : "离线"));
  },
  onError: (res) => {
    console.log("合成出错:" + res.errorMessage);
  }
});

鉴权说明

模式 鉴权要求 说明
offline appId + authSn(序列号 SN) 需在百度智能云控制台领取离线合成资源并购买/申请序列号。appId、应用包名、SN 三者必须与控制台登记完全一致,否则报 -102/-109 授权错误。首次联网自动下载授权文件
online iamKey(永久授权 key) 使用官网申请的永久 iamKey,每次启动 App 激活一次
mix 两者都需要 离线引擎与在线引擎分别鉴权

内置离线模型

插件 utssdk/app-android/assets/ 目录内置以下模型(共约 55MB),首次初始化自动复制到应用私有目录 filesDir/tts_models/(只复制一次,之后直接使用):

发音人标识 说明 模型文件 大小
duxiaomei 度小美(普通女声,默认 bd_etts_common_speech_duxiaomei_mand_eng_high_am-tac-csubgan16k_v4.9.0_20240918_20251031153737.dat 10.7MB
duxiaoyu 度小宇(成熟男声) bd_etts_common_speech_duxiaoyu_mand_eng_high_am-tac-csubgan16k_v4.9.0_20240918_20251031153737.dat 10.3MB
duxiaoyao 度逍遥(情感男声) bd_etts_common_speech_duxiaoyao_mand_eng_high_am-tac-csubgan16k_v4.9.0_20251110_20251210203318.dat 10.3MB
duyaya 度丫丫(可爱女童) bd_etts_common_speech_duyaya_mand_eng_high_am-tac-csubgan16k_v4.9.0_20220419_20251031153737.dat 8.3MB

中文文本模型(所有发音人共用):bd_etts_common_text_txt_all_mand_eng_middle_big_v6.0.0_20240731.dat(15.5MB)

如需替换为其他百度模型,将模型文件放入插件 assets 目录,并通过 initTTStextModelPath / speechModelPath 指定文件绝对路径即可。


API 详细说明

initTTS(options) 初始化语音合成引擎

初始化流程:创建合成器实例 → 复制离线模型(异步)→ 设置鉴权与参数 → 加载引擎。重复调用会先释放旧实例再重新初始化。

参数 TTSInitOptions:

属性 类型 必填 默认值 说明
mode string "offline" 合成模式:"offline" 纯离线 / "online" 纯在线 / "mix" 离在线混合
appId string 离线/mix 必填 - 百度开放平台应用 AppId
authSn string 离线/mix 必填 - 离线鉴权序列号 SN
iamKey string 在线/mix 必填 - 在线鉴权永久 iamKey
speaker string "duxiaomei" 默认离线发音人:"duxiaoyu" / "duxiaomei" / "duxiaoyao" / "duyaya"
textModelPath string 内置模型 自定义文本模型文件绝对路径(与 speechModelPath 需同时提供,提供后不再复制内置模型)
speechModelPath string 内置模型 自定义声学模型文件绝对路径
speed string "5" 语速,取值 ["0"-"15"]
volume string "5" 音量,取值 ["0"-"15"]
pitch string "5" 音调,取值 ["0"-"15"]
onlineSpeaker string "4100" 在线发音人编号(仅在线/混合模式生效)
enableLog boolean false 是否开启 SDK 调试日志(排查问题时开启)
success function - 初始化成功回调 (res: TTSInitResult) => void
fail function - 初始化失败回调 (err: TTSFail) => void
complete function - 结束回调(成功/失败均触发)

TTSInitResult:

属性 类型 说明
mode string 实际初始化的模式
engineVersion number 引擎版本号
engineInfo string 引擎信息描述
textModelPath string 文本模型文件绝对路径
speechModelPath string 声学模型文件绝对路径
offlineCode number 离线引擎加载结果码(0 为成功;mode=online 时为 0)
offlineMessage string 离线引擎加载结果描述
onlineCode number 在线引擎加载结果码(0 为成功;mode=offline 时为 0)
onlineMessage string 在线引擎加载结果描述

speak(options) 合成并播放

将文本加入合成队列,合成完成后自动播放。支持多次调用,SDK 内部按顺序排队播放。

参数 TTSSpeakOptions:

属性 类型 必填 默认值 说明
text string - 待合成文本,不超过 120 GBK 字节(约 60 个汉字),超长请分句多次调用
mode string 初始化时的模式 本次合成模式:"offline" / "online" / "mix"
utteranceId string 自动生成 合成标识 id(不传自动生成 tts_utt_N),用于关联事件回调
speed string 初始化值 本次合成语速 ["0"-"15"]
volume string 初始化值 本次合成音量 ["0"-"15"]
pitch string 初始化值 本次合成音调 ["0"-"15"]
speaker string 初始化值 本次离线发音人标识。切换为非默认发音人时,插件会自动复制对应声学模型(首次)
needAudioData boolean false 是否在 onAudioData 回调中返回音频数据(Base64 编码 PCM)
onStart function - 合成开始回调 (res: TTSEvent) => void
onProgress function - 播放进度回调,progress 取值 0-100
onAudioData function - 合成音频数据回调(needAudioData 为 true 时有效)
onFinish function - 合成播放完成回调
onError function - 合成/播放出错回调
success function - 入队成功回调 (res: TTSSpeakResult) => void
fail function - 入队失败回调(文本为空、引擎未初始化、合成失败等)
complete function - 结束回调

TTSSpeakResult:

属性 类型 说明
utteranceId string 本次合成标识 id
code number 入队结果码(0 为成功)
message string 入队结果描述

注意:success 仅表示任务入队成功,合成与播放结果请通过 onStart / onProgress / onFinish / onError 事件回调获取。

synthesize(options) 仅合成不播放

参数与 speak 完全一致,区别是不自动播放,仅完成合成(音频数据可通过 onAudioData 获取,采样率等信息在 onFinishsampleRate 字段)。

pauseTTS / resumeTTS / stopTTS / releaseTTS 播放控制

// 暂停播放(之后可通过 resumeTTS 恢复)
pauseTTS({ success: (res) => console.log(res.code) });

// 继续播放(只能恢复被"暂停"的任务)
resumeTTS();

// 停止合成并停止播放(彻底终止,不可恢复!)
stopTTS();

// 释放引擎资源(彻底销毁实例,需重新 initTTS 才能继续使用)
releaseTTS();

控制接口参数均为可选 TTSControlOptions:

属性 类型 说明
success function 控制成功回调 (res: TTSControlResult) => void,res 包含 code(0 成功)与 message
fail function 控制失败回调
complete function 结束回调

三个接口的语义区别(重要):

接口 行为 后续可否 resume
pauseTTS 暂停当前播放 ✔ resumeTTS 从暂停处恢复
stopTTS 彻底终止合成与播放,丢弃队列 ✘ 不可恢复,需重新 speak
releaseTTS 销毁引擎实例并释放资源 ✘ 需重新 initTTS

getTTSInfo(options) 查询引擎/模型信息

参数 TTSInfoOptions:

属性 类型 必填 说明
modelPath string 需要校验/查询的模型文件绝对路径(不传则不校验模型)
success function (res: TTSInfoResult) => void

TTSInfoResult:

属性 类型 说明
engineVersion number 引擎版本号
engineInfo string 引擎信息描述
cuid string 设备唯一标识(离线鉴权与 cuid 绑定相关)
modelInfo string 模型文件信息(modelPath 为空时为空字符串)
modelValid boolean 模型文件是否有效(modelPath 为空时为 false)

事件类型(TTSEvent)

所有事件回调的参数均为 TTSEvent 对象:

属性 类型 说明
type string 事件类型,见下表
utteranceId string 合成标识 id
sn string 合成序列号
instanceId string 实例 id
progress number 合成/播放进度(0-100)
engineType number 合成引擎类型:0 在线,1 离线
sampleRate number 当前音频采样率
errorCode number 错误码(无错误为 0)
errorMessage string 错误信息
audioData string 音频数据(16K 16bits 单声道 PCM,Base64 编码;needAudioData 为 false 时为空字符串)

type 取值:

事件类型 触发时机 分发至
SYNTHESIZE_START 单条合成开始 onStart
SYNTHESIZE_DATA_ARRIVED 合成音频数据到达(一段) onAudioData
SYNTHESIZE_FINISH 单条合成完成 onFinish
SYNTHESIZE_ERROR 合成出错 onError
PLAY_START 播放开始 onStart
PLAY_PROGRESS 播放进度变化 onProgress
PLAY_FINISH 播放完成 onFinish
PLAY_ERROR 播放出错 onError

保存音频文件示例:将 audioData Base64 解码后按顺序写入同一文件,即可得到完整 PCM;文件扩展名建议 .pcm,16K 采样率 16bit 单声道。


插件错误码

插件自身错误码(errCode),错误对象为 TTSFail(含 errSubject="zy-baidutts"、errCode、errMsg):

errCode 说明
9060001 引擎未初始化,请先调用 initTTS
9060002 参数错误(text 为空、无法获取 Context 等)
9060003 引擎初始化失败(实例创建失败或引擎加载失败)
9060004 模型文件不存在或无效(发音人标识无效、模型校验失败)
9060005 合成失败(speak/synthesize 入队失败)
9060006 播放控制失败(pause/resume/stop/release 返回错误)
9060007 鉴权参数缺失(离线需要 appId + authSn,在线需要 iamKey)
9060008 模型文件复制失败(assets → 私有目录)

合成/播放过程中的引擎级错误(如授权失败 -102/-109 等)通过 onError 事件的 errorCode / errorMessage 返回,详见百度官方文档《语音合成 Android SDK》错误码章节。


示例代码

<template>
    <view class="page">
        <view class="header">
            <text class="app-title">百度离线语音合成</text>
            <text class="app-subtitle">支持离线合成(内置4发音人)与在线合成</text>
        </view>

        <view class="section">
            <view class="section-title">鉴权配置</view>
            <input class="input" v-model="appId" placeholder="AppId(离线合成必填)" placeholder-class="ph" />
            <input class="input" v-model="authSn" placeholder="序列号 SN(离线合成必填)" placeholder-class="ph" />
            <input class="input" v-model="iamKey" placeholder="永久 iamKey(在线合成必填)" placeholder-class="ph" />
            <view class="mode-row">
                <view class="mode-item" :class="{ active: mode === 'offline' }" @click="mode = 'offline'">离线</view>
                <view class="mode-item" :class="{ active: mode === 'online' }" @click="mode = 'online'">在线</view>
                <view class="mode-item" :class="{ active: mode === 'mix' }" @click="mode = 'mix'">混合</view>
            </view>
        </view>

        <view class="section">
            <view class="section-title">发音人与语速</view>
            <view class="mode-row">
                <view class="mode-item" :class="{ active: speaker === 'duxiaomei' }" @click="speaker = 'duxiaomei'">度小美</view>
                <view class="mode-item" :class="{ active: speaker === 'duxiaoyu' }" @click="speaker = 'duxiaoyu'">度小宇</view>
                <view class="mode-item" :class="{ active: speaker === 'duxiaoyao' }" @click="speaker = 'duxiaoyao'">度逍遥</view>
                <view class="mode-item" :class="{ active: speaker === 'duyaya' }" @click="speaker = 'duyaya'">度丫丫</view>
            </view>
            <view class="slider-row">
                <text class="slider-label">语速 {{ speed }}</text>
                <slider class="slider" :min="0" :max="15" :step="1" :value="speed" activeColor="#4f6ef7" @change="onSpeedChange" />
            </view>
        </view>

        <view class="section">
            <view class="section-title">合成文本</view>
            <textarea class="textarea" v-model="text" placeholder="请输入待合成文本(不超过60个汉字)" placeholder-class="ph"></textarea>
            <view class="progress-row" v-if="playing">
                <text class="progress-label">播放进度:{{ progress }}%</text>
            </view>
        </view>

        <view class="btn-grid">
            <button class="btn primary" @click="handleInit">初始化</button>
            <button class="btn success" @click="handleSpeak">合成播放</button>
            <button class="btn info" @click="handleSynthesize">仅合成</button>
            <button class="btn warn" @click="handlePause">暂停</button>
            <button class="btn warn" @click="handleResume">继续</button>
            <button class="btn warn" @click="handleStop">停止</button>
            <button class="btn danger" @click="handleRelease">释放</button>
            <button class="btn info" @click="handleInfo">引擎信息</button>
        </view>

        <view class="section">
            <view class="section-title">日志</view>
            <scroll-view class="log-area" scroll-y>
                <text class="log-text">{{ logs }}</text>
            </scroll-view>
        </view>
    </view>
</template>

<script>
    import { initTTS, speak, synthesize, pauseTTS, resumeTTS, stopTTS, releaseTTS, getTTSInfo } from "@/uni_modules/zy-baidutts";

    export default {
        data() {
            return {
                appId: '',
                authSn: '',
                iamKey: '',
                mode: 'offline',
                speaker: 'duxiaomei',
                speed: 5,
                text: '百度语音合成,让应用开口说话。',
                logs: '',
                playing: false,
                progress: 0
            }
        },
        methods: {
            log(msg) {
                const now = new Date();
                const time = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();
                this.logs = '[' + time + '] ' + msg + '\n' + this.logs;
            },
            onSpeedChange(e) {
                this.speed = e.detail.value;
            },
            handleInit() {
                if (this.mode === 'offline' && (!this.appId || !this.authSn)) {
                    this.log('离线合成需要填写 AppId 和序列号 SN');
                    return;
                }
                if (this.mode === 'online' && !this.iamKey) {
                    this.log('在线合成需要填写永久 iamKey');
                    return;
                }
                this.log('开始初始化(首次启动需复制模型文件,请耐心等待)...');
                initTTS({
                    mode: this.mode,
                    appId: this.appId,
                    authSn: this.authSn,
                    iamKey: this.iamKey,
                    speaker: this.speaker,
                    speed: String(this.speed),
                    enableLog: true,
                    success: (res) => {
                        this.log('初始化成功 mode=' + res.mode + ' engineVersion=' + res.engineVersion);
                        this.log('文本模型: ' + res.textModelPath);
                        this.log('声学模型: ' + res.speechModelPath);
                    },
                    fail: (err) => {
                        this.log('初始化失败: ' + err.errMsg + ' (errCode=' + err.errCode + ')');
                    }
                });
            },
            handleSpeak() {
                this.playing = true;
                this.progress = 0;
                speak({
                    text: this.text,
                    onStart: (res) => {
                        this.log('合成开始 utteranceId=' + res.utteranceId);
                    },
                    : (res) => {
                        this.progress = res.progress;
                    },
                    onFinish: (res) => {
                        this.playing = false;
                        this.log('播放完成 engineType=' + (res.engineType === 0 ? '在线' : '离线'));
                    },
                    onError: (res) => {
                        this.playing = false;
                        this.log('合成出错: ' + res.errorMessage + ' (code=' + res.errorCode + ')');
                    },
                    fail: (err) => {
                        this.playing = false;
                        this.log('调用失败: ' + err.errMsg + ' (errCode=' + err.errCode + ')');
                    }
                });
            },
            handleSynthesize() {
                synthesize({
                    text: this.text,
                    onFinish: (res) => {
                        this.log('合成完成(未播放),采样率=' + res.sampleRate);
                    },
                    onError: (res) => {
                        this.log('合成出错: ' + res.errorMessage + ' (code=' + res.errorCode + ')');
                    },
                    fail: (err) => {
                        this.log('调用失败: ' + err.errMsg);
                    }
                });
            },
            handlePause() {
                pauseTTS({
                    success: (res) => this.log('已暂停'),
                    fail: (err) => this.log('暂停失败: ' + err.errMsg)
                });
            },
            handleResume() {
                resumeTTS({
                    success: (res) => this.log('已继续'),
                    fail: (err) => this.log('继续失败: ' + err.errMsg)
                });
            },
            handleStop() {
                stopTTS({
                    success: (res) => {
                        this.playing = false;
                        this.log('已停止');
                    },
                    fail: (err) => this.log('停止失败: ' + err.errMsg)
                });
            },
            handleRelease() {
                releaseTTS({
                    success: (res) => this.log('资源已释放 code=' + res.code),
                    fail: (err) => this.log('释放失败: ' + err.errMsg)
                });
            },
            handleInfo() {
                getTTSInfo({
                    success: (res) => {
                        this.log('引擎版本=' + res.engineVersion);
                        this.log('引擎信息=' + res.engineInfo);
                        this.log('设备 cuid=' + res.cuid);
                    },
                    fail: (err) => this.log('查询失败: ' + err.errMsg)
                });
            }
        }
    }
</script>

<style>
.page { min-height: 100vh; background: #f0f2f5; padding-bottom: 40rpx; }
.header { padding: 60rpx 40rpx 40rpx; background: linear-gradient(135deg, #4f6ef7 0%, #6c5ce7 100%); }
.app-title { display: block; color: #ffffff; font-size: 40rpx; font-weight: bold; }
.app-subtitle { display: block; color: rgba(255,255,255,0.85); font-size: 24rpx; margin-top: 10rpx; }
.section { background: #ffffff; border-radius: 16rpx; margin: 24rpx; padding: 24rpx; }
.section-title { font-size: 30rpx; font-weight: bold; color: #333333; margin-bottom: 20rpx; }
.input { border: 1px solid #e0e0e0; border-radius: 8rpx; padding: 16rpx 20rpx; font-size: 28rpx; margin-bottom: 16rpx; }
.ph { color: #bbbbbb; }
.mode-row { display: flex; flex-direction: row; flex-wrap: wrap; }
.mode-item { padding: 12rpx 30rpx; border-radius: 32rpx; background: #f0f2f5; color: #666666; font-size: 26rpx; margin: 0 16rpx 16rpx 0; }
.mode-item.active { background: #4f6ef7; color: #ffffff; }
.slider-row { display: flex; flex-direction: row; align-items: center; }
.slider-label { width: 160rpx; font-size: 26rpx; color: #666666; }
.slider { flex: 1; }
.textarea { width: 100%; height: 160rpx; border: 1px solid #e0e0e0; border-radius: 8rpx; padding: 16rpx 20rpx; font-size: 28rpx; box-sizing: border-box; }
.progress-row { margin-top: 16rpx; }
.progress-label { font-size: 26rpx; color: #4f6ef7; }
.btn-grid { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-between; margin: 24rpx; }
.btn { width: 23%; margin-bottom: 16rpx; font-size: 26rpx; line-height: 2.4; }
.btn.primary { background: #4f6ef7; color: #ffffff; }
.btn.success { background: #11998e; color: #ffffff; }
.btn.info { background: #6c5ce7; color: #ffffff; }
.btn.warn { background: #f39c12; color: #ffffff; }
.btn.danger { background: #e74c3c; color: #ffffff; }
.log-area { height: 300rpx; background: #1e1e28; border-radius: 12rpx; padding: 16rpx; }
.log-text { color: #9ae6b4; font-size: 22rpx; font-family: monospace; white-space: pre-wrap; }
</style>

注意事项

  1. 自定义基座:插件依赖原生 SDK(AAR)与 55MB 模型资源,必须云端打包自定义基座后运行,标准基座无效。
  2. 首次初始化耗时:首次启动需复制约 55MB 模型文件到私有目录,耗时数秒(异步执行,不阻塞 UI),仅执行一次。
  3. 文本长度限制:单次合成文本不超过 120 GBK 字节(约 60 个汉字)。长文本请分句后多次调用 speak,SDK 内部会排队依次播放。
  4. stop 与 pause 的区别stopTTS 会彻底终止任务,之后调用 resumeTTS 无效;需要"暂停后继续"请使用 pauseTTS
  5. 回调生命周期(keepAlive)speak / synthesize 的事件回调(/onAudioData 等)需持续触发,插件已启用 @UTSJS.keepAlive,回调对象常驻内存。请避免高频循环调用 speak(如 for 循环中短间隔调用),正常业务频率无影响。
  6. 发音人切换speak 时传入非默认 speaker,插件会自动将对应声学模型复制到私有目录(首次约需 1 秒)后再入队合成。
  7. 鉴权一致性:离线授权校验 appId、应用包名、SN 三者匹配,打包时请确认云打包使用的 Android 包名与百度控制台登记一致。
  8. 在线模式数据安全:在线/混合模式下,待合成文本会发送至百度语音服务器;纯离线模式文本仅本地处理。

常见问题(FAQ)

Q1:初始化报 -102 / -109 授权错误? A:检查 appId、SN 与百度控制台登记信息是否一致;确认云打包的 Android 包名与控制台登记包名完全一致;设备首次使用需联网激活一次授权。

Q2:初始化报 9060008 模型复制失败? A:确认插件 utssdk/app-android/assets/ 目录下 5 个 .dat 模型文件完整(文本模型 1 个 + 声学模型 4 个),重新打包基座后重试。

Q3:调用 resumeTTS 显示成功但没有继续播放? A:resumeTTS 只能恢复被 pauseTTS 暂停的任务。若之前调用的是 stopTTS(彻底终止),resume 无法恢复,请重新调用 speak。

Q4: 只触发一次或报"回调函数已释放"? A:HBuilderX 4.25+ 回调默认单次触发后回收。本插件 speak/synthesize 已配置 @UTSJS.keepAlive 支持持续回调,请确认 HBuilderX 版本 ≥ 4.27。

Q5:支持后台播放吗? A:合成与播放基于 SDK 内部线程,App 切后台通常可继续播放,但系统回收进程后无法保证;如需长时后台播报,请配合前台服务使用。

Q6:如何获取合成音频保存为文件? A:speak/synthesize 时设置 needAudioData: true,在 onAudioData 回调中收集 audioData(Base64),全部到齐后(SYNTHESIZE_FINISH)Base64 解码写入文件,即为 16K 16bits 单声道 PCM 数据。

更新日志

changelog.md

隐私、权限声明

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

android.permission.INTERNET,android.permission.ACCESS_NETWORK_STATE,android.permission.READ_PHONE_STATE,android.permission.WRITE_EXTERNAL_STORAGE,android.permission.READ_EXTERNAL_STORAGE

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

待合成文本仅用于本地离线合成引擎处理;在线模式合成文本将发送至百度语音服务器

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

暂无用户评论。