灵云语音合成
程序员文章站
2022-03-08 12:16:21
...
注册
注册比较简单,就不做过多介绍了,注册万应用以后,在后台创建自己的应用,创建完应用以后需要给应用开通对应的语音能力。
集成
如果使用在线功能,下载对应的SDK,里面有jar包和so,就可以满足需求了。如果要使用离线的语音功能,还需要下载灵云资源文件
源码
灵云在线语音合成
权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
配置类
package kong.qingwei.kqwhcittsdemo;
/**
* Created by kqw on 2016/8/12.
* 灵云配置信息
*/
public final class ConfigUtil {
/**
* 灵云APP_KEY
*/
public static final String APP_KEY = "填入自己的APP KEY";
/**
* 开发者**
*/
public static final String DEVELOPER_KEY = "填入自己的DEVELOPER KEY";
/**
* 灵云云服务的接口地址
*/
public static final String CLOUD_URL = "test.api.hcicloud.com:8888";
/**
* 需要运行的灵云能力
*/
// public static final String CAP_KEY = "tts.local.synth";
public static final String CAP_KEY = "tts.cloud.wangjing";
}
封装灵云语音的初始化
package kong.qingwei.kqwhcittsdemo;
import android.app.Activity;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
import com.sinovoice.hcicloudsdk.api.HciCloudSys;
import com.sinovoice.hcicloudsdk.common.AuthExpireTime;
import com.sinovoice.hcicloudsdk.common.HciErrorCode;
import com.sinovoice.hcicloudsdk.common.InitParam;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Created by kqw on 2016/8/12.
* 初始化灵云语音
*/
public class HciUtil {
private static final String TAG = "HciUtil";
private Activity mActivity;
private final String mConfigStr;
public HciUtil(Activity activity) {
mActivity = activity;
// 加载信息,返回InitParam, 获得配置参数的字符串
InitParam initParam = getInitParam();
mConfigStr = initParam.getStringConfig();
}
public boolean initHci() {
// 初始化
int errCode = HciCloudSys.hciInit(mConfigStr, mActivity);
if (errCode != HciErrorCode.HCI_ERR_NONE && errCode != HciErrorCode.HCI_ERR_SYS_ALREADY_INIT) {
Toast.makeText(mActivity, "hciInit error: " + HciCloudSys.hciGetErrorInfo(errCode), Toast.LENGTH_SHORT).show();
return false;
}
// 获取授权/更新授权文件 :
errCode = checkAuthAndUpdateAuth();
if (errCode != HciErrorCode.HCI_ERR_NONE) {
// 由于系统已经初始化成功,在结束前需要调用方法hciRelease()进行系统的反初始化
Toast.makeText(mActivity, "CheckAuthAndUpdateAuth error: " + HciCloudSys.hciGetErrorInfo(errCode), Toast.LENGTH_SHORT).show();
HciCloudSys.hciRelease();
return false;
}
return true;
}
/**
* 加载初始化信息
*
* @return 系统初始化参数
*/
private InitParam getInitParam() {
String authDirPath = mActivity.getFilesDir().getAbsolutePath();
// 前置条件:无
InitParam initparam = new InitParam();
// 授权文件所在路径,此项必填
initparam.addParam(InitParam.AuthParam.PARAM_KEY_AUTH_PATH, authDirPath);
// 是否自动访问云授权,详见 获取授权/更新授权文件处注释
initparam.addParam(InitParam.AuthParam.PARAM_KEY_AUTO_CLOUD_AUTH, "no");
// 灵云云服务的接口地址,此项必填
initparam.addParam(InitParam.AuthParam.PARAM_KEY_CLOUD_URL, ConfigUtil.CLOUD_URL);
// 开发者Key,此项必填,由捷通华声提供
initparam.addParam(InitParam.AuthParam.PARAM_KEY_DEVELOPER_KEY, ConfigUtil.DEVELOPER_KEY);
// 应用Key,此项必填,由捷通华声提供
initparam.addParam(InitParam.AuthParam.PARAM_KEY_APP_KEY, ConfigUtil.APP_KEY);
// 配置日志参数
String sdcardState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(sdcardState)) {
String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String packageName = mActivity.getPackageName();
String logPath = sdPath + File.separator + "sinovoice" + File.separator + packageName + File.separator + "log" + File.separator;
// 日志文件地址
File fileDir = new File(logPath);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
// 日志的路径,可选,如果不传或者为空则不生成日志
initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_PATH, logPath);
// 日志数目,默认保留多少个日志文件,超过则覆盖最旧的日志
initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_COUNT, "5");
// 日志大小,默认一个日志文件写多大,单位为K
initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_SIZE, "1024");
// 日志等级,0=无,1=错误,2=警告,3=信息,4=细节,5=调试,SDK将输出小于等于logLevel的日志信息
initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_LEVEL, "5");
}
return initparam;
}
/**
* 获取授权
*
* @return 授权结果
*/
private int checkAuthAndUpdateAuth() {
// 获取系统授权到期时间
int initResult;
AuthExpireTime objExpireTime = new AuthExpireTime();
initResult = HciCloudSys.hciGetAuthExpireTime(objExpireTime);
if (initResult == HciErrorCode.HCI_ERR_NONE) {
// 显示授权日期,如用户不需要关注该值,此处代码可忽略
Date date = new Date(objExpireTime.getExpireTime() * 1000);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
Log.i(TAG, "expire time: " + sdf.format(date));
if (objExpireTime.getExpireTime() * 1000 > System.currentTimeMillis()) {
// 已经成功获取了授权,并且距离授权到期有充足的时间(>7天)
Log.i(TAG, "checkAuth success");
return initResult;
}
}
// 获取过期时间失败或者已经过期
initResult = HciCloudSys.hciCheckAuth();
if (initResult == HciErrorCode.HCI_ERR_NONE) {
Log.i(TAG, "checkAuth success");
return initResult;
} else {
Log.e(TAG, "checkAuth failed: " + initResult);
return initResult;
}
}
}
封装灵云语音合成能
package kong.qingwei.kqwhcittsdemo;
import android.app.Activity;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
import com.sinovoice.hcicloudsdk.api.HciCloudSys;
import com.sinovoice.hcicloudsdk.common.AuthExpireTime;
import com.sinovoice.hcicloudsdk.common.HciErrorCode;
import com.sinovoice.hcicloudsdk.common.InitParam;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Created by kqw on 2016/8/12.
* 初始化灵云语音
*/
public class HciUtil {
private static final String TAG = "HciUtil";
private Activity mActivity;
private final String mConfigStr;
public HciUtil(Activity activity) {
mActivity = activity;
// 加载信息,返回InitParam, 获得配置参数的字符串
InitParam initParam = getInitParam();
mConfigStr = initParam.getStringConfig();
}
public boolean initHci() {
// 初始化
int errCode = HciCloudSys.hciInit(mConfigStr, mActivity);
if (errCode != HciErrorCode.HCI_ERR_NONE && errCode != HciErrorCode.HCI_ERR_SYS_ALREADY_INIT) {
Toast.makeText(mActivity, "hciInit error: " + HciCloudSys.hciGetErrorInfo(errCode), Toast.LENGTH_SHORT).show();
return false;
}
// 获取授权/更新授权文件 :
errCode = checkAuthAndUpdateAuth();
if (errCode != HciErrorCode.HCI_ERR_NONE) {
// 由于系统已经初始化成功,在结束前需要调用方法hciRelease()进行系统的反初始化
Toast.makeText(mActivity, "CheckAuthAndUpdateAuth error: " + HciCloudSys.hciGetErrorInfo(errCode), Toast.LENGTH_SHORT).show();
HciCloudSys.hciRelease();
return false;
}
return true;
}
/**
* 加载初始化信息
*
* @return 系统初始化参数
*/
private InitParam getInitParam() {
String authDirPath = mActivity.getFilesDir().getAbsolutePath();
// 前置条件:无
InitParam initparam = new InitParam();
// 授权文件所在路径,此项必填
initparam.addParam(InitParam.AuthParam.PARAM_KEY_AUTH_PATH, authDirPath);
// 是否自动访问云授权,详见 获取授权/更新授权文件处注释
initparam.addParam(InitParam.AuthParam.PARAM_KEY_AUTO_CLOUD_AUTH, "no");
// 灵云云服务的接口地址,此项必填
initparam.addParam(InitParam.AuthParam.PARAM_KEY_CLOUD_URL, ConfigUtil.CLOUD_URL);
// 开发者Key,此项必填,由捷通华声提供
initparam.addParam(InitParam.AuthParam.PARAM_KEY_DEVELOPER_KEY, ConfigUtil.DEVELOPER_KEY);
// 应用Key,此项必填,由捷通华声提供
initparam.addParam(InitParam.AuthParam.PARAM_KEY_APP_KEY, ConfigUtil.APP_KEY);
// 配置日志参数
String sdcardState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(sdcardState)) {
String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String packageName = mActivity.getPackageName();
String logPath = sdPath + File.separator + "sinovoice" + File.separator + packageName + File.separator + "log" + File.separator;
// 日志文件地址
File fileDir = new File(logPath);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
// 日志的路径,可选,如果不传或者为空则不生成日志
initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_PATH, logPath);
// 日志数目,默认保留多少个日志文件,超过则覆盖最旧的日志
initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_COUNT, "5");
// 日志大小,默认一个日志文件写多大,单位为K
initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_SIZE, "1024");
// 日志等级,0=无,1=错误,2=警告,3=信息,4=细节,5=调试,SDK将输出小于等于logLevel的日志信息
initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_LEVEL, "5");
}
return initparam;
}
/**
* 获取授权
*
* @return 授权结果
*/
private int checkAuthAndUpdateAuth() {
// 获取系统授权到期时间
int initResult;
AuthExpireTime objExpireTime = new AuthExpireTime();
initResult = HciCloudSys.hciGetAuthExpireTime(objExpireTime);
if (initResult == HciErrorCode.HCI_ERR_NONE) {
// 显示授权日期,如用户不需要关注该值,此处代码可忽略
Date date = new Date(objExpireTime.getExpireTime() * 1000);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
Log.i(TAG, "expire time: " + sdf.format(date));
if (objExpireTime.getExpireTime() * 1000 > System.currentTimeMillis()) {
// 已经成功获取了授权,并且距离授权到期有充足的时间(>7天)
Log.i(TAG, "checkAuth success");
return initResult;
}
}
// 获取过期时间失败或者已经过期
initResult = HciCloudSys.hciCheckAuth();
if (initResult == HciErrorCode.HCI_ERR_NONE) {
Log.i(TAG, "checkAuth success");
return initResult;
} else {
Log.e(TAG, "checkAuth failed: " + initResult);
return initResult;
}
}
}
使用
初始化
// 灵云语音工具类
HciUtil mInitTts = new HciUtil(this);
// 初始化灵云语音
boolean isInitHci = mInitTts.initHci();
if (isInitHci) { // 初始化成功
// 语音合成能力工具类
mTtsUtil = new TtsUtil(this);
// 初始化语音合成
isInitPlayer = mTtsUtil.initPlayer(this);
}
语音合成
/**
* 开始合成
*
* @param view v
*/
public void synth(View view) {
if (!isInitPlayer) {
Toast.makeText(this, "初始化失败", Toast.LENGTH_SHORT).show();
return;
}
String text = mEditText.getText().toString();
if (TextUtils.isEmpty(text)) {
Toast.makeText(this, "合成内容为空", Toast.LENGTH_SHORT).show();
return;
}
mTtsUtil.synth(text);
}
语音合成回调
// 语音合成的回调
@Override
public void onPlayerEventStateChange(TTSCommonPlayer.PlayerEvent playerEvent) {
}
@Override
public void onPlayerEventProgressChange(TTSCommonPlayer.PlayerEvent playerEvent, int i, int i1) {
}
@Override
public void onPlayerEventPlayerError(TTSCommonPlayer.PlayerEvent playerEvent, int i) {
}
灵云离线语音合成
离线语音合成相对也比较简单,首先要下载离线资源,下载完以后是一个zip包,解压缩里面有类似这样的几个文件
给每个文件重命名,前面加lib
,后面加后缀.so
,然后导入工程
导入资源文件以后,修改capKey为离线语音合成
public static final String CAP_KEY = "tts.local.synth";
注:灵云的离线语音能力,第一次使用的时候也是需要有一个联网授权的过程,授权成功以后,即可在授权期内使用离线语音能力。