編輯:關於Android編程
首先,語音合成是指將文本信息轉換成聲音。意思就是將文本轉化為聲音,讓你的應用開口說話。國內在業內比較有名的第三方語音合成平台有百度語音和科大訊飛。
本文集成的是百度語音合成,其主要特點是:
完全永久免費
業界首創完全永久免費新形式,為開發者提供最流暢最自然的語音合成服務。完全免費,永久使用,徹底擺脫限制。
離線在線融合模式
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應用開發集成百度語音合成使用方法實例講解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對本站網站的支持!
在Android中和我們打交道最多的就是Activity,因為我們會頻繁的與界面進行交互,而Activity內部關於界面方面的操作都是由Window來實現的,因此我們有必
本系列文章主要介紹如何利用Android開發一個簡單的健康食譜軟件。用到的相關技術如下所示:提供GridView和ListView的基本使用利用univers
1、效果圖如下:這效果用戶體驗還是很酷炫,今天我們就來講解如何實現這個效果。2、分析為了方便理解,作圖分析如圖所示,整個頁面分為四個部分: &nbs
現在的微信推送已為最新版6.2。不知你是否注意到新版本微信中有一個新功能——收錢。微信這款功能能夠及時的幫助大家還款和收款,只要掃一