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信息

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 使用文档

9. 错误信息

DUI Lite 2.0 - 错误码