Android Studio应用开发集成百度语音合成使用方法实例讲解
首先,语音合成是指将文本信息转换成声音。意思就是将文本转化为声音,让你的应用开口说话。国内在业内比较有名的第三方语音合成平台有百度语音和科大讯飞。
本文集成的是百度语音合成,其主要特点是:
完全永久免费
业界首创完全永久免费新形式,为开发者提供最流畅最自然的语音合成服务。完全免费,永久使用,彻底摆脱限制。
离线在线融合模式
sdk可以根据当前网络状况,自动判断使用本地引擎还是云端引擎进行语音合成,再也不用担心流量消耗!
多语言多音色可选
中文普通话、中英文混读、男声、女声任你选,更支持语速、音调、音量、音频码率设置,让你的应用拥有最甜美和最磁性的声音!
流畅自然的合成效果
语音合成技术业界领先,合成效果接近真人发声,流畅自然,且极具表现力,给你最舒适的听觉体验!
百度语音官方的demo是在eclipse环境下编写的,而在android studio中则有点小区别,下面请看百度语音合成使用详细步骤(一步一步操作不要跳跃心急吃不了热豆腐):
1、注册百度语音开发者平台
注册百度账号,注册开发者信息,创建应用,可以得到 app id、 api key、和 secret key,在开发过程中会使用这三个值进行授权(很关键),开通语音合成服务,若需要使用离线合成功能还需要申请离线授权。详细步骤请看百度语音接入流程 。
key值查看(很关键)
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在相同目录下。若没有相应的目录就自己创建。整个结构如下图:
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应用开发集成百度语音合成使用方法实例讲解,希望对大家有所帮助