首先,语音合成是指将文本信息转换成声音。意思就是将文本转化为声音,让你的应用开口说话。国内在业内比较有名的第三方语音合成平台有百度语音和科大讯飞。
本文集成的是百度语音合成,其主要特点是:
完全永久免费
业界首创完全永久免费新形式,为开发者提供最流畅最自然的语音合成服务。完全免费,永久使用,彻底摆脱限制。
离线在线融合模式
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应用开发集成百度语音合成使用方法实例讲解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
1.1.1. TTS 1.1.1. TTS 我们的语音合成接口使用 C/S 架构,服务端默认启动,开发者需要通过调用客户端接口与服务端通讯,TTS服务架构图如下: 客户端头文件目录位于: #include <tts/tts_client.h> 除了要 include 头文件外,还需要链接 -lrktts。 API int tts_init(); // tts初始化接口 int tts_spe
1.1. TTS(语音合成) HTTP接口文档 1.1.1. 概述 1.1.2. 服务地址 1.1.3. 协议详解 1.1.4. 协议概述 1.1. TTS(语音合成) HTTP接口文档 1.1.1. 概述 本文档目的是描述Rokid云TTS(语音合成)HTTP接口协议,面向想要了解TTS细节,并具有一定开发能力的开发者或用户。 1.1.2. 服务地址 环境 地址 用途 线上 https://ma
1.1. TTS(语音合成) WebSocket接口文档 1.1.1. 概述 1.1.2. 服务地址 1.1.3. 协议详解 1.1.4. 协议地址 1.1.5. 协议概述 1.1. TTS(语音合成) WebSocket接口文档 1.1.1. 概述 本文档目的是描述Rokid云TTS(语音合成)WebSocket接口协议,面向想要了解TTS细节,并具有一定开发能力的开发者或用户。 1.1.2.
1.1.1. 开放平台接口定义文档(http版) - 语音合成 1.1.2. 简介 1.1.3. 编解码 1.1.4. 认证方式 1.1.5. Curl示例 1.1.6. 设备认证 1.2. 语音合成API 1.2.1. 请求URL 1.2.2. proto 文件 1.2.3. 请求和回复数据 1.1.1. 开放平台接口定义文档(http版) - 语音合成 1.1.2. 简介 Rokid语音合成服
1.1.1. 语音合成 WebSocket 接口定义文档 1.1.2. 概述 1.1.3. 协议详解 1.1.4. 服务地址 1.1.5. 协议地址 1.1.6. 协议概述 1.1.1. 语音合成 WebSocket 接口定义文档 1.1.2. 概述 本文档目的是描述云端语音接口的 WebSocket 版本的开放协议,面向想要了解语音合成(TTS)细节,并具有一定开发能力的开发者或用户。 1.1.
本文向大家介绍Python Web版语音合成实例详解,包括了Python Web版语音合成实例详解的使用技巧和注意事项,需要的朋友参考一下 前言 语音合成技术能将用户输入的文字,转换成流畅自然的语音输出,并且可以支持语速、音调、音量设置,打破传统文字式人机交互的方式,让人机沟通更自然。 应用场景 将游戏场景中的公告、任务或派单信息通过语音播报,让玩家玩游戏或配送员送货的同时,也可接听新任务。 文学