Android SDK
1. 离线TTS概述
DUI Lite SDK 离线TTS可使在无网的情况下,提供将文字信息转化为声音信息的能力,方便您更流畅的体验合成音,给您的应用程序增加“嘴巴”功能,更趋近于人。您仅仅需要将下载的SDK嵌入到工程项目中,就可以流畅的获取从文字输入到语音输出的支持。另外,我们也提供了具有特色的发音人(若需要定制,可联系商务)。如果希望语音输出内容更富有感情,可以在对话回复中为回复内容添加SSML标签。
2. 技术申请
先在DUI开放平台注册一个账号成为开发者,登录并创建单项技术,输入名称及产品图标
选择本地语音,点击保存
点击进入授权管理页面
申请APIKEY, 填入名称,app的SHA256,包名,点击确定
生成Product ID,Product Key ,Product Secret ,APIKEY,SDK
Product ID:集成SDK时需用到的鉴权参数
Product Key:集成SDK时需用到的鉴权参数
Product Secret :集成SDK时需用到的鉴权参数
APIKEY:集成SDK时需用到的鉴权参数
选择离线语音合成下载,文件中包含:sdk so sample javaDoc
3.集成
3.1准备
jar so tts合成使用的资源
资源信息
so信息
3.2权限
如果资源放在sdcard中,需要申请读写权限
<!-- 文件读写需要用到此权限 -->
<uses-permission android:name="androidpermission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
targetSdkVersion 版本高于30,需要增加权限
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
if (Build.VERSION.SDK_INT >= 30) {
if (!Environment.isExternalStorageManager()) {
Intent intent = new Intent("android.settings.MANAGE_ALL_FILES_ACCESS_PERMISSION");
startActivity(intent);
}
}
3.3混淆
4.引擎运行流程图
5. 功能使用
AILocalTTSConfig config = new AILocalTTSConfig();
//设置后端合成音色资源,如果只需设置一个,则array只需要传一个成员值就可以
config.addSpeakerResource(mBackResBinArray);
config.setEnableOptimization(true);
/**
* 普通话
*/
config.setDictResource("tts/v2.1.49_aitts_sent_dict_local.db");//普通话字典
config.setFrontBinResource("tts/v2.1.49_local_front.bin_eng");//普通话
config.setLanguage(0);//不设置默认是0
spinner_res.setSelection(0);
// 设置合成音色的外部路径,包含文件名(需要手动拷贝到指定目录)
// config.addSpeakerResource("/sdcard/speech/tts/zhilingf_common_back_ce_local.v2.1.0.bin");
mEngine = AILocalTTSEngine.createInstance();//创建实例
mEngine.init(config, new AILocalTTSListener());//初始化合成引擎
5.1初始化参数说明
详细参数说明参考AILocalTTSConfig
参数名 | 取值 | 说明 | 是否必须 | 默认值 |
---|---|---|---|---|
setLanguage(int language) | 0,4,5,6,7 | 0是默认中文 4粤语 5英语 6法语7泰语 | 必须 | 0 |
setDictResource(String dictResource) | bin文件路径 | 如在 sd 里设置为绝对路径 如/sdcard/speech/***.db如在 assets里设置为名称 | 必须 | 空 |
setFrontBinResource(String frontBinResource) | 前端bin文件路径 | 设置 FrontBinResource,包含文本归一化,分词的,韵律等如在 sd 里设置为绝对路径如/sdcard/speech/***.bin如在 assets 里设置为名称 | 必须 | 空 |
addSpeakerResource(String speakerResource) | 发音人bin文件路径 | 设置 发音人资源,若只需要一个发音人,则设置一个即可。设置多个时第1个即为使用的发音人 | 必须 | 空 |
5.2开始合成和播报参数
speak示例
aILocalTTSIntent = new AILocalTTSIntent();
// 设置合成音语速,范围为0.5~2.0
aILocalTTSIntent.setSpeed(0.85f);
aILocalTTSIntent.setUseSSML(false); // 设置是否使用ssml合成语法,默认为false
aILocalTTSIntent.setVolume(100); // 设置合成音频的音量,范围为1~500
aILocalTTSIntent.setLmargin(10); //设置头部静音段,范围5-20
aILocalTTSIntent.setRmargin(10); //设置尾部静音段,范围5-20
// 保存合成音频到指定路径
aILocalTTSIntent.setSaveAudioFilePath("/sdcard/aispeech/tts");
aILocalTTSIntent.setUseTimeStamp(true);
aILocalTTSIntent.setSleepTime(300);
mEngine.speak(aILocalTTSIntent, refText, "1024");
详细参数说明AILocalTTSIntent
参数名 | 取值 | 说明 | 是否必须 | 默认值 |
---|---|---|---|---|
setSpeed(float speed) | float 范围为0.5~2.0 | 设置语音合成的速度 | 非 | 1.0f |
setVolume(int volume) | int 范围1-500 | 设置语音合成的音量 | 非 | 80 |
setUseSSML(boolean useSSML) | boolean | 设置是否使用ssml 默认不使用为false | 非 | false |
switchToSpeaker(String speakerResource) | Sting | 发音人资源,切换发音人 | 非 | 空 |
setUseTimeStamp(boolean useTimeStamp) | boolean | 音素返回对应的回调onTimestampReceived(byte[] bytes,int size)拿到数据 | 非 | false |
5.3 动态设置参数
详细参数说明AILocalTTSEngine
参数名 | 取值 | 说明 | 是否必须 | 默认值 |
---|---|---|---|---|
setUseCache(boolean useCache) | bool | 设置是否使用缓存,默认为true 缓存TTS缓存信息和音频文件,存放在应用外部缓存目录下的 ttsCache 文件夹下。 | 非 | true |
speak(AILocalTTSIntent aiLocalTTSIntent, String refText, String utteranceId) | aiLocalTTSIntent详见AILocalTTSIntent refText:合成文本 utteranceId:utteranceId | 合成并播放 | ||
synthesize(AILocalTTSIntent aiLocalTTSIntent, String text, String utteranceId) | aiLocalTTSIntent详见AILocalTTSIntent refText:合成文本 utteranceId:utteranceId | 只合成,不播放,同时抛出实时合成音频流 | ||
deleteLocalResFile() | 删除TTS本地资源方法 ,可以在onInit回调失败时调用,一般是相关bin资源在assets下时调用,若是外置目录需注意需要重新copy进去 |
6.示例代码
详细代码参考sample
AILocalTTSEngine mEngine;
AILocalTTSConfig config = new AILocalTTSConfig();
// 设置assets目录下合成字典名和相应的Md5文件名
config.setDictResource(SampleConstants.TTS_DICT_RES, SampleConstants.TTS_DICT_MD5);
// 设置合成字典的外部路径,包含文件名(需要手动拷贝到指定目录)
// config.setDictResource("/sdcard/speech/tts/aitts_sent_dict_idx_middle_2.0.4_20180806.db");
// 设置assets目录下前端合成资源名和相应的Md5文件名
config.setFrontBinResource(SampleConstants.TTS_FRONT_RES, SampleConstants.TTS_FRONT_RES_MD5);
// 设置合成前端资源的外部路径,包含文件名(需要手动拷贝到指定目录)
// config.setFrontBinResource("/sdcard/speech/tts/local_front.bin");
// default is true
config.setUseCache(false);
//设置后端合成音色资源,如果只需设置一个,则array只需要传一个成员值就可以
config.addSpeakerResource(mBackResBinArray, mBackResBinMd5sumArray);
// 设置合成音色的外部路径,包含文件名(需要手动拷贝到指定目录)
// config.addSpeakerResource("/sdcard/speech/tts/zhilingf_common_back_ce_local.v2.1.0.bin");
mEngine = AILocalTTSEngine.getInstance();//创建实例
mEngine.init(config, new AILocalTTSListenerImpl());//初始化合成引擎
AILocalTTSIntent aILocalTTSIntent = new AILocalTTSIntent();
// 设置合成音语速,范围为0.5~2.0
aILocalTTSIntent.setSpeed(0.85f);
aILocalTTSIntent.setUseSSML(false); // 设置是否使用ssml合成语法,默认为false
aILocalTTSIntent.setVolume(100); // 设置合成音频的音量,范围为1~500
// 保存合成音频到指定路径,格式为wav
aILocalTTSIntent.setSaveAudioFilePath(Environment.getExternalStorageDirectory() + "/tts/"
+ System.currentTimeMillis() + ".wav");
// 合成并播放
mEngine.speak(aILocalTTSIntent, refText, "1024");
// 合成音频,不播放,同时输出实时pcm音频,音频回调在onSynthesizeDataArrived接口
// mEngine.synthesize(aILocalTTSIntent, refText, "1024");
mEngine.pause();
mEngine.resume();
mEngine.stop();
mEngine.destroy();
private class AILocalTTSListenerImpl implements AILocalTTSListener {
@Override
public void onInit(int status) {
Log.i(Tag, "初始化完成,返回值:" + status);
Log.i(Tag, "onInit");
if (status == AIConstant.OPT_SUCCESS) {
tip.setText("初始化成功!");
btnStart.setEnabled(true);
} else {
tip.setText("初始化失败!code:" + status);
}
}
@Override
public void onError(String utteranceId, AIError error) {
tip.setText("检测到错误");
content.setText(content.getText() + "\nError:\n" + error.toString());
}
@Override
public void onSynthesizeStart(String utteranceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tip.setText("合成开始");
Log.d(Tag, "合成开始");
}
});
}
@Override
public void onSynthesizeDataArrived(String utteranceId, byte[] audioData) {
//Log.d(Tag, "合成pcm音频数据:" + audioData.length);
//正常合成结束后会收到size大小为0的audioData,即audioData.length == 0。应用层可以根据该标志停止播放
//若合成过程中取消(stop或release),则不会收到该结束标志
}
@Override
public void onSynthesizeFinish(String utteranceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tip.setText("合成结束");
Log.d(Tag, "合成结束");
}
});
}
@Override
public void onSpeechStart(String utteranceId) {
tip.setText("开始播放");
Log.i(Tag, "开始播放");
}
@Override
public void onSpeechProgress(int currentTime, int totalTime, boolean isRefTextTTSFinished) {
showTip("当前:" + currentTime + "ms, 总计:" + totalTime + "ms, 可信度:" + isRefTextTTSFinished);
}
@Override
public void onSpeechFinish(String utteranceId) {
tip.setText("播放完成");
Log.i(Tag, "播放完成");
}
}
7. 常见使用方式
7.1 特定资源类和language使用
特定的资源及发音人,英语资源,intent中切换发音人的时候需要设置发音人及language(英语是5),否则会发出鸟语
switchToSpeaker(String speakerResource, int language)
7.2合成方式
7.2.1合成并播报
AILocalTTSEngine.speak(AILocalTTSIntent,refText,"1024");
7.2.2 只合成不播放
AILocalTTSEngine.synthesize(AILocalTTSIntent,refText,"1024");
8. 常见使用问题
8.1本地TTS合成支持哪些音频?
目前仅支持WAV
8.2TTS缓存大小,缓存限制?
默认缓存100条(2.37.2版本),默认每条缓存的字数是200,超过限制不缓存,避免超大音频读取导致进程长期占用
8.3TTS合成播报手机号
// 合成的文本类型, text or ssml, default is text
intent.setTextType("ssml");
mEngine.speak(intent, "<?xml version=\"1.0\" encoding=\"utf8\"?><speak xml:lang=\"cn\"><p>我的手机号是<sayas type=\"telephone\">180000000000</sayas>,今年公司创收<sayas type=\"number:digits\">17666890053元</sayas>今年公司创收<sayas type=\"currency\">17666890053元</sayas></p></speak>", "1024");
SSML 使用文档