Android Google TTS

Google TTS相對於其他TTS的使用方式來講非常的容易上手,網路上也有很多教學文章可參考。

但由於開發所使用的機器Android版本較舊,只有早期的Pico TTS可以使用,必須上網下載Google TTS apk才能使用Google文字轉語音引擎。

下載並安裝好Google TTS後,遇到以下幾種問題及解決方式。

只有出現Pico TTS,無顯示Google TTS

進入[設定 -> 語言與輸入設定 -> 文字轉語音輸出] 發現只有出現Pico TTS卻沒有Google文字轉語音引擎。

遇到此問題時,必須先將Pico TTS停用。

從[設定->應用程式]中選擇Pico TTS後,選擇停用。

再度進入文字轉語音輸出中就可以看到Google文字轉語音引擎。

無法進入文字轉語音輸出

由於客製化的設備中,將語言與輸入設定隱藏起來。

經由Log trace後,此設定頁面為TextToSpeechSettings,它是一個Fragment,由Settings app中的SubSetting所使用。

我們可以透過adb 來launch此Fragment,網路上搜尋到的方式為:

cmd
1
2
adb shell am start -n com.android.settings/com.android.settings.SubSettings -e :android:show_fragment com.android.settings.tts.TextToSpeechSettings

但此方式喚起後會Crash: NullPointerException,改用以下的方式才能成功喚起此Fragment。

cmd
1
2
adb shell am start -n com.android.settings/com.android.settings.SubSettings -e :settings:show_fragment com.android.settings.tts.TextToSpeechSettings

執行結果

成功喚起後,可透過Google文字轉語音引擎,將語音設定為 中文(台灣)的模式。

本篇使用android.speech.tts.TextToSpeech package來實做TTS。

Step 1: 初始化TTS

初始化時設定初始化Listener : TextToSpeech.OnInitListener ,初始化完成會由onInit 函數返回結果。

MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener {

private TextToSpeech mTextToSpeech;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextToSpeech = new TextToSpeech(this.getApplicationContext(), this);
}

@Override
protected void onDestroy() {
if (mTextToSpeech != null) {
mTextToSpeech.shutdown();
}
super.onDestroy();
}

@Override
public void onInit(int status) {
Log.e("MainActivity", "onInit : " + status);
}
}

Step 2: 設定語系

初始化成功後,可設定語系並檢測是否支援此語系。

MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
@Override
public void onInit(int status) {
Log.e("Nick Main", "onInit : " + status);
if (status == TextToSpeech.SUCCESS) {
int result = mTextToSpeech.setLanguage(Locale.TRADITIONAL_CHINESE);
if (result != TextToSpeech.LANG_COUNTRY_AVAILABLE
&& result != TextToSpeech.LANG_AVAILABLE){
Log.e("MainActivity", "TTS 不支持此語言!");
}
}
}

Step 3: 監聽TTS進度

當開始讀出語音時,我們可能需要在開始朗讀或結束朗讀時,執行一些動作。
所以必須使用UtteranceProgressListener來監聽進度。

可在初始化成功時,設置監聽。

MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Override
public void onInit(int status) {
Log.e("Nick Main", "onInit : " + status);
if (status == TextToSpeech.SUCCESS) {
mTextToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override public void onStart(String s) {

Log.e("MainActivity", "onStart: " + s);
}

@Override public void onDone(String s) {
Log.e("MainActivity", "onDone: " + s);
}

@Override public void onError(String s) {
Log.e("MainActivity", "onError: " + s);
}
});

int result = mTextToSpeech.setLanguage(Locale.TRADITIONAL_CHINESE);
if (result != TextToSpeech.LANG_COUNTRY_AVAILABLE
&& result != TextToSpeech.LANG_AVAILABLE){
Log.e("MainActivity", "TTS 不支持此語言!");
}
}
}

使用 mTextToSpeech.speak(“測試Google中文語音”, TextToSpeech.QUEUE_ADD, null);

執行時文字有讀出聲音,但是Callback函式都沒有收到訊息,原因是因為沒有設定utteranceId,所以TTS library不知該返回給誰。

Step 4: 設定utteranceId

在呼叫speak API時必須傳入utteranceId,使用Random來產生一組utteranceId。

MainActivity
1
2
3
4
5
6
7
8
9
Random random = new Random();
random.setSeed(Calendar.getInstance().getTimeInMillis());

HashMap<String, String> myHashAlarm = new HashMap<String, String>();
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_ALARM));
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, String.valueOf(random.nextInt()));

int result = mTextToSpeech.speak("測試Google中文語音", TextToSpeech.QUEUE_ADD, myHashAlarm);

執行後就會在UtteranceProgressListener中的onStart與onDone中,看見返回結果。

作者

Nick Lin

發表於

2020-03-20

更新於

2023-01-18

許可協議


評論