如何从Android

时间:2017-12-09 01:00:12

标签: android microphone android-audiomanager android-audiorecord pocketsphinx-android

我在Android上使用pocketsphynx库进行关键字定位,它的目的非常好。但是,当我尝试释放麦克风以在应用程序的另一个组件中使用它时,我无法这样做。我在logcat中收到以下错误:

12-11 10:19:55.827 255-30344/? I/AudioFlinger_Threads: AudioFlinger's thread 0xa6cc0000 ready to run
12-11 10:19:55.849 255-31292/? W/APM::AudioPolicyManager: startInput(17675) preempting low-priority input 17671
12-11 10:19:55.859 255-29587/? W/AudioALSAStreamManager: -routingInputDevice(), input_device == AUDIO_DEVICE_NONE(0x0), return
12-11 10:19:55.924 27054-1900/? W/AudioRecord: dead IAudioRecord, creating a new one from obtainBuffer()
12-11 10:19:55.925 255-30344/? W/AudioALSAStreamManager: -routingInputDevice(), input_device == current_input_device(0x80000004), return
12-11 10:19:55.927 255-30346/? I/AudioFlinger_Threads: AudioFlinger's thread 0xaa880000 ready to run
12-11 10:19:55.930 255-31292/? W/APM::AudioPolicyManager: stopInput() unknown input 17671
12-11 10:19:55.930 255-31292/? W/APM::AudioPolicyManager: releaseInput() releasing unknown input 17671
12-11 10:19:55.931 255-953/? W/APM::AudioPolicyManager: startInput(AUDIO_SOURCE_HOTWORD) invalid, already started high-priority input 17675
12-11 10:19:55.931 27054-1900/? W/AudioRecord: restoreRecord_l() failed status -38
12-11 10:19:55.934 27054-1900/? E/AudioRecord-JNI: Error -38 during AudioRecord native read
12-11 10:19:55.951 27054-1900/? E/AudioProvider: audioRecord read failed
                                                 com.google.android.apps.gsa.shared.exception.GsaIOException: Error code: 393221 | not open
                                                     at com.google.android.libraries.assistant.hotword.a.a(SourceFile:67)
                                                     at com.google.android.libraries.assistant.hotword.b.run(SourceFile:30)
                                                     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
                                                     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
                                                     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
                                                     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                     at java.lang.Thread.run(Thread.java:818)

当我尝试使用getUserMedia中的WebView时会发生这种情况。在这样做之前,我正在打电话

recognizer.cancel();

来自我的活动,但这似乎没有帮助。

我也尝试使用.stop().removeListener(...) API,但问题仍然存在。请建议是否有办法释放pocketphinx制作的麦克风,以便应用程序的其他组件可以再次使用麦克风。

感谢任何帮助。

更新1 :添加了更多日志并查看了AudioPolicyManager的Android代码。似乎有两个流程(31292953)尝试通过startInput调用竞争,而一个(31292)关闭另一个(953) 。显然,我可能会错误地解释日志。

更新2 :我查看了pocketphynx SpeechRecognizer.shutdown方法,发现这是实际上释放AudioRecord对象的方法。通过试验结束错误,我设法弄清楚如何调用shutdown而不是崩溃应用程序(它必须在onResult中发生,在删除所有侦听器之后)。在那之后,我的另一个组件开始工作。我还没有机会确认是否可以在shutdown之后重新启动关键字定位。如果在此之后需要重新初始化(这需要花费很多时间),那么这将不是一个可接受的解决方法。

更新3:我确认shutdown无需释放麦克风。我在调用stop API后设法创建了我的其他组件。关键似乎是停止pocketphinx需要一点时间,另一个组件应该等待。我用过的对我有用的事件是onResult。此时,另一个组件已经能够获得新的AudioRecord。在那之后我仍然没有尝试重新启动pocketphinx。

1 个答案:

答案 0 :(得分:0)

好吧,我让它上班了。调用SpeechRecognizer.shutdown确实没必要。我能够使用SpeechRecognizer.stop API,同时确保等待最后一个结果进入我onResult实施的RecognitionListener回调中。之后,我可以调用getUserMedia浏览器API,并成功获取麦克风。

我的onResult实施中的

RecognitionListener代码:

recognizer.removeListener(listener);

我还能够确认重新开始识别很容易,我只需要执行以下操作:

recognizer.addListener(listener);
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
recognizer.startListening(KWS_SEARCH);

注意:我在一个单独的线程中停止识别器,类似于识别器的实例化方式,但我还没有确认是否有必要。