Подтвердить что ты не робот

Одновременное распознавание речи и аудиозапись Android

Мои приложения записывают аудио с использованием класса MediaRecorder в AsyncTask, а также используют перевод Google API для преобразования текста в текст - Recognizer Intent - используя код из этого вопроса: Как использовать распознавание речи без раздражающий диалог на телефонах Android.

Я попытался также записать аудио в Thread, но это хуже решение. Это вызывает больше проблем. Моя проблема в том, что мое приложение работает правильно на эмуляторе. Но эмулятор не поддерживает рекогносцировку речи из-за отсутствия услуг распознавания голоса. И на моем устройстве мое приложение потерпело крах, когда я начинаю записывать аудио и речевое распознавание - "неожиданно остановился". Однако, когда я отключил Wi-Fi, приложение работает правильно, как на эмуляторе.

Запись звука требуется в AndroidManifest:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

и репликаторы распознавания речи:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />

Я полагаю, что это проблема с одним аудиовходом? Как я могу решить эту проблему? Репликаторы Google Recech Recognizer работают в основном потоке пользовательского интерфейса, поэтому я не могу, например, выполнить его в Async Task. Поэтому у меня есть запись звука в Async Task. У меня нет идеи, почему это вызывает проблемы.

Я подключил свое устройство к Eclipse, и я использовал отладку USB. И это у меня есть в LogCat:

08-23 14:50:03.528: ERROR/ActivityThread(12403): Activity go.android.Activity has leaked ServiceConnection [email protected] that was originally bound here
08-23 14:50:03.528: ERROR/ActivityThread(12403): android.app.ServiceConnectionLeaked: Activity go.android.Activity has leaked ServiceConnection [email protected] that was originally bound here
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.ActivityThread$PackageInfo$ServiceDispatcher.<init>(ActivityThread.java:1121)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.ActivityThread$PackageInfo.getServiceDispatcher(ActivityThread.java:1016)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.ContextImpl.bindService(ContextImpl.java:951)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.content.ContextWrapper.bindService(ContextWrapper.java:347)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.speech.SpeechRecognizer.startListening(SpeechRecognizer.java:267)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at go.android.Activity.startRecordingAndAnimation(Activity.java:285)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at go.android.Activity.onResume(Activity.java:86)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1151)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.Activity.performResume(Activity.java:3823)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3118)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3143)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2684)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.os.Looper.loop(Looper.java:123)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at android.app.ActivityThread.main(ActivityThread.java:4627)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at java.lang.reflect.Method.invokeNative(Native Method)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at java.lang.reflect.Method.invoke(Method.java:521)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
08-23 14:50:03.528: ERROR/ActivityThread(12403):     at dalvik.system.NativeStart.main(Native Method)

И после этого еще одно исключение:

08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412): Failed to create session
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412): com.google.android.voicesearch.speechservice.ConnectionException: POST failed
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at com.google.android.voicesearch.speechservice.SpeechServiceHttpClient.post(SpeechServiceHttpClient.java:176)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at com.google.android.voicesearch.speechservice.SpeechServiceHttpClient.post(SpeechServiceHttpClient.java:88)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at com.google.android.voicesearch.speechservice.ServerConnectorImpl.createTcpSession(ServerConnectorImpl.java:118)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at com.google.android.voicesearch.speechservice.ServerConnectorImpl.createSession(ServerConnectorImpl.java:98)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at com.google.android.voicesearch.speechservice.RecognitionController.runRecognitionMainLoop(RecognitionController.java:679)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at com.google.android.voicesearch.speechservice.RecognitionController.startRecognition(RecognitionController.java:463)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at com.google.android.voicesearch.speechservice.RecognitionController.access$200(RecognitionController.java:75)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at com.google.android.voicesearch.speechservice.RecognitionController$1.handleMessage(RecognitionController.java:300)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at android.os.Looper.loop(Looper.java:123)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at android.os.HandlerThread.run(HandlerThread.java:60)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412): Caused by: java.net.SocketTimeoutException
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:564)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:88)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:191)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:82)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:174)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:179)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:235)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:259)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:279)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:121)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:410)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at android.net.http.AndroidHttpClient.execute(AndroidHttpClient.java:243)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     at com.google.android.voicesearch.speechservice.SpeechServiceHttpClient.post(SpeechServiceHttpClient.java:167)
08-23 14:50:08.000: ERROR/ServerConnectorImpl(12412):     ... 10 more
08-23 14:50:08.000: ERROR/RecognitionController(12412): Ignoring error 2
4b9b3361

Ответ 1

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

Я попытаюсь кратко объяснить подход, который я использовал. Я объединил две функции в этом проекте: Google Speech API и запись Flac.

API Google Speech вызывается через HTTP-соединения. Майк Пультц дает более подробную информацию об API:

"(...) новый [Google] API - это полнодуплексный потоковый API. Это означает, что на самом деле он использует два HTTP-соединения - один запрос POST для загрузки контента в виде" живого "фрагментированного потока, и второй запрос GET для доступа к результатам, что имеет большее значение для более длинных образцов аудио или для потоковой передачи звука.

Однако, этот API должен получить звуковой файл FLAC для правильной работы. Это заставляет нас перейти ко второй части: запись флагов

Я реализовал запись Flac в этом проекте путем извлечения и адаптации некоторых фрагментов кода и библиотек из приложения с открытым исходным кодом под названием AudioBoo. AudioBoo использует собственный код для записи и воспроизведения формата flac.

Таким образом, можно записать звук flac, отправить его в Google Speech API, получить текст и воспроизвести записанный звук.

Проект, который я создал, имеет основные принципы, чтобы заставить его работать и может быть улучшен для конкретных ситуаций. Чтобы заставить его работать по другому сценарию, необходимо получить ключ API Google Speech, который получается в составе группы Google Chromium-dev. Я оставил один ключ в этом проекте, чтобы показать его работу, но в конечном итоге я его удалю. Если кому-то нужна дополнительная информация об этом, сообщите мне, потому что я не могу разместить более двух ссылок в этом сообщении.

Ответ 2

Поздний ответ, но для первого исключения вы должны уничтожить свой SpeechRecognizer после этого, что вы хотите, например, (в onStop() или onDestroy() или непосредственно после того, как вам больше не нужен SpeechRecognizer):

    if (YourSpeechRecognizer != null)
    {
        YourSpeechRecognizer.stopListening();
        YourSpeechRecognizer.cancel();
        YourSpeechRecognizer.destroy();
    }

Ответ 3

Я успешно выполнил это с помощью API CLOUD SPEECH.  Вы можете найти это демо речь Google.

API распознает более 80 языков и вариантов, чтобы поддерживать ваши глобальной пользовательской базы. Вы можете расшифровать текст пользователей, диктующих микрофон приложений, включение управления и управления через голос, или транскрипцию аудиофайлов, среди многих других случаев использования. Признать аудио загружается в запрос и интегрируется с вашим хранилищем аудио Google Cloud Storage, используя ту же технологию, которую Google использует для владеть своими продуктами.

Он использует звуковой буфер для транскрибирования данных с помощью API Google Speech. Я использовал этот буфер для хранения аудиозаписей с помощью AudioRecorder.

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

В этом он запускает и останавливает распознавание речи на основе голоса. Он также предоставляет средство SPEECH_TIMEOUT_MILLIS в VoiceRecorder.java, которое так же, как EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS RecognizerIntent, но пользователь контролируется.

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

Ответ 4

Я еще не тестировал это решение, но, возможно, есть возможность. В http://developer.android.com/reference/android/speech/RecognitionService.Callback.html существует метод void bufferReceived(byte[] buffer). Возможным решением является сохранение этого восстановленного буфера в классе AudioRecord Android. Он имеет метод, подобный read(byte[] audioData, int offsetInBytes, int sizeInBytes). Так, возможно, можно подключить эти две утилиты таким образом? Возможно, возникли проблемы с настройкой AudioRecord и преобразованием результата в формат mp3 или wav после записи.

Ответ 5

Недавние проекты на google-speech 'и на' android-opus '(opuslib) позволяют простое одновременное распознавание наряду с аудиозаписью в файле opus в android ext. место хранения.

Глядя на VoiceRecorder в речевом проекте, только с несколькими дополнительными строками кода после прочтения микрофонного буфера, буфер также может потребляться файловым (PCM16 - Opus-кодеком) в дополнение к текущему речевому наблюдателю.

см. минимальное слияние двух проектов выше в Google-speech-opus-recorder