Android—实现科大讯飞语音合成
背景(可以不看)
实验室项目开发的APP需要有语音提示功能,之前的做法是人工录音,剪辑片段,调用Android的多媒体,播放,呵呵呵,,,这是21世纪!这样肯定显得有点low啊,且不说档次,应用场景也不足啊,人工录音内容固定,这不适合我们的需求。其实我当时也不知道这技术叫语音合成,老师提了一提,下来一百度,科大讯飞果断站了出来,提供了API,给你点个赞!这里介绍一下如何使用该API中的语音合成技术。
准备工作
注册开发者APPID
首先需要做的就是注册能够使用该API的APPID,如今使用这种API都需要注册,比如百度地图API等,不想多说,并向你抛出了个链接 http://www.xfyun.cn
导入SDK
注册完APPDID之后,下载开发包,解压缩,得到如下文件,在Android Studio项目结构下的app下新建libs,将其中的文件全部copy到libs下,如下图所示:
这里要注意啊,导进来要进行Gradle的编译啊,并且注意到每一项前面的三角符号是可以点开的,下面有内容的,这是需要编译之后才有,如果不能打开,相当于只是添加了些文件,后面使用里面的类,代码无法自动提示,MB,都没编译进来,有个屁啊,(本人踩过的坑,手动捂脸)
添加用户权限
需要配置如下权限
<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--读取联系人权限,上传联系人需要用到此权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--外存储写权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存储读权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置权限,用来记录应用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人脸识别,还要添加:摄相头权限,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />
配置Gradle
使用AS开发Android Application Gradle的配置少不了,官方的文档上没有指出需要配置Gradle,但是事实证明不配置的话,会出现一个很奇怪的异常,在Module下的build.gradle
文件:
- 在
defaultConfig
下添加以下内容:
// 配置.so文件
ndk {
// 选择要添加的对应的cpu类型的.so库
abiFilters 'x86', 'armeabi', 'armeabi-v7a', 'armeabi-v8a', 'mips','mips64','x86_64'
}
- 在
buildTypes
下添加以下内容:
//配置JNILibs
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
到这里,准备工作应该是准备完成了
干正事
SDK的初始化
初始化就一句话
// 进行SDK的初始化
SpeechUtility.createUtility(APP.this, SpeechConstant.APPID + "=yourAPPID");
这句话一般写在app初始化时,如果你是写demo,只有一个Activity,那么就写在onCreate之后就可以,但是我相信,真正使用绝非这么简单,所以配置到APP文件中最好,我一开始不知道什么是APP文件(手动捂脸,好low),其实APP文件是一个java类文件,继承Application,如下图:
Application这个类,一看就应该明了,是我们每个应用程序都用的,然后如何将我们新建的APP和我们的Android程序关联,看下图:
这是AndroidManifest.xml
下的配置项,将这里的application指定为我们自己创建的java类文件即可,看到.APP
前面的那一个.
点没有,表示路径,说明我们的APP.java类直接在我们的包名下。如下图:
这里com.jiajia.speechdemo
就是我的包名。
封装语音合成工具类
在上面的截图中有一个TTSUtility类,没错,我们把语音合成疯转在一个工具类中。同时将其打造成单例模式。这样在我们整个应用程序中,只有一个工具类,就不用每次需要合成是都new一个对象
public class TTSUtility {
// 发音人
public final static String[] COLOUD_VOICERS_VALUE = {"xiaoyan", "xiaoyu", "catherine", "henry", "vimary", "vixy", "xiaoqi", "vixf", "xiaomei","xiaolin", "xiaorong", "xiaoqian", "xiaokun", "xiaoqiang", "vixying", "xiaoxin", "nannan", "vils",};
private static final String TAG = "TTSUtility";
// 语音合成对象
private static SpeechSynthesizer mTts;
//上下文
private Context mContext;
private volatile static TTSUtility instance;
/**
* 合成回掉监听
*/
private static SynthesizerListener mTtsListener = new SynthesizerListener() {
@Override
public void onSpeakBegin() {
Log.d(TAG, "开始播放");
}
@Override
public void onBufferProgress(int percent, int beginPos, int endPos, String info) {
// TODO 缓冲的进度
Log.d(TAG, "缓冲 : " + percent);
}
@Override
public void onSpeakPaused() {
Log.d(TAG, "暂停播放");
}
@Override
public void onSpeakResumed() {
Log.d(TAG, "继续播放");
}
@Override
public void onSpeakProgress(int percent, int beginPos, int endPos) {
// TODO 说话的进度
Log.d(TAG, "合成 : " + percent);
}
@Override
public void onCompleted(SpeechError error) {
if (error == null) {
Log.d(TAG, "播放完成");
} else if (error != null) {
Log.d(TAG, error.getPlainDescription(true));
}
}
@Override
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
}
};
/**
* 构造方法
*
* @param context 上下文
*/
private TTSUtility(Context context) {
mContext = context;
// 初始化合成对象
mTts = SpeechSynthesizer.createSynthesizer(mContext, new InitListener() {
@Override
public void onInit(int code) {
if (code != ErrorCode.SUCCESS) {
Log.d("fjj", "初始化失败,错误码:" + code);
}
Log.d("fjj", "初始化失败,q错误码:" + code);
}
});
}
public static TTSUtility getInstance(Context context) {
if (instance == null) {
synchronized (TTSUtility.class) {
if (instance == null) {
instance = new TTSUtility(context);
}
}
}
return instance;
}
/**
* 停止语音播报
*/
public static void stopSpeaking() {
// 对象非空并且正在说话
if (null != mTts && mTts.isSpeaking()) {
// 停止说话
mTts.stopSpeaking();
}
}
/**
* 判断当前有没有说话
*
* @return
*/
public static boolean isSpeaking() {
if (null != mTts) {
return mTts.isSpeaking();
} else {
return false;
}
}
/**
* 开始合成
*
* @param text
*/
public void speaking(String text) {
if (TextUtils.isEmpty(text))
return;
int code = mTts.startSpeaking(text, mTtsListener);
Log.d("fjj", "-----" + code + "++++++++++");
if (code != ErrorCode.SUCCESS) {
if (code == ErrorCode.ERROR_COMPONENT_NOT_INSTALLED) {
Toast.makeText(mContext, "没有安装语音+ code = " + code, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mContext, "语音合成失败,错误码: " + code, Toast.LENGTH_SHORT).show();
}
}
}
/**
* 参数设置
*
* @return
*/
private void setParam() {
// 清空参数
mTts.setParameter(SpeechConstant.PARAMS, null);
// 引擎类型 网络
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
// 设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, COLOUD_VOICERS_VALUE[0]);
// 设置语速
mTts.setParameter(SpeechConstant.SPEED, "50");
// 设置音调
mTts.setParameter(SpeechConstant.PITCH, "50");
// 设置音量
mTts.setParameter(SpeechConstant.VOLUME, "100");
// 设置播放器音频流类型
mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");
// mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/KRobot/wavaudio.pcm");
// 背景音乐 1有 0 无
// mTts.setParameter("bgs", "1");
}
}
这样封装之后在任何你想要"说话"的地方直接调用下面者句话就可以;
TTSUtility.getInstance(getApplicationContext()).speaking("编程使我快乐");
可以看到封装的工具类中可以进行参数的设置,主要包括以下内容:
语言(LANGUAGE,中文、英文等)
方言(ACCENT,中文的普通话,粤语等)
发音人特征(性别,年龄,语气)
语速(SPEED)
音量(VOLUME)
语调(PITCH)
音频采样率(SAMPLE_RATE)
感兴趣可以自己多尝试!
参考资料
最后
- 本文内容个人拙见,若有出入,欢迎指正。
- 欢迎赏脸关注:家佳Talk
Android—实现科大讯飞语音合成的更多相关文章
- C#将科大讯飞语音合成文件转换为MULAW音频格式
任务描述:通过科大讯飞语音合成组件在线完成文本转语音的合成,然后再转换为电话系统IVR要求的音频格式: wave mu-law 16位 8kHZ 64kbps. 完成步骤: 首先,我们要先通过科大讯飞 ...
- 科大讯飞语音合成系统 V5.0绿色便携版
中文名: 中科大讯飞Interphonic 5.0语音合成系统英文名: Interphonic 5.0版本: 5.0发行时间: 2006年制作发行: 中科大讯飞语言: 简体中文系统简介InterPho ...
- Android集成科大讯飞SDK语音听写及语音合成功能实现
前言 现在软件设计越来越人性化.智能化.一些常见的输入都慢慢向语音听写方向发展,一些常见的消息提示都向语音播报发展.所以语音合成和语音听写是手机软件开发必不可少的功能.目前国内这方面做的比较好的应该是 ...
- ROS语音交互——科大讯飞语音合成TTS(二)
之前我用过科大讯飞的语音包,为了记录一下我重新使用一下 首先注册科大讯飞账号及应用,以后每个下载的在线使用SDK都是以此账户ID登录讯飞语音服务器. 下载科大讯飞在线合成包. $ unzip Linu ...
- Unicode浅析——调用科大讯飞语音合成接口(日语)所遇到的天坑
如题,最近做的项目需要调用科大讯飞的语音合成接口,将日文合成日语.然后坑爹的是跟我对接的那一方直接扔过来一份接口文档,里面并未提及日语合成所需要的参数.中文.英文合成倒是没问题,就这个日语合成的音频始 ...
- 科大讯飞语音合成api
import base64import jsonimport timeimport hashlibimport requests # API请求地址.API KEY.APP ID等参数,提前填好备用a ...
- 科大讯飞和Tizen-TTS语音合成引擎
最近在做一个文本转语音TTS(Text to Speech)的第三方软件封装,使用的是国内语音技术龙头安徽科大讯飞公司提供的离线引擎AiSound5.0,主要用于汽车导航用途.科大讯飞还提供 了AiT ...
- 语音语音合成科大讯飞和Tizen-TTS语音合成引擎
废话就不多说了,开始... 最近在做一个文本转语音TTS(Text to Speech)的第三方软件封装,应用的是海内语音技术龙头安徽科大讯飞公司提供的离线引擎AiSound5.0,重要用于 ...
- Android文字转语音引擎(TTS)使用
百度网盘下载地址 密码:3si0资源来源:https://blog.csdn.net/Sqq_yj/article/details/82460580?utm_source=blogxgwz4 简单比较 ...
随机推荐
- Struts2知识点小结(四)--拦截器与注解开发
一.Struts2的拦截器(interceptor) 作用:当请求进入struts2框架后(进入之前可以用filter进行拦截),想对请求进行拦截操作(功能增强.权限控制),需要拦截器组件 1.str ...
- JVM 垃圾回收机制和常见算法和 JVM 的内存结构和内存分配(面试题)
一.JVM 垃圾回收机制和常见算法 Sun 公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同.GC(Garbage Collector)在回收对象前首先必 ...
- vue组件的基本知识点
1. 组件中 is 的特性: 有些 HTML 元素,诸如 <ul>.<ol>.<table> 和 <select>,对于哪些元素可以出现在其内部是有严格 ...
- Mysqldump自定义导出n条记录
很多时候DBA需要导出部分记录至开发.测试环境,因数据量需求较小,如果原库的记录多,且表数量也多,在用mysqldump命令导出时可以添加一个where参数,自定义导出n条记录,而不必全量导出. 示例 ...
- JS 红包随机
微信随机红包,指定金额指定用户,随机发送红包 var moneys = new Array(); var moneyTotal = 0; function rand(obj){ if(obj.size ...
- SpringMVC+Mybatis框架搭建
一.新建javaweb项目,并建好相应的包结构 二.添加项目jar到lib目录下 三.在config包中新建配置文件 sping-mvc.xml,内容如下: <?xml version=&quo ...
- while else
count = 0 while count <= 5 : count += 1 if count == 3:pass print("Loop",count) else: pr ...
- 43-Identity MVC:UI
1-打开之前写的MvcCookieAuthSample项目, 在AccountController新加Register,Login方法 public class AccountController : ...
- python操作nosql数据库之memcache
一.memcache的安装 1.memcache简介 Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象减少读取数据库的次数,从而 ...
- Python操作nosql数据库之redis
一.NoSQL的操作 NoSQL,泛指非关系型的数据库.随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不 ...