欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Studio应用开发集成百度语音合成使用方法实例讲解

程序员文章站 2024-03-02 10:47:10
首先,语音合成是指将文本信息转换成声音。意思就是将文本转化为声音,让你的应用开口说话。国内在业内比较有名的第三方语音合成平台有百度语音和科大讯飞。 本文集成的是百度语音合...

首先,语音合成是指将文本信息转换成声音。意思就是将文本转化为声音,让你的应用开口说话。国内在业内比较有名的第三方语音合成平台有百度语音和科大讯飞。

本文集成的是百度语音合成,其主要特点是:

完全永久免费

业界首创完全永久免费新形式,为开发者提供最流畅最自然的语音合成服务。完全免费,永久使用,彻底摆脱限制。

离线在线融合模式

sdk可以根据当前网络状况,自动判断使用本地引擎还是云端引擎进行语音合成,再也不用担心流量消耗!

多语言多音色可选

中文普通话、中英文混读、男声、女声任你选,更支持语速、音调、音量、音频码率设置,让你的应用拥有最甜美和最磁性的声音!

流畅自然的合成效果

语音合成技术业界领先,合成效果接近真人发声,流畅自然,且极具表现力,给你最舒适的听觉体验!

百度语音官方的demo是在eclipse环境下编写的,而在android studio中则有点小区别,下面请看百度语音合成使用详细步骤(一步一步操作不要跳跃心急吃不了热豆腐):

1、注册百度语音开发者平台

注册百度账号,注册开发者信息,创建应用,可以得到 app id、 api key、和 secret key,在开发过程中会使用这三个值进行授权(很关键),开通语音合成服务,若需要使用离线合成功能还需要申请离线授权。详细步骤请看百度语音接入流程 。

key值查看(很关键)

Android Studio应用开发集成百度语音合成使用方法实例讲解

2、下载资源

下载百度语音sdk,根据自己的需要下载,本样例下载的是离在线融合语音合成sdk_android版 , 地址: http://yuyin.baidu.com/tts/download

3、集成百度语音指南

3.1添加 jar 包和 so 库到工程

将开发包中的 libs 目录整体拷贝到工程目录(eclipse的用户),libs 目录包括了jar包和各平台的 so 库,开发者视应用需要可以进行删减。galaxy_lite.jar 是百度 android 公共基础库,如果项目中还集成了其它百度 sdk,
如 push sdk,在打包过程中出现类似如下的错误信息:

[2013-10-22 11:02:57 - dex loader] unable to execute dex: multiple dex files define
lcom/baidu/android/common/logging/configuration;
[2013-10-22 11:02:57 - voicerecognitiondemo] conversion to dalvik format failed: unable to
execute dex: multiple dex files define lcom/baidu/android/common/logging/configuration;

请将此 jar 包移除。对于使用android studio的用户,应将libs目录中的jar包放在libs目录下,然后添加库依赖(千万别忘记), 而 .so 库则应该放在jnilibs目录下, jnilibs目录与java、res在相同目录下。若没有相应的目录就自己创建。整个结构如下图:

Android Studio应用开发集成百度语音合成使用方法实例讲解

3.2 添加语音合成资源文件

将开发包中的 data 目录下的 dat 文件放到工程的assets目录下,assets目录与java、res在同一目录下,以便设置资源文件参数时使用。

3.3 权限声明

使用百度语音需要声明以下权限:

<uses-permission android:name="android.permission.internet" />
<uses-permission android:name="android.permission.access_network_state" />
<uses-permission android:name="android.permission.modify_audio_settings" />
<uses-permission android:name="android.permission.write_external_storage" />
<uses-permission android:name="android.permission.write_settings" />
<uses-permission android:name="android.permission.read_phone_state" />
<uses-permission android:name="android.permission.access_wifi_state" />
<uses-permission android:name="android.permission.change_wifi_state" />

4、语音合成功能代码

4、1 tts初始化

//获取 tts 实例 
speechsynthesizer = speechsynthesizer.getinstance(); 
//设置 app 上下文(必需参数) 
speechsynthesizer.setcontext(context); 
//设置 tts 监听器 
speechsynthesizer.setspeechsynthesizerlistener(speechsynthesizerlistener);
//文本模型文件路径,文件的绝对路径 (离线引擎使用) 
speechsynthesizer.setparam(speechsynthesizer.param_tts_text_model_file, 
text_model_file_full_path_name); 
//声学模型文件路径,文件的绝对路径 (离线引擎使用) 
speechsynthesizer.setparam(speechsynthesizer.param_tts_speech_model_file, 
speech_model_file_full_path_name); 
// 本 地 授 权 文 件 路 径 , 如 未 设 置 将 使 用 默 认 路 径 . 设 置 临 时 授 权 文 件 路 径 ,
//licence_file_name 请替换成临时授权文件的实际路径,仅在使用临时 license 文件时需要进行设置,
//如果在[应用管理]中开通了离线授权,不需要设置该参数,建议将该行代码删除(离线引擎) 
speechsynthesizer.setparam(speechsynthesizer.param_tts_licence_file, 
license_file_full_path_name); 
//请替换为语音开发者平台上注册应用得到的 app id (离线授权) 
speechsynthesizer.setappid("your_app_id"); 
//请替换为语音开发者平台注册应用得到的 apikey 和 secretkey (在线授权) 
speechsynthesizer.setapikey("your_api_key", "your_secret_key"); 
//授权检测接口 
authinfo authinfo = speechsynthesizer.auth(ttsmode); 
//引擎初始化接口 
speechsynthesizer.inittts(ttsmode);

注意:在初始化设置之前先把assets文件夹中的资源文件拷贝到sd卡中,以便使用。另外,离线授权临时文件有效期只有30天,若要长久使用语音离线合成应在应用管理中开通离线授权。

4、2合成并播放

mspeechsynthesizer.speak(text);

该接口比较耗时,采用排队策略,调用后将自动加入合成队列,并按调用顺序进行合成和播放。

好了,到此你的语音合成就可以使用了,若想要进行更多参数设置,请看百度语音合成官方开发文档 和开发手册。

5、源码

最后贴上我的源码。

manifest文件: androidmanifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.junkchen.bdttsdemo">
<uses-permission android:name="android.permission.internet" />
<uses-permission android:name="android.permission.access_network_state" />
<uses-permission android:name="android.permission.modify_audio_settings" />
<uses-permission android:name="android.permission.write_external_storage" />
<uses-permission android:name="android.permission.write_settings" />
<uses-permission android:name="android.permission.read_phone_state" />
<uses-permission android:name="android.permission.access_wifi_state" />
<uses-permission android:name="android.permission.change_wifi_state" />
<application
android:allowbackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsrtl="true"
android:theme="@style/apptheme">
<activity android:name=".mainactivity">
<intent-filter>
<action android:name="android.intent.action.main" />
<category android:name="android.intent.category.launcher" />
</intent-filter>
</activity>
</application>
</manifest>

layout布局文件: activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context="com.junkchen.bdttsdemo.mainactivity">
<edittext
android:id="@+id/edt_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:minlines="5"
android:text="hi 我是百度语音合成,请输入要合成的语音内容" />
<button
android:id="@+id/btn_speak"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="语音合成并播放" />
</linearlayout>

java: mainactivity.java

package com.junkchen.bdttsdemo;
import android.os.bundle;
import android.os.environment;
import android.support.v7.app.appcompatactivity;
import android.util.log;
import android.view.view;
import android.widget.button;
import android.widget.edittext;
import com.baidu.tts.answer.auth.authinfo;
import com.baidu.tts.client.speecherror;
import com.baidu.tts.client.speechsynthesizer;
import com.baidu.tts.client.speechsynthesizerlistener;
import com.baidu.tts.client.ttsmode;
import java.io.file;
import java.io.filenotfoundexception;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
public class mainactivity extends appcompatactivity implements speechsynthesizerlistener {
private static final string tag = "mainactivity";
private speechsynthesizer mspeechsynthesizer;//百度语音合成客户端
private string msampledirpath;
private static final string sample_dir_name = "baidutts";
private static final string speech_female_model_name = "bd_etts_speech_female.dat";
private static final string speech_male_model_name = "bd_etts_speech_male.dat";
private static final string text_model_name = "bd_etts_text.dat";
private static final string license_file_name = "temp_license_2016-04-05";
private static final string english_speech_female_model_name = "bd_etts_speech_female_en.dat";
private static final string english_speech_male_model_name = "bd_etts_speech_male_en.dat";
private static final string english_text_model_name = "bd_etts_text_en.dat";
private static final string app_id = "7957876";//请更换为自己创建的应用
private static final string api_key = "cvn31pilxbhrndgdlnhyeuyq";//请更换为自己创建的应用
private static final string secret_key = "84e6987b56f11e6ee97e02ef25a2b4f0";//请更换为自己创建的应用
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
initialenv();
initialtts();
initview();
}
@override
protected void ondestroy() {
this.mspeechsynthesizer.release();//释放资源
super.ondestroy();
}
private edittext edt_content;
private button btn_speak;
private void initview() {
edt_content = (edittext) findviewbyid(r.id.edt_content);
btn_speak = (button) findviewbyid(r.id.btn_speak);
btn_speak.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
string content = edt_content.gettext().tostring();
mspeechsynthesizer.speak(content);
log.i(tag, ">>>say: " + edt_content.gettext().tostring());
}
});
}
/**
* 初始化语音合成客户端并启动
*/
private void initialtts() {
//获取语音合成对象实例
this.mspeechsynthesizer = speechsynthesizer.getinstance();
//设置context
this.mspeechsynthesizer.setcontext(this);
//设置语音合成状态监听
this.mspeechsynthesizer.setspeechsynthesizerlistener(this);
//文本模型文件路径 (离线引擎使用)
this.mspeechsynthesizer.setparam(speechsynthesizer.param_tts_text_model_file, msampledirpath + "/"
+ text_model_name);
//声学模型文件路径 (离线引擎使用)
this.mspeechsynthesizer.setparam(speechsynthesizer.param_tts_speech_model_file, msampledirpath + "/"
+ speech_female_model_name);
//本地授权文件路径,如未设置将使用默认路径.设置临时授权文件路径,licence_file_name请替换成临时授权文件的实际路径,
//仅在使用临时license文件时需要进行设置,如果在[应用管理]中开通了离线授权,
//不需要设置该参数,建议将该行代码删除(离线引擎)
this.mspeechsynthesizer.setparam(speechsynthesizer.param_tts_licence_file, msampledirpath + "/"
+ license_file_name);
//请替换为语音开发者平台上注册应用得到的app id (离线授权)
this.mspeechsynthesizer.setappid(app_id);
// 请替换为语音开发者平台注册应用得到的apikey和secretkey (在线授权)
this.mspeechsynthesizer.setapikey(api_key, secret_key);
//发音人(在线引擎),可用参数为0,1,2,3。。。
//(服务器端会动态增加,各值含义参考文档,以文档说明为准。0--普通女声,1--普通男声,2--特别男声,3--情感男声。。。)
this.mspeechsynthesizer.setparam(speechsynthesizer.param_speaker, "0");
// 设置mix模式的合成策略
this.mspeechsynthesizer.setparam(speechsynthesizer.param_mix_mode, speechsynthesizer.mix_mode_default);
// 授权检测接口(可以不使用,只是验证授权是否成功)
authinfo authinfo = this.mspeechsynthesizer.auth(ttsmode.mix);
if (authinfo.issuccess()) {
log.i(tag, ">>>auth success.");
} else {
string errormsg = authinfo.getttserror().getdetailmessage();
log.i(tag, ">>>auth failed errormsg: " + errormsg);
}
// 引擎初始化tts接口
mspeechsynthesizer.inittts(ttsmode.mix);
// 加载离线英文资源(提供离线英文合成功能)
int result =
mspeechsynthesizer.loadenglishmodel(msampledirpath + "/" + english_text_model_name, msampledirpath
+ "/" + english_speech_female_model_name);
log.i(tag, ">>>loadenglishmodel result: " + result);
}
@override
public void onsynthesizestart(string s) {
//监听到合成开始
log.i(tag, ">>>onsynthesizestart()<<< s: " + s);
}
@override
public void onsynthesizedataarrived(string s, byte[] bytes, int i) {
//监听到有合成数据到达
log.i(tag, ">>>onsynthesizedataarrived()<<< s: " + s);
}
@override
public void onsynthesizefinish(string s) {
//监听到合成结束
log.i(tag, ">>>onsynthesizefinish()<<< s: " + s);
}
@override
public void onspeechstart(string s) {
//监听到合成并开始播放
log.i(tag, ">>>onspeechstart()<<< s: " + s);
}
@override
public void onspeechprogresschanged(string s, int i) {
//监听到播放进度有变化
log.i(tag, ">>>onspeechprogresschanged()<<< s: " + s);
}
@override
public void onspeechfinish(string s) {
//监听到播放结束
log.i(tag, ">>>onspeechfinish()<<< s: " + s);
}
@override
public void onerror(string s, speecherror speecherror) {
//监听到出错
log.i(tag, ">>>onerror()<<< description: " + speecherror.description + ", code: " + speecherror.code);
}
private void initialenv() {
if (msampledirpath == null) {
string sdcardpath = environment.getexternalstoragedirectory().tostring();
msampledirpath = sdcardpath + "/" + sample_dir_name;
}
file file = new file(msampledirpath);
if (!file.exists()) {
file.mkdirs();
}
copyfromassetstosdcard(false, speech_female_model_name, msampledirpath + "/" + speech_female_model_name);
copyfromassetstosdcard(false, speech_male_model_name, msampledirpath + "/" + speech_male_model_name);
copyfromassetstosdcard(false, text_model_name, msampledirpath + "/" + text_model_name);
copyfromassetstosdcard(false, license_file_name, msampledirpath + "/" + license_file_name);
copyfromassetstosdcard(false, "english/" + english_speech_female_model_name, msampledirpath + "/"
+ english_speech_female_model_name);
copyfromassetstosdcard(false, "english/" + english_speech_male_model_name, msampledirpath + "/"
+ english_speech_male_model_name);
copyfromassetstosdcard(false, "english/" + english_text_model_name, msampledirpath + "/"
+ english_text_model_name);
}
/**
* 将工程需要的资源文件拷贝到sd卡中使用(授权文件为临时授权文件,请注册正式授权)
*
* @param iscover 是否覆盖已存在的目标文件
* @param source
* @param dest
*/
public void copyfromassetstosdcard(boolean iscover, string source, string dest) {
file file = new file(dest);
if (iscover || (!iscover && !file.exists())) {
inputstream is = null;
fileoutputstream fos = null;
try {
is = getresources().getassets().open(source);
string path = dest;
fos = new fileoutputstream(path);
byte[] buffer = new byte[1024];
int size = 0;
while ((size = is.read(buffer, 0, 1024)) >= 0) {
fos.write(buffer, 0, size);
}
} catch (filenotfoundexception e) {
e.printstacktrace();
} catch (ioexception e) {
e.printstacktrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
try {
if (is != null) {
is.close();
}
} catch (ioexception e) {
e.printstacktrace();
}
}
}
}
}

以上所述是小编给大家介绍的android studio应用开发集成百度语音合成使用方法实例讲解,希望对大家有所帮助