Android
Text to Speech (TTS)
Recherche…
Base texte-parole
layout_text_to_speech.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter text here!"
android:id="@+id/textToSpeak"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/textToSpeak"
android:id="@+id/btnSpeak"/>
</RelativeLayout>
AndroidTextToSpeechActivity.java
public class AndroidTextToSpeechActivity extends Activity implements
TextToSpeech.OnInitListener {
EditText textToSpeak = null;
Button btnSpeak = null;
TextToSpeech tts;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textToSpeak = findViewById(R.id.textToSpeak);
btnSpeak = findViewById(R.id.btnSpeak);
btnSpeak.setEnabled(false);
tts = new TextToSpeech(this, this);
btnSpeak.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
speakOut();
}
});
}
@Override
public void onDestroy() {
// Don't forget to shutdown tts!
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(Locale.US);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "This Language is not supported");
} else {
btnSpeak.setEnabled(true);
speakOut();
}
} else {
Log.e("TTS", "Initilization Failed!");
}
}
private void speakOut() {
String text = textToSpeak.getText().toString();
if(text == null || text.isEmpty())
return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
String utteranceId=this.hashCode() + "";
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceId);
} else {
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
}
}
La langue à parler peut être définie en fournissant un setLanguage()
Locale
à la méthode setLanguage()
:
tts.setLanguage(Locale.CHINESE); // Chinese language
Le nombre de langues prises en charge varie entre les niveaux Android. La méthode isLanguageAvailable()
peut être utilisée pour vérifier si une langue isLanguageAvailable()
est prise en charge:
tts.isLanguageAvailable(Locale.CHINESE);
Le niveau de hauteur de parole peut être défini à l'aide de la méthode setPitch()
. Par défaut, la valeur de la hauteur est 1.0. Utilisez des valeurs inférieures à 1,0 pour diminuer le niveau de hauteur ou des valeurs supérieures à 1,0 pour augmenter le niveau de hauteur:
tts.setPitch(0.6);
Le débit de parole peut être défini à l'aide de setSpeechRate()
. Le taux de parole par défaut est 1.0. Le taux de parole peut être doublé en le réglant sur 2.0 ou sur la moitié en le réglant sur 0.5:
tts.setSpeechRate(2.0);
Implémentation de TextToSpeech sur les API
L'implémentation observable à froid, émise lorsque le moteur TTS a fini de parler, commence à s'exprimer lorsqu'il est abonné. Notez que le niveau 21 de l’API introduit une manière différente d’exercer la parole:
public class RxTextToSpeech {
@Nullable RxTTSObservableOnSubscribe audio;
WeakReference<Context> contextRef;
public RxTextToSpeech(Context context) {
this.contextRef = new WeakReference<>(context);
}
public void requestTTS(FragmentActivity activity, int requestCode) {
Intent checkTTSIntent = new Intent();
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
activity.startActivityForResult(checkTTSIntent, requestCode);
}
public void cancelCurrent() {
if (audio != null) {
audio.dispose();
audio = null;
}
}
public Observable<Boolean> speak(String textToRead) {
audio = new RxTTSObservableOnSubscribe(contextRef.get(), textToRead, Locale.GERMANY);
return Observable.create(audio);
}
public static class RxTTSObservableOnSubscribe extends UtteranceProgressListener
implements ObservableOnSubscribe<Boolean>,
Disposable, Cancellable, TextToSpeech.OnInitListener {
volatile boolean disposed;
ObservableEmitter<Boolean> emitter;
TextToSpeech textToSpeech;
String text = "";
Locale selectedLocale;
Context context;
public RxTTSObservableOnSubscribe(Context context, String text, Locale locale) {
this.selectedLocale = locale;
this.context = context;
this.text = text;
}
@Override public void subscribe(ObservableEmitter<Boolean> e) throws Exception {
this.emitter = e;
if (context == null) {
this.emitter.onError(new Throwable("nullable context, cannot execute " + text));
} else {
this.textToSpeech = new TextToSpeech(context, this);
}
}
@Override @DebugLog public void dispose() {
if (textToSpeech != null) {
textToSpeech.setOnUtteranceProgressListener(null);
textToSpeech.stop();
textToSpeech.shutdown();
textToSpeech = null;
}
disposed = true;
}
@Override public boolean isDisposed() {
return disposed;
}
@Override public void cancel() throws Exception {
dispose();
}
@Override public void onInit(int status) {
int languageCode = textToSpeech.setLanguage(selectedLocale);
if (languageCode == android.speech.tts.TextToSpeech.LANG_COUNTRY_AVAILABLE) {
textToSpeech.setPitch(1);
textToSpeech.setSpeechRate(1.0f);
textToSpeech.setOnUtteranceProgressListener(this);
performSpeak();
} else {
emitter.onError(new Throwable("language " + selectedLocale.getCountry() + " is not supported"));
}
}
@Override public void onStart(String utteranceId) {
//no-op
}
@Override public void onDone(String utteranceId) {
this.emitter.onNext(true);
this.emitter.onComplete();
}
@Override public void onError(String utteranceId) {
this.emitter.onError(new Throwable("error TTS " + utteranceId));
}
void performSpeak() {
if (isAtLeastApiLevel(21)) {
speakWithNewApi();
} else {
speakWithOldApi();
}
}
@RequiresApi(api = 21) void speakWithNewApi() {
Bundle params = new Bundle();
params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "");
textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params, uniqueId());
}
void speakWithOldApi() {
HashMap<String, String> map = new HashMap<>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, uniqueId());
textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, map);
}
private String uniqueId() {
return UUID.randomUUID().toString();
}
}
public static boolean isAtLeastApiLevel(int apiLevel) {
return Build.VERSION.SDK_INT >= apiLevel;
}
}