Как добавить Text-to-Speech в свое приложение

Android предоставляет действительно огромные возможности для работы с устройствами. Например, он позволяет конвертировать текст в речь, о чём и будет говориться в этой статье. Это достигается благодаря использованию Синтеза речи (Text-to-Speech), который не только умеет конвертировать текст в речь, но также может говорить на разных языках.

Синтез речи может использоваться в самых разных областях, например, одно из наиболее частых применений это озвучивание текста для пользователей нарушением зрения. Синтез речи также применяется для того, чтобы читать вслух книги или изучать языки.

В нашем приложении «Карточки для детей» с помощью Text-to-Speech, если активировать эту опцию в настройках, озвучивается содержимое выбранной карточки при нажатии на неё. В этой статье мы рассмотрим, как добавляется синтез речи в приложение.

Для того, чтобы использовать в своём приложении синтез речи, Android SDK предоставляет класс TextToSpeech, который и синтезирует речь из текста. Его реализация достаточно проста, для начала нужно инициализировать экземпляр TextToSpeech и слушатель onInitListener.

private TextToSpeech TTS;
...
TTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
  @Override public void onInit(int initStatus) {

  }
});

В этом слушателе мы должны определить свойства экземпляра TextToSpeech после его инициализации, такие как язык, тембр и так далее. Для этого добавим в onItit() следующий код.

TTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
  @Override public void onInit(int initStatus) {
    if (initStatus == TextToSpeech.SUCCESS) {
      if (TTS.isLanguageAvailable(new Locale(Locale.getDefault().getLanguage()))
          == TextToSpeech.LANG_AVAILABLE) {
        TTS.setLanguage(new Locale(Locale.getDefault().getLanguage()));
      } else {
        TTS.setLanguage(Locale.US);
      }
      TTS.setPitch(1.3f);
      TTS.setSpeechRate(0.7f);
      ttsEnabled = true;
    } else if (initStatus == TextToSpeech.ERROR) {
      Toast.makeText(PagerActivity.this, R.string.tts_error, Toast.LENGTH_LONG).show();
      ttsEnabled = false;
    }
  }
});

Если инициализация завершена успешно, то с помощью метода isLanguageAvailable() проверяем доступность русского языка. В зависимости от того, доступен ли русский язык, методом setLanguage() устанавливаем экземпляру TextToSpeech или русский язык, или английский.

setLanguage() в качестве параметра принимает объект Locale, однако здесь есть один момент: TextToSpeech не знает локаль ru_RU, которая возвращается при вызове метода Locale.getDefault(). Поэтому при установке русского языка лучше явно задать локаль ru для корректной работы. Получить её можно, вызвав метод Locale.getDefault().getLanguage().

Метод setPitch() выставляет тембр голоса, который будет озвучивать текст.

Метод setSpeechRate() устанавливает скорость речи.

Теперь, когда объект инициализирован, нужно заставить его читать текст. Для этого при нажатии на карточку вызывается callback, передающий слушателю на активности с экземпляром TextToSpeech данные, которые нужно озвучить. Ключевым в процессе синтеза речи будет являться метод speak() класса TextToSpeech.

@Override public void speak(String text) {
  if (!ttsEnabled) return;
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    ttsGreater21(text);
  } else {
    ttsUnder20(text);
  }
}

@SuppressWarnings("deprecation") private void ttsUnder20(String text) {
  HashMap<String, String> map = new HashMap<>();
  map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
  TTS.speak(text, TextToSpeech.QUEUE_FLUSH, map);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP) private void ttsGreater21(String text) {
  String utteranceId = this.hashCode() + "";
  TTS.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceId);
}

В метод speak() необходимо передать следующие параметры:

  • text — текст, который нужно воспроизвести;
  • TextToSpeech.QUEUE_FLUSH — флаг, обозначающий, что при добавлении новой фразы текущую необходимо прервать и начать воспроизведение добавленной. Если вы хотите составить очередь из фраз, следует использовать вместо этого флаг TextToSpeech.QUEUE_ADD;
  • Дополнительные параметры.

Главным отличием здесь является то, как формируются дополнительные параметры, в частности идентификатор фразы.

Для версий ниже Lolipop 5.0 (API 21) нужно создать объект HashMap<String, String>, в который необходимо добавить пару ключ-значение, где ключ TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID обозначает, что мы хотим добавить в параметры идентификатор фразы, а значение — собственно идентификатор, например «MessageId».

В новых же версиях Android это можно сделать проще, без использования HashMap.

В результате мы добавили TextToSpeech в наше приложение и получили возможность воспроизводить название каждой карточки средствами устройства.

Нашли ошибку в тексте?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *