Я работаю над приложением, в котором нам нужно принять речевой ввод и получить STT с соответствующим звуком обратно. До недавнего времени мне удавалось получать аудиофайлы, возвращенные из Android распознавания речи с помощью дополнительных функций:
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
.putExtra(RecognizerIntent.EXTRA_LANGUAGE, addRegion(sttLang))
.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt))
.putExtra("android.speech.extra.GET_AUDIO_FORMAT", "audio/AMR")
.putExtra("android.speech.extra.GET_AUDIO", true)
Теперь я получаю возврат "операция отменена", когда определены дополнительные функции GET_AUDIO_FORMAT и GET_AUDIO.
Я попытался реализовать SpeechRecognizer
и слушатель (ниже), но он также возвращает только текст, а метод onBufferReceived
задокументирован Google как ненадежный (https://developer.android.com/reference/kotlin/android/speech/RecognitionListener?hl=en#onBufferReceived (kotlin). ByteArray) ).
class MySpeechRecognizer(context: Context): RecognitionListener {
private val recognizer: SpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(context)
private lateinit var listener: SpeechResultListener
fun createRecognizer(activityListener: SpeechResultListener) {
recognizer.setRecognitionListener(this)
this.listener = activityListener
}
fun startListening(intent: Intent) {
recognizer.startListening(intent)
}
override fun onReadyForSpeech(params: Bundle?) {
Log.v(Exception().stackTrace[0].toString(), "Ready for speech")
}
override fun onError(error: Int) {
Crashlytics.log(Log.INFO, Exception().stackTrace[0].toString(), "Speech Error: $error")
listener.handleError()
}
override fun onEvent(eventType: Int, params: Bundle?) {
Crashlytics.log(Log.INFO, Exception().stackTrace[0].toString(),
"Speech Event: $eventType")
}
override fun onBeginningOfSpeech() {
Crashlytics.log(Log.INFO, Exception().stackTrace[0].toString(), "Speech Start")
}
override fun onBufferReceived(buffer: ByteArray?) {
Crashlytics.log(Log.INFO, Exception().stackTrace[0].toString(),
"Speech Buffer: $buffer")
}
override fun onEndOfSpeech() {
Crashlytics.log(Log.INFO, Exception().stackTrace[0].toString(), "Speech End")
}
override fun onPartialResults(partialResults: Bundle?) {
val resultArray = partialResults?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
Crashlytics.log(Log.INFO, Exception().stackTrace[0].toString(),
"Speech Parts: $resultArray")
}
override fun onResults(results: Bundle?) {
val resultArray = results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
val confidenceArray = results?.getFloatArray(SpeechRecognizer.CONFIDENCE_SCORES)
Crashlytics.log(Log.INFO, Exception().stackTrace[0].toString(),
"Speech Results: $resultArray confidences: $confidenceArray")
// TODO: Get Audio here DM
if (resultArray != null) {
listener.handleTranscription(resultArray[0], null)
} else {
Crashlytics.log(Log.WARN, Exception().stackTrace[0].toString(),
"Null Speech Results!")
}
}
override fun onRmsChanged(rmsdB: Float) {
Crashlytics.log(Log.VERBOSE, Exception().stackTrace[0].toString(), "Speech RMS: $rmsdB")
}
}
interface SpeechResultListener {
fun handleTranscription(transcription: String, audio: ByteArray?)
fun handleError()
Я пытался использовать объект MediaRecorder
, запущенный на onBeginningOfSpeech
, но микрофон не может связываться с MediaRecorder и SpeechRecognizer
одновременно. Я мог бы создать объект AudioRecord
и получить необработанные данные потокового микрофона, но я не вижу способа передать это в SpeechRecognizer
.
Кто-нибудь нашел решение для этого, которое работает на более новых версиях Android (API 26-28 +)? Я открыт для использования другой схемы распознавания речи, мне действительно нужен STT со звуком, мне не нужен частичный результат и RMS обязательно.