首页 文章

Android语音识别和录音同时进行

提问于
浏览
16

我的应用程序使用AsyncTask中的MediaRecorder类记录音频,并使用Google API转换语音到文本 - Recognizer Intent - 使用此问题中的代码: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" />

我想这是单音频输入的问题?我该如何解决这个问题? Google Speech Recognizer需要在主UI线程中工作,因此我无法在Async Task中执行此操作 . 所以我在Async Task中录音 . 我不知道为什么这会导致问题 .

我已将设备连接到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

5 回答

  • 1

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

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

    Google Speech API通过HTTP连接调用 . 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个以上的链接 .

  • 3

    延迟回答,但对于第一个异常,你必须在你想要的之后销毁你的SpeechRecognizer,例如(在onStop()或onDestroy()中或在你不再需要SpeechRecognizer之后直接销毁):

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

    我已经在CLOUD SPEECH API的帮助下成功完成了这项工作 . 您可以通过google speech找到它的演示 .

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

    它使用音频缓冲区借助Google Speech API转录数据 . 我已经使用这个缓冲区来存储AudioRecorder的音频录音 .

    因此,通过此演示,我们可以与音频录制并行转录用户的演讲 .

    在此,它基于语音启动和停止语音识别 . 它还在VoiceRecorder.java中提供了一个SPEECH_TIMEOUT_MILLIS设施,它与RecognizerIntentEXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS相同,但是由用户控制 .

    总而言之,你可以指定静音超时,并根据它在用户输出后停止,并在用户开始说话后立即重新开始 .

  • 0

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

  • 0

    最近关于'google-speech ' and on ' android-opus'(opuslib)的项目允许简单的并发识别以及音频记录到android ext中的opus文件 . 存储 .

    查看语音项目中的VoiceRecorder,在读取麦克风缓冲区后只需几行额外的代码,除了当前的语音观察器之外,缓冲区还可以被fileSink(PCM16到Opus-codec)使用 .

    Google-speech-opus-recorder看到上面两个项目的最小合并

相关问题