Распознавание речи Android через микрофон Bluetooth в Jetpack Compose — 2024 г.Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Распознавание речи Android через микрофон Bluetooth в Jetpack Compose — 2024 г.

Сообщение Anonymous »

Может кто-нибудь объяснить, как реализовать распознавание речи в реальном времени с помощью микрофона Bluetooth с помощью Android Jetpack Compose? Я изо всех сил пытался найти какие-либо полезные ресурсы по этому вопросу.
Это подход, который я пытаюсь использовать, но постоянно получаю Ошибку в распознавании речи: 8 и < Strong>RecognitionService занят ошибки.
Вот код, который я использую
package com.example.nora.bluetooth

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothHeadset
import android.bluetooth.BluetoothProfile
import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.speech.RecognitionListener
import android.speech.RecognizerIntent
import android.speech.SpeechRecognizer
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import timber.log.Timber

class BluetoothAudioManager(private val context: Context) {
private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
private var bluetoothHeadset: BluetoothHeadset? = null
private val audioManager: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
private var speechRecognizer: SpeechRecognizer? = null
private val handler = Handler(Looper.getMainLooper())
private var retryCount = 0
private val MAX_RETRY_COUNT = 3
private var isListeningActive = false
private var isScoStarted = false

private val _isBluetoothHeadsetConnected = MutableStateFlow(false)
val isBluetoothHeadsetConnected: StateFlow = _isBluetoothHeadsetConnected

private val _transcribedText = MutableStateFlow("")
val transcribedText: StateFlow = _transcribedText

private val _isListening = MutableStateFlow(false)
val isListening: StateFlow = _isListening

init {
setupBluetoothProxy()
}

private fun setupBluetoothProxy() {
bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener {
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
if (profile == BluetoothProfile.HEADSET) {
bluetoothHeadset = proxy as BluetoothHeadset
checkHeadsetConnection()
}
}

override fun onServiceDisconnected(profile: Int) {
if (profile == BluetoothProfile.HEADSET) {
bluetoothHeadset = null
_isBluetoothHeadsetConnected.value = false
}
}
}, BluetoothProfile.HEADSET)
}

private fun checkHeadsetConnection() {
val connectedDevices = bluetoothHeadset?.connectedDevices
_isBluetoothHeadsetConnected.value = !connectedDevices.isNullOrEmpty()
Timber.d("Bluetooth headset connected: ${_isBluetoothHeadsetConnected.value}")
}

private fun setupSpeechRecognizer() {
if (speechRecognizer == null) {
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context)
}
speechRecognizer?.setRecognitionListener(createRecognitionListener())
}

private fun createRecognitionListener(): RecognitionListener {
return object : RecognitionListener {
override fun onReadyForSpeech(params: Bundle?) {
Timber.d("Ready for speech")
_isListening.value = true
retryCount = 0
}

override fun onBeginningOfSpeech() {
Timber.d("Speech began")
}

override fun onRmsChanged(rmsdB: Float) {}

override fun onBufferReceived(buffer: ByteArray?) {}

override fun onEndOfSpeech() {
Timber.d("Speech ended")
_isListening.value = false
}

override fun onError(error: Int) {
Timber.e("Error in speech recognition: $error")
_isListening.value = false
handleSpeechRecognitionError(error)
}

override fun onResults(results: Bundle?) {
val matches = results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
if (!matches.isNullOrEmpty()) {
val recognizedText = matches[0]
Timber.d("Speech recognized: $recognizedText")
_transcribedText.value = recognizedText
}
if (isListeningActive) {
restartListening()
}
}

override fun onPartialResults(partialResults: Bundle?) {
val matches = partialResults?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
if (!matches.isNullOrEmpty()) {
val partialText = matches[0]
Timber.d("Partial speech recognized: $partialText")
_transcribedText.value = partialText
}
}

override fun onEvent(eventType: Int, params: Bundle?) {}
}
}

fun startListening() {
isListeningActive = true
setupSpeechRecognizer()
startBluetoothSco()
handler.postDelayed({
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true)
putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 10000)
putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 1500)
putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, 1500)
}
speechRecognizer?.startListening(intent)
_isListening.value = true
Timber.d("Started listening")
}, 1000) // Delay to ensure Bluetooth SCO is ready
}

fun stopListening() {
isListeningActive = false
speechRecognizer?.stopListening()
stopBluetoothSco()
_isListening.value = false
Timber.d("Stopped listening")
}

private fun startBluetoothSco() {
if (!isScoStarted && _isBluetoothHeadsetConnected.value) {
Timber.d("Starting Bluetooth SCO")
audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
audioManager.startBluetoothSco()
audioManager.isBluetoothScoOn = true
isScoStarted = true
}
}

private fun stopBluetoothSco() {
if (isScoStarted) {
Timber.d("Stopping Bluetooth SCO")
audioManager.stopBluetoothSco()
audioManager.isBluetoothScoOn = false
audioManager.mode = AudioManager.MODE_NORMAL
isScoStarted = false
}
}

private fun handleSpeechRecognitionError(error: Int) {
when (error) {
SpeechRecognizer.ERROR_AUDIO -> Timber.e("Audio recording error")
SpeechRecognizer.ERROR_CLIENT -> {
Timber.e("Client side error")
// Reinitialize SpeechRecognizer
releaseSpeechRecognizer()
setupSpeechRecognizer()
}
SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS -> Timber.e("Insufficient permissions")
SpeechRecognizer.ERROR_NETWORK -> Timber.e("Network error")
SpeechRecognizer.ERROR_NETWORK_TIMEOUT -> Timber.e("Network timeout")
SpeechRecognizer.ERROR_NO_MATCH -> Timber.e("No recognition result matched")
SpeechRecognizer.ERROR_RECOGNIZER_BUSY -> {
Timber.e("RecognitionService busy")
releaseSpeechRecognizer()
setupSpeechRecognizer()
}
SpeechRecognizer.ERROR_SERVER -> Timber.e("Server error")
SpeechRecognizer.ERROR_SPEECH_TIMEOUT -> Timber.e("No speech input")
}
if (isListeningActive && retryCount < MAX_RETRY_COUNT) {
retryCount++
Timber.d("Retrying speech recognition (attempt $retryCount)")
handler.postDelayed({ restartListening() }, 1000)
} else if (retryCount >= MAX_RETRY_COUNT) {
Timber.e("Max retry count reached. Stopping speech recognition.")
stopListening()
}
}

private fun restartListening() {
stopBluetoothSco()
handler.postDelayed({
startListening()
}, 500)
}

private fun releaseSpeechRecognizer() {
speechRecognizer?.destroy()
speechRecognizer = null
}

fun release() {
bluetoothHeadset?.let { headset ->
bluetoothAdapter?.closeProfileProxy(BluetoothProfile.HEADSET, headset)
}
stopBluetoothSco()
releaseSpeechRecognizer()
Timber.d("BluetoothAudioManager released")
}
}


Подробнее здесь: https://stackoverflow.com/questions/789 ... mpose-2024
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Программа Python для преобразования речи в текст не регистрирует микрофон
    Anonymous » » в форуме Python
    0 Ответы
    79 Просмотры
    Последнее сообщение Anonymous
  • Используйте микрофон в Java для распознавания речи с помощью VOSK
    Anonymous » » в форуме JAVA
    0 Ответы
    45 Просмотры
    Последнее сообщение Anonymous
  • Распознавание речи не работает для приложения Android, использующего SpeechRecouncer в качестве службы
    Anonymous » » в форуме Android
    0 Ответы
    59 Просмотры
    Последнее сообщение Anonymous
  • Распознавание речи на Android 13
    Anonymous » » в форуме JAVA
    0 Ответы
    29 Просмотры
    Последнее сообщение Anonymous
  • Распознавание речи на Android 13
    Anonymous » » в форуме Android
    0 Ответы
    32 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Android»