当前位置: 移动技术网 > IT编程>移动开发>Android > 20.5 语音合成(百度2016年2月29日发布的tts引擎)

20.5 语音合成(百度2016年2月29日发布的tts引擎)

2019年07月24日  | 移动技术网IT编程  | 我要评论

2012315,万丽珠,另类套词

一、简介

编写手机app时,有时需要使用文字转语音(text to speech)的功能,比如开车时阅读收到的短信、导航语音提示、界面中比较重要的信息通过语音强调、……等。

由于android自带的pico tts并不支持中文,所以要既能阅读中文文本,还能阅读英文文本,必须下载第三方提供的能说中文的语音包。

二、申请百度tts授权

本节以百度2016年2月29日发布的“离在线融合语音合成sdk_android 2.2.3版”为例说明用c#实现语音合成的基本用法。之所以选择百度语音合成来实现,是因为据百度官网声明,该开发包是“永久免费”的。网址如下:

http://yuyin.baidu.com/tts/

由于原来已经申请过mydemos的授权,所以再继续申请tts授权就比较简单了,申请和设置步骤如下。

1、申请授权

进入 http://yuyin.baidu.com/tts/ 的首页:

单击【立即使用】,进入“开通语音合成服务”的页面:


在下拉框中选择原来已经申请的某个应用,单击【下一步】,然后按提示操作,开通离线服务即可。

2、在bdmapv371bindinglib项目中转换jar文件

先通过 http://yuyin.baidu.com/tts/ 首页中的【相关下载】下载对应的开发包,然后再按下面的步骤操作。

1、将示例中的com.baidu.tts_2.2.3.20160229_359d952_release.jar、galaxy-v2.0.jar添加到jars文件夹下,如下图所示,然后将其【生成操作】属性全部设置为“embeddedjar”。

2、在metadata.xml文件中添加下面的语句:

<remove-node path="/api/package[@name='com.baidu.tts.aop']/interface[@name='iproxyfactory']/method[@name='createproxied' and count(parameter)=0]" /> 

3、重新生成项目,此时应该无错误。

经过这3个步骤,就完成了tts的jar包导入和转换为.cs文件的过程。

3、在mydemos项目中添加.so文件

将tts相关的4个.so文件添加到mydemos项目的x86文件夹下,如下图所示,然后将其【生成操作】属性全部设置为“androidnativelibrary”。

4、将.dat文件添加到sd卡的baidutts文件夹下

具体添加办法见【常见问题解答】,这里不再截图。

也可以先将这些文件添加到assets文件夹下,然后通过代码将其复制到sd卡的文件夹下。为简化起见,这里通过手工直接复制了。

ok,经过上面这4步,以后就可以在mydemos项目中的任何模块中轻松利用百度tts实现语音阅读的功能了

三、示例

1、运行截图

单击【阅读】,就会自动用女音朗读文本框中的内容,单击【批量阅读】,就会依次朗读队列中添加的文字段(主要是为了演示阅读各种不同的中英文短句)。

2、设计步骤

(1)添加ch2005main.axml

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<linearlayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:weightsum="4">
<button
android:id="@+id/speak"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="阅读"
android:textsize="12dp" />
<button
android:id="@+id/pause"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="暂停"
android:textsize="12dp" />
<button
android:id="@+id/resume"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="继续"
android:textsize="12dp" />
<button
android:id="@+id/stop"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="停止"
android:textsize="12dp" />
</linearlayout>
<linearlayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:weightsum="4">
<button
android:id="@+id/synthesize"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="synthesize"
android:textsize="12dp" />
<button
android:id="@+id/play"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="play"
android:textsize="12dp" />
<button
android:id="@+id/batchspeak"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="批量阅读"
android:textsize="12dp" />
<button
android:id="@+id/nextactivity"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:enabled="false"
android:text="备用"
android:textsize="12dp" />
</linearlayout>
<edittext
android:id="@+id/input"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="input" />
<textview
android:id="@+id/showtext"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="10dp"
android:background="@android:color/darker_gray"
android:minlines="3"
android:scrollbars="vertical" />
</linearlayout>

2、添加ch2005mainactivity.cs

using system;
using system.collections.generic;
using system.linq;
using system.text;
using android.app;
using android.os;
using android.widget;
using com.baidu.tts.client;
using com.baidu.tts.answer.auth;
namespace mydemos.srcdemos
{
[activity(label = "【例20-5】百度tts基本用法")]
public class ch2005mainactivity : activity, ispeechsynthesizerlistener
{
private edittext minput;
private textview mshowtext;
private speechsynthesizer mspeechsynthesizer;
/// <summary>
/// sd卡上保存百度tts文件的路径
/// </summary>
private string msampledirpath;
private const string speechfemalemodelname = "bd_etts_speech_female.dat";
private const string speechmalemodelname = "bd_etts_speech_male.dat";
private const string textmodelname = "bd_etts_text.dat";
private const string englishspeechfemalemodelname = "bd_etts_speech_female_en.dat";
private const string englishspeechmalemodelname = "bd_etts_speech_male_en.dat";
private const string englishtextmodelname = "bd_etts_text_en.dat";
protected override void oncreate(bundle savedinstancestate)
{
base.oncreate(savedinstancestate);
setcontentview(resource.layout.ch2005main);
msampledirpath = android.os.environment.externalstoragedirectory.path + "/baidutts";
console.writeline("msampledirpath=" + msampledirpath);
initialview();
initialtts();
}
private void initialtts()
{
mspeechsynthesizer = speechsynthesizer.instance;
mspeechsynthesizer.setcontext(this);
mspeechsynthesizer.setspeechsynthesizerlistener(this);
// 文本模型文件路径 (离线引擎使用)
mspeechsynthesizer.setparam(speechsynthesizer.paramttstextmodelfile,
msampledirpath + "/" + textmodelname);
// 声学模型文件路径 (离线引擎使用)
mspeechsynthesizer.setparam(speechsynthesizer.paramttsspeechmodelfile,
msampledirpath + "/" + speechfemalemodelname);
// 请替换为语音开发者平台上注册应用得到的app id (离线授权)
//mspeechsynthesizer.setappid("your_app_id");
mspeechsynthesizer.setappid(ch.ttsappid);
// 请替换为语音开发者平台注册应用得到的apikey和secretkey (在线授权)
//this.mspeechsynthesizer.setapikey("your_api_key", "your_secret_key");
this.mspeechsynthesizer.setapikey(ch.ttsapikey, ch.ttssecretkey);
// 发音人(在线引擎),可用参数为0,1,2,3。。。(服务器端会动态增加,各值含义参考文档,以文档说明为准。0--普通女声,1--普通男声,2--特别男声,3--情感男声。。。)
mspeechsynthesizer.setparam(speechsynthesizer.paramspeaker, "0");
// 设置mix模式的合成策略
mspeechsynthesizer.setparam(speechsynthesizer.parammixmode, speechsynthesizer.mixmodedefault);
// 授权检测接口(可以不使用,只是验证授权是否成功)
authinfo authinfo = this.mspeechsynthesizer.auth(ttsmode.mix);
if (authinfo.issuccess)
{
console.writeline("授权检测--授权成功(auth success)。");
}
else
{
string errormsg = authinfo.ttserror.detailmessage;
console.writeline("授权检测--授权失败(auth failed),errormsg=" + errormsg);
}
// 初始化tts
mspeechsynthesizer.inittts(ttsmode.mix);
// 加载离线英文资源(提供离线英文合成功能)
int result = mspeechsynthesizer.loadenglishmodel(
msampledirpath +
"/" + englishtextmodelname, msampledirpath +
"/" + englishspeechfemalemodelname);
}
private void initialview()
{
minput = findviewbyid<edittext>(resource.id.input);
minput.text = "今天阳光明媚,风和日丽!";
mshowtext = findviewbyid<textview>(resource.id.showtext);
var speak = findviewbyid<button>(resource.id.speak);
speak.click += delegate
{
string text = this.minput.text;
int result = this.mspeechsynthesizer.speak(text);
if (result < 0)
{
system.diagnostics.debug.writeline("出错了,错误码:{0},请检查百度tts文档中对应错误码的含义。", result);
}
};
var pause = findviewbyid<button>(resource.id.pause);
pause.click += delegate
{
mspeechsynthesizer.pause();
};
var resume = findviewbyid<button>(resource.id.resume);
resume.click += delegate
{
mspeechsynthesizer.resume();
};
var stop = findviewbyid<button>(resource.id.stop);
stop.click += delegate
{
mspeechsynthesizer.stop();
};
var synthesize = findviewbyid<button>(resource.id.synthesize);
synthesize.click += delegate
{
string text = this.minput.text;
int result = this.mspeechsynthesizer.synthesize(text);
if (result < 0)
{
system.diagnostics.debug.writeline("error,please look up error code in doc or url:http://yuyin.baidu.com/docs/tts/122 ");
}
};
var play = findviewbyid<button>(resource.id.play);
play.click += delegate { };
var batchspeak = findviewbyid<button>(resource.id.batchspeak);
batchspeak.click += delegate
{
list<speechsynthesizebag> bags = new list<speechsynthesizebag>();
bags.add(getspeechsynthesizebag("123456", "0"));
bags.add(getspeechsynthesizebag("你好", "1"));
bags.add(getspeechsynthesizebag("使用百度语音合成sdk", "2"));
bags.add(getspeechsynthesizebag("hello", "3"));
bags.add(getspeechsynthesizebag("这是一个demo工程", "4"));
int result = this.mspeechsynthesizer.batchspeak(bags);
if (result < 0)
{
system.diagnostics.debug.writeline("error({0}),please look up error code in doc or url:http://yuyin.baidu.com/docs/tts/122 ", result);
}
};
}
protected override void ondestroy()
{
base.ondestroy();
}
private speechsynthesizebag getspeechsynthesizebag(string text, string utteranceid)
{
speechsynthesizebag speechsynthesizebag = new speechsynthesizebag();
speechsynthesizebag.settext(text);
speechsynthesizebag.utteranceid = utteranceid;
return speechsynthesizebag;
}
public void onerror(string utteranceid, speecherror error)
{
console.writeline("onerror error=" + error.description + "--utteranceid=" + utteranceid);
}
public void onspeechfinish(string utteranceid)
{
console.writeline("onspeechfinish utteranceid=" + utteranceid);
}
public void onspeechprogresschanged(string p0, int p1)
{
//console.writeline("onspeechprogresschanged");
}
public void onspeechstart(string utteranceid)
{
console.writeline("onspeechstart utteranceid=" + utteranceid);
}
public void onsynthesizedataarrived(string utteranceid, byte[] data, int progress)
{
console.writeline("onsynthesizedataarrived");
}
public void onsynthesizefinish(string utteranceid)
{
console.writeline("onspeechfinish utteranceid=" + utteranceid);
}
public void onsynthesizestart(string utteranceid)
{
console.writeline("onsynthesizestart utteranceid=" + utteranceid);
}
}
}

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网