语音合成 Android SDK
一、SDK描述
京东AI为满足TTS相关产品的快速接入,在REST API的基础上对各种平台和语言进行封装,大大降低客户接入的难度。现已发布的平台及语言有:C/C++,Java,Android,IOS,Python, H5等,已适用于大部分的应用场景。并成功应用于虚拟主播,智能客服,智能外呼,读书,新闻读报,引导机器人,智能音箱等各领域的应用场景。
用户通过SDK创建TTSEngine对象,设置用户需要的参数,把文本数据通过speak和synthesize方法,交给实例化的ttsEngine对象,即可通过注册的Listener对象,获取生成的语音数据和系统的各种状态,大大降低了AI功能接入的难度。
本MixTTS同时屏蔽了在线和离线模式的差异性, 用户只需要在生成TTSEngine对象的时候,指定Online还是Offline模式即可, 从用户角度,维护了上层业务的一致性。
1.1. 功能描述
当前主要支持的功能: 基本功能: 语音数据处理,网络通讯,音频实时回调,实时播放合成音频等。
1.2. 鉴权说明
平台为每个API提供试用体验服务,您在AI市场选择“免费试用”规格下单后,即可开始体验业内领先的人工智能API服务。 免费试用服务具有调用量、QPS限制,如需更高性能的API服务,可以提交咨询工单,联系京东AI扩容购买。
该SDK封装TTS API的功能,需要先参考 接入流程 获取AppKey和SecretKey,并在调用SDK时作为参数传入。
1.3. 支持的设备
- 系统: 支持 Android 4.3 及以上系统。通过 minSdkVersion 参数检测。
- 机型: 手机、平板及其它智能终端设备。
- 架构: 支持 [armeabi],armeabi-v7a,armeabi-v8a,[x86],[x86_64]。
- 外设: 设备上有麦克风输入。
- 网络: 支持 wifi 及系统网络。
二、使用说明
2.1. 下载地址
- v2.1.57(MD5:e9de26a5c38eb69af5d570dec93f9dcb)
历史版本:
2.2. 集成指南
- 将jar包拷贝到工程libs目录下,并加入工程依赖。
- 将 libs 目录下 [armeabi],arm64-v8a,armeabi-v7a,[x86] 文件夹按需添加到 android studio 工程 src/main/jniLibs 目录中, eclipse 用户默认为 libs 目录。
- 为工程添加必要的权限
添加设置:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2.3.各权限使用说明
名称 | 用途 |
---|---|
android.permission.INTERNET | 允许应用联网发送语音数据给服务器获 取识别结果 |
android.permission.ACCESS_NETWORK_STATE | 获取当前 WiFi 状态 |
Android 6.0 及以上的动态申请权限,示例参考.
private void applyPremission() {
String permissions[] = {
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.INTERNET,
};
ArrayList<String> applyList = new ArrayList<String>();
for(String perm :permissions) {
if(PackageManager.PERMISSION_GRANTED !=
ContextCompat.checkSelfPermission(this,perm)) {
applyList.add(perm);
}
}
String tmpList[] = new String[applyList.size()];
if(!applyList.isEmpty()){
ActivityCompat.requestPermissions(this, applyList.toArray(tmpList), 123);
}
}
三、接口说明
3.1 JDLogProxy Log代理类
JDLogProxy.setEnable(true, JDLogProxy.VERBOSE)
参数说明:
enable:true/false level:VERBOSE 、DEBUG 、INFO 、WARN 、ERROR 、ASSERT
3.2 TTSParam 参数封装
setOpts()
函数定义:
setOpts(String key, String val)
功能:
设置TTS系统参数值。
参数说明:
key:参数名称 val:参数值
用例:
TTSParam ttsParam = new TTSParam();
ttsParam.setOpts("aue", "2"); // 0:wav, 1:pcm, 2:opus, 3:mp3
ttsParam.setOpts("sr", "16000"); // 采样率 wav和pcm支持4k到24k的采样率 opus支持8k 12k 16k 和24k的采样率
ttsParam.setOpts("serverURL", "XXXXXXXX"); 接口地址(注意每个API接口地址不同,详见购买的API接口文档)
ttsParam.setOpts("appKey", "XXXXXXX");
ttsParam.setOpts("appSecret", "XXXXXXXXXXX");
ttsParam.setOpts("CustomerType", "0"); // 固定值,Neuhub平台
ttsParam.setOpts("tte", "1"); // 1:UTF-8 (目前仅支持UTF-8格式)
ttsParam.setOpts("tim", "1"); // 0:女声 1:男声
ttsParam.setOpts("vol", "4"); // 音量[0.1, 10.0]
ttsParam.setOpts("sp", "1.0"); // 语速 [0.5, 2.0] wav和pcm支持4k到24k的采样率
ttsParam.setOpts("streamMode", "1"); // 1 流式模式, 0 非流式模式
ttsParam.setOpts("tt", "0"); // 文本格式, 0:文本 1:SSML
ttsParam.setOpts("ttsModel", "taotao.dat"); //引擎模型, 在离线模式下有效
ttsParam.setOpts("connectTimeout", "3000"); //3s
ttsParam.setOpts("readTimeout", "5000"); //5s
ttsParam.setOpts("playCacheNum", "0"); //播放器缓冲设置, 内部默认为2
ttsParam.setOpts("httpProtocols", "http1"); //http1版本协议
ttsParam.setOpts("authID", "XXXX"); //离线认证ID
getOpts()
函数定义:
getOpts(String key)
功能:
获取系统参数值
参数:
key:参数名称
用例:
String readTimeout = ttsParam.getOpts("readTimeout")
toString()
功能:
输出系统的参数
用例:
String paramInfo = ttsParam.toString()
3.3 TTSEngineListener SDK事件监听类
onSynthesizeStart()
函数定义:
onSynthesizeStart(String utteranceId)
功能: 合成开始回调函数,在发起合成请求时回调 参数: utteranceId:合成文本的ID,在调用合成接口的时候, 一般使用UUID的值作为输入
onSynthesizeFirstPackage(String utteranceId)
功能: 合成时,返回第一包的回调,一般用来计算延时时间 参数: utteranceId:同上。
onSynthesizeDataArrived()
功能: 合成数据的回调函数,在用户使用了synthesize方法这个回调有效。在speak方法时,这个回调无效 参数: utteranceId:同上 audioData:合成的音频数据, PCM数据格式 index:数据返回的index值, 当index由正数变为负数时, 合成数据结束 process:合成进度 timeStamp:合成数据的时间戳
onSynthesizeFinish()
函数定义:
onSynthesizeFinish(String utteranceId)
功能: 合成结束回调 参数: utteranceId:同上
onPlayStart()
函数定义:
onPlayStart(String utteranceId)
功能: 播放开始,使用speak方法会有此回调,使用synthesize没有 参数: utteranceId:同上
onPlayProgressChanged()
函数定义:
onPlayProgressChanged(String utteranceId, double progress)
功能: 播放状态回调,主要提示播放进度 参数: utteranceId:同上 progress:播放进度
onPlayFinish()
函数定义
onPlayFinish(String utteranceId)
功能: 播放结束,当缓存中没有数据时,调用此回调。 参数: utteranceId:同上
onError()
函数定义:
onError(String utteranceId, TTSErrorCode errno)
功能: 系统异常回调 参数: utteranceId:同上。
3.4 TTSEngine 引擎类
loadAssets()
函数定义:
loadAssets(Context ctx, String path, TTSMode mode)
功能: 加载系统资源 参数: ctx:getApplicationContext() path:load资源路径,默认是“assets” mode:ONLINE、OFFLINE
用例:
TTSEngine.loadAssets(getApplicationContext(), "assets", TTSMode.ONLINE)
setTTSEngineListener()
函数定义:
setTTSEngineListener(TTSEngineListener listener)
功能: 加载系统资源 参数: listener:TTSEngine的监听对象 用例:
ttsEngine.setTTSEngineListener(new MyTTSEngineListener())
TTSEngine()
函数定义:
TTSEngine(Context ctx, TTSMode mode)
功能: 创建tts engine对象 参数: ctx:getApplicationContext() mode:同上 用例:
TTSEngine ttsEngine = new TTSEngine(getApplicationContext(), TTSMode.ONLINE)
setParam()
函数定义:
setParam(TTSParam param)
功能: 设置参数。 参数: param:TTSEngine 参数对象
用例:
ttsEngine.setParam(ttsParam)
auth()
函数定义:
auth()
功能: 完成SDK认证(离线模式使用) 参数: authID:认证ID,请在http://neuhub.jd.com/上申请 用例:
ttsEngine.auth()
speak()
函数定义:
speak(String txt, String utteranceId)
功能: TTS 合成并播放功能 参数: txt:文本输入 utteranceId:文本ID 用例:
String txtID = UUID.randomUUID().toString()
ttsEngine.speak("江南的风景真是好", txtID)
synthesize()
函数定义:
synthesize(String txt, String utteranceId)
功能: TTS 合成音频功能。 参数: txt:文本输入。 utteranceId:文本ID。 用例:
String txtID = UUID.randomUUID().toString()
ttsEngine.synthesize("你好,京东!", txtID)
cancel()
函数定义:
cancel()
功能: 在ttsEngine退出时执行此函数, 释放SDK内部资源
pause()
函数定义:
pause()
功能: 暂停,合成部分继续执行,将线程缓存到播放线程中, 但是播放将停止, 在执行resume时, 播放线程继续播放缓存的数据。
resume()
函数定义:
resume()
功能: 继续,将播放线程中的数据继续播放完毕
stop()
函数定义:
stop()
功能: 停止,将播放线程中的数据清空,放弃本次操作
四、NDK平台限制
为减少APP的大小,采用主流的平台支持, 比如:arm64-v8a、armeabi-v7a,其他平台特殊平台, 请联系商务。
android {
defaultConfig {
XXXX
ndk {
//abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
abiFilters "armeabi-v7a"
}
}
}
五、错误码
此处错误码只包含的SDK,只处理SDK处理的错误,API的错误通过onError函数直接透传。
Name | Value | Description |
---|---|---|
OK_NO | 0 | Success |
ERR_RESOURCE_NO | -100 | Loading error |
ERR_PLAYER_NO | -101 | audio player error |
ERR_TEXTEMPTY_NO | -102 | Text is empty |
ERR_TEXTTOOLONG_NO | -103 | Text is too long |
ERR_SYNTHESIZE_NO | -104 | Synthesize error |
ERR_INITTTSENGINE_NO | -105 | Init TTS engine error |
ERR_BATCHEMPTY_NO | -106 | Batch speak empty |
ERR_BATCHTOOLONG_NO | -107 | Batch speak too long |
ERR_PLAYERNULL_NO | -108 | Audio player is null |
ERR_PLAYERCLOSE_NO | -108 | Audio player release failed |
ERR_TTSENGINECLOSE_NO | -110 | TTS engine release failed |
ERR_NOT_SUPPORT | -111 | TTS engine not support |
ERR_SRV_Error | -112 | TTS Srv status |
ERR_NOT_AUTH | -113 | TTS Not Auth |
ERR_NO_Data_Recv | -114 | Recv Data len = 0 |
ERR_PARAM_NO_SUPPORT | -115 | Param Not Support |
ERR_SRV_Exception | -116 | Http Srv Exception |
ERR_AUTH_OK | -117 | TTS Auth OK |
ERR_AUTH_Err | -118 | TTS Auth Err |
ERR_UNKNOWN_NO | -999 | Unknown error |
六、Demo示例
JDLogProxy.setEnable(true, JDLogProxy.VERBOSE);
boolean ret = TTSEngine.loadAssets(getApplicationContext(), "assets", TTSMode.ONLINE);
if(!ret){
JDLogProxy.i(TAG, "loadAssets failed" );
return;
}
ttsEngine.setTTSEngineListener(new MyTTSEngineListener());
TTSParam ttsParam = new TTSParam();
ttsParam.setOpts("aue", "2"); // 0:wav, 1:pcm, 2:opus, 3:mp3
ttsParam.setOpts("sr", "16000"); // 采样率 wav和pcm支持4k到24k的采样率 opus支持8k 12k 16k 和24k的采样率
ttsParam.setOpts("serverURL", "XXXXX");接口地址(注意每个API接口地址不同,详见购买的API接口文档)
ttsParam.setOpts("appKey", "XXXXXXX");
ttsParam.setOpts("appSecret", "XXXXXX");
ttsParam.setOpts("CustomerType", "0"); // 固定值,Neuhub平台
ttsParam.setOpts("tim", "1"); // 0:女声 1:男声 (注意每个API的音色参数不同,详见购买的API接口文档)
ttsParam.setOpts("vol", "4"); // 音量[0.1, 10.0]
ttsParam.setOpts("sp", "1.0"); // 语速 [0.5, 2.0]
ttsParam.setOpts("streamMode", "1"); // 1 流式模式, 0 非流式模式
ttsParam.setOpts("tt", "0"); // 文本格式, 0:文本 1:SSML
ttsParam.setOpts("ttsModel", "taotao.dat"); //引擎模型, 在离线模式下有效
ttsParam.setOpts("connectTimeout", "5000"); //5s
ttsParam.setOpts("readTimeout", "10000"); //10s
ttsParam.setOpts("playCacheNum", "2"); //播放器的缓存
ttsParam.setOpts("httpProtocols", "http1"); //协议版本 http1,http2
ttsParam.setOpts("authID", "XXXXXXXXXXXXX"); //认证ID
ttsEngine.setParam(ttsParam);
ttsEngine.auth(); //auth ID 只在离线模式下调用即可
String txtID = UUID.randomUUID().toString();
ttsEngine.speak("你好,京东!", txtID);
//请把以下接口放在控制程序中
//ttsEngine.pause();
//ttsEngine.resume();
//ttsEngine.stop();
//在对象销毁时, 调用一次,释放内部资源
//ttsEngine.cancel();
//监听函数
public class MyTTSEngineListener implements TTSEngineListener {
@Override
public void onSynthesizeStart(String utteranceId){
JDLogProxy.i(TAG, "onSynthesizeStart=" + utteranceId);
}
@Override
public void onSynthesizeFirstPackage(String utteranceId){
JDLogProxy.i(TAG, "onSynthesizeFirstPackage=" + utteranceId);
}
@Override
public void onSynthesizeDataArrived(String utteranceId, byte[] audioData, int index, double process, String timeStamp){
JDLogProxy.i(TAG, "onSynthesizeDataArrived: utteranceId=" + utteranceId + ", index=" + index + ", process=" + process + ", timeStamp=" + timeStamp);
}
@Override
public void onSynthesizeFinish(String utteranceId){
JDLogProxy.i(TAG, "onSynthesizeFinish=" + utteranceId);
}
@Override
public void onPlayStart(String utteranceId){
JDLogProxy.i(TAG, "onPlayStart=" + utteranceId);
}
@Override
public void onPlayProgressChanged(String utteranceId, double progress){
JDLogProxy.i(TAG, "onPlayProgressChanged=" + progress);
}
//播放暂停状态时的回调方法
public void onPlayPause(String utteranceId){
JDLogProxy.i(TAG, "onPlayPause=" + utteranceId);
}
//播放暂停状态转变为继续
public void onPlayResume(String utteranceId){
JDLogProxy.i(TAG, "onPlayPause=" + utteranceId);
}
@Override
public void onPlayFinish(String utteranceId){
JDLogProxy.i(TAG, "onPlayFinish=" + utteranceId);
}
@Override
public void onError(String utteranceId, TTSErrorCode errno){
JDLogProxy.i(TAG, "utteranceId=" +utteranceId + ", onError=" + errno.getErrno() + ", desc=" + errno.getDesc());
}
}