Как добиться плавного преобразования текста в речь с помощью идентификаторов высказываний

Моя цель - использовать API преобразования текста в речь Android для воспроизведения предложения текста как речи, отслеживая текущее произнесенное слово.

Чтобы добиться плавного естественного воспроизведения, я использую:

tts.speak("This is the sentence", TextToSpeech.QUEUE_FLUSH, null, null)

но тогда я не могу уследить за произнесенным в данный момент словом.

Чтобы воспроизвести предложение, отслеживая произносимое в данный момент слово, я использую:

val words = "This is the sentence".split(" ")
words.forEachIndexed { index, element ->
    tts.speak(element, TextToSpeech.QUEUE_ADD, null, index.toString())
}

в сочетании с UtteranceProgressListener, но тогда речь будет очень отрывистой и не будет считаться естественным предложением.

Есть ли способ получить одновременно произносимое естественным образом предложение и в то же время отслеживать произносимое в данный момент слово?

1
0
985
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы посмотрите последнюю версию документации Android, вы заметите новый метод, представленный в UtteranceProgressListener на уровне API 26, который называется onRangeStart ((String utteranceId, int start, int end, int frame)

https://developer.android.com/reference/android/speech/tts/UtteranceProgressListener.html#onRangeStart(java.lang.String,%20int,%20int,%20int)

Однако, как указано в документации:

"Вызывается, только если механизм предоставляет информацию о времени, вызывая rangeStart (int, int, int)"

Это реализовано в SynthesisCallback: https://developer.android.com/reference/android/speech/tts/SynthesisCallback.html#rangeStart(int,%20int,%20int)

Снова в документации говорится:

«Служба может вызвать этот метод, чтобы предоставить информацию о времени произнесенного текста».

К сожалению, это означает, что обратный вызов, предоставляющий необходимую информацию о времени, зависит от реализации.

На моем устройстве под управлением Android 8.0.0 и с использованием движка tts по умолчанию (com.google.android.tts) я не получил обратного вызова.

Для тестирования вам потребуется

  • для сборки с SDK уровня 26 или выше
  • Реализуйте свой собственный UtteranceProgressListener
  • Установите его для механизма TextToSpeech, вызвав TextToSpeech.setOnUtteranceProgressListener (слушатель);
  • Переопределите метод onRangeStart (String, int, int, int) в вашем UtteranceProgressListener.

Если ваша реализация поддерживает информацию о времени, вы сделаете обратный вызов, если нет, возможно, лучше всего найти другую реализацию движка или, возможно, реализовать свой собственный TextToSpeechService.

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

Gaurav Saluja 27.11.2020 14:46

Другие вопросы по теме