【问题标题】:Android speech recognizing and audio recording in the same timeAndroid语音识别和录音同时进行
【发布时间】:2011-08-23 12:02:59
【问题描述】:

我的应用程序使用 AsyncTask 中的 MediaRecorder 类录制音频,并使用 Google API 将语音转换为文本 - 识别器意图 - 使用此问题中的代码:How can I use speech recognition without the annoying dialog in android phones

我也尝试在 Thread 中录制音频,但这是更糟糕的解决方案。它会导致更多的问题。我的问题是我的应用程序在模拟器上正常工作。但由于缺乏语音识别服务,模拟器不支持语音识别。在我的设备上,当我开始录制音频和语音识别时,我的应用程序崩溃了 - “意外停止”。但是,当我关闭 wifi 时,应用程序可以像在模拟器上一样正常工作。

在 AndroidManifest 中录制音频需要:

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

和语音识别要求者:

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

我想这是单音频输入的问题?我该如何解决这个问题? 谷歌语音识别器需要在主 UI 线程中工作,所以我不能例如在异步任务中这样做。所以我在异步任务中有录音。我不知道为什么这会导致问题。

我已将我的设备连接到 Eclipse 并使用了 USB 调试。这是我在 LogCat 中的执行:

08-23 14:50:03.528: ERROR/ActivityThread(12403): Activity go.android.Activity has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@48181340 that was originally bound here
08-23 14:50:03.528: ERROR/ActivityThread(12403): android.app.ServiceConnectionLeaked: Activity go.android.Activity has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@48181340 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

【问题讨论】:

  • 我正在尝试做同样的事情。但似乎可能只有一个应用程序录制音频。你成功了吗?现在我正在尝试录制音频并进行一些破解以将其发送到语音识别器,但我很难找到响应 RECOGNIZE_SPEECH 的活动或服务。
  • 我没有测试过这个解决方案,但也许有可能。在developer.android.com/reference/android/speech/… 中有方法void bufferReceived(byte[] buffer)。可能的解决方案是将这个接收缓冲区保存在 AudioRecord Android 类中。它有类似read(byte[] audioData, int offsetInBytes, int sizeInBytes) 的方法。那么也许有可能以这种方式连接这两个实用程序?配置 AudioRecord 以及在录制后将结果转换为 mp3 或 wav 格式时可能会出现问题。
  • 有人有运气吗?这对于创建语音记录的抄本非常有用。创建语音到文本文件,然后可以播放录音以验证它。
  • 嘿@woyaru,你找到解决办法了吗?我一直面临同样的问题,似乎找不到任何东西。

标签: android android-asynctask speech-recognition


【解决方案1】:

我找到了一个可以很好地进行语音识别和录音的解决方案。这是我创建的一个简单 Android 项目的link,以显示解决方案的工作原理。另外,我在项目中放置了一些打印屏幕来说明应用程序。

我将尝试简要解释我使用的方法。我在该项目中结合了两个功能:Google Speech API 和 Flac 录音。

通过 HTTP 连接调用 Google Speech API。 Mike Pultz 提供了有关 API 的更多详细信息:

"(...) 新的 [Google] API 是一个全双工流式 API。这意味着它实际上使用了两个 HTTP 连接——一个 POST 请求将内容作为“实时”上传” 分块流,以及访问结果的第二个 GET 请求,这对于较长的音频样本或流式音频更有意义。”

但是,此 API 需要接收 FLAC 声音文件才能正常工作。这让我们进入第二部分:Flac 录音

我通过从名为 AudioBoo 的开源应用程序中提取和改编一些代码和库,在该项目中实现了 Flac 录音。 AudioBoo 使用原生代码录制和播放 flac 格式。

因此,可以录制 flac 声音,将其发送到 Google Speech API,获取文本并播放刚刚录制的声音。

我创建的项目具有使其工作的基本原则,并且可以针对特定情况进行改进。为了使其在不同的场景中工作,有必要获得一个 Google Speech API 密钥,该密钥是通过成为 Google Chromium-dev 组的一部分获得的。我在那个项目中留下了一把钥匙只是为了表明它正在工作,但我最终会删除它。如果有人需要有关它的更多信息,请告诉我,因为我无法在这篇文章中放置超过 2 个链接。

【讨论】:

  • 我将很快测试您的解决方案。我很久没有合适的设备了。最后我有设备来测试它。
  • @isantsan 你能告诉我如何将音频文件保存在存储卡中,然后将语音中的音频转换为文本 api 吗?我想做同样的功能。你能告诉我示例代码,这样我就可以开始了。
  • 我们将音频录制为 .flac 文件(使用 AudioBoo 开发的一些库),然后通过 HTTP 连接将 .flac 文件发送给 Google。在我对 GitHub 项目的回答中有一个链接,其中包含此实现的简单示例。
  • @isantsan 我想发送音频文件 > 15 秒。我看到了您的评论,但不确定如何实施。你能帮我吗?
  • 我将从答案中的 GitHub 项目开始并尝试运行它。你能让那个项目运行起来吗?
【解决方案2】:

迟到的答案,但对于第一个例外,您必须在完成您想要的操作之后销毁您的 SpeechRecognizer,例如(在 onStop() 或 onDestroy() 中或直接在您不再需要 SpeechRecognizer 之后):

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

【讨论】:

    【解决方案3】:

    CLOUD SPEECH API 的帮助下,我成功地完成了这项工作。 你可以通过google speech找到它的demo。

    API 可识别 80 多种语言和变体,以支持您的 全球用户群。您可以将用户口述的文本转录为 应用程序的麦克风,通过语音启用命令和控制,或 转录音频文件,以及许多其他用例。识别音频 在请求中上传,并与您的音频存储集成 谷歌云存储,使用与谷歌相同的技术 为自己的产品提供动力。

    它使用音频缓冲区在 Google Speech API 的帮助下转录数据。在AudioRecorder 的帮助下,我已经使用这个缓冲区来存储录音。

    因此,通过这个演示,我们可以将用户的语音与录音并行转录。

    在此,它启动和停止基于语音的语音识别。它还提供了VoiceRecorder.java 中的 SPEECH_TIMEOUT_MILLIS 功能,与RecognizerIntent 中的EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS 相同,但由用户控制。

    总而言之,您可以指定静音超时,并在此基础上在用户输出后停止,并在用户开始讲话后立即重新开始。

    【讨论】:

    • 昂贵的解决方案
    【解决方案4】:

    'google-speech' 和 'android-opus' (opuslib) 上的近期项目允许简单、同时识别以及音频记录到 android ext 中的 opus 文件。贮存。

    看speech project中的VoiceRecorder,在读取mic buffer后只需要多出几行代码,这个buffer除了当前speech外,还可以被fileSink(PCM16 to Opus-codec)消费-观察者。

    Google-speech-opus-recorder中查看上述两个项目的最小合并

    【讨论】:

    • 项目已弃用
    • 感谢分享。但我得到了这个错误:E/ApiFragment: Error calling the API. io.grpc.StatusRuntimeException: UNIMPLEMENTED: GRPC target method can't be resolved. 有什么想法吗?
    【解决方案5】:

    我还没有测试过这个解决方案,但也许有可能。在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 格式时可能会出现问题。

    【讨论】:

    • 不幸的是,每个设备(根本)都不会调用此方法,因此无法保证您是否获得任何音频数据。这是一个可悲且令人沮丧的结果,因为我们试图在我们的听写应用程序 Dictator 中利用此功能。此外,该数据的格式和采样率没有正式定义,但它通常看起来像(8KHz,但取决于实现)16 位单声道。
    猜你喜欢
    • 2017-02-07
    • 1970-01-01
    • 2022-08-18
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 2021-08-14
    • 2021-04-17
    相关资源
    最近更新 更多