<AudioRecord> "无法获取录音源1的音频输入"

16

我一直在尝试初始化Android的AudioRecord,但遇到了问题。我在网上搜索了很长时间,但没有成功。

我的手机是三星GalaxyS,SDK版本为7。在初始化AudioRecord时,我将采样率设为8000,声道设置为MONO,音频格式设置为16位,并且根据日志显示,最小缓冲区大小设置为4160。我在清单文件中添加了AUDIO_RECORD权限。

初始化代码如下:

...
private static int SAMPLE_RATE = 8000;
private static int CHANNEL_CONFIG = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private static int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
// ??? Both 8Bit and Default are deemed illegal.

public MicVolumeManager() {
    this.bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
        CHANNEL_CONFIG, AUDIO_FORMAT);
    PhoneDebugger.debug("AUDIO-BUFFER-SIZE", 
        Integer.toString(this.bufferSize));

    this.recorder = new AudioRecord(AudioSource.MIC, SAMPLE_RATE,
        CHANNEL_CONFIG, AUDIO_FORMAT, this.bufferSize);

    this.audioBuffer = new byte[this.bufferSize];
}
...

然而,该对象(this.recorder)未能初始化。以下是使用DDMS记录的日志:

AUDIO-BUFFER-SIZE(3253): 4160
AudioRecord(3253): set(): sampleRate 8000, channels 16, frameCount 2080
AudioPolicyManager(2175): getInput() inputSource 1, samplingRate 8000, format 1, channels 10, acoustics 0
AudioFlinger(2175): openInput() openInputStream returned input 0x0, SamplingRate 8000, Format 1, Channels 10, acoustics 0, status -17
AudioRecord(3253): 无法为记录源1获取音频输入
AudioRecord-JNI(3253): 创建AudioRecord实例时出错:初始化检查失败。
AudioRecord-Java(3253): [android.media.AudioRecord] 在初始化本地AudioRecord对象时出现错误代码-20。

请问有什么帮助吗?非常感谢!

7个回答

16

对我来说,原因是未能调用 AudioRecord.release() 以释放先前的 AudioRecord 实例; 它会占用 AudioFlinger 中的本地资源,并干扰后续的 AudioRecord 实例。在三星迷人版(Galaxy S)Android 2.1(爱克莱尔)上看到过这种情况; 可能是爱克莱尔或三星实现特别不耐烦。


9

遇到了相同的错误,直到我重新启动设备。

看起来在我的Galaxy S上,本地实现有缺陷:在整个手机运行时间内多次获取和释放AudioRecorder会导致该错误。


1
请注意我的上面的回答,我的手机也是三星Galaxy S,它有一个本地层,对于AudioRecord.release()的调用非常挑剔。 - Liudvikas Bukys
我也遇到了Galaxy S的同样问题。有什么办法可以确保我不会再遇到这个问题吗?O.o - Mario Lenci
我遇到了相同的问题,当我重新启动后它就开始工作了。我该怎么做才能避免这个问题再次出现? - Renjith K N

5

使用音频录制器后,必须停止并释放它。然后,下一次初始化音频录制器时,就可以正常使用了。


4

你好,当我尝试初始化一个AudioRecord对象时,遇到了同样的问题。解决方法是在实例化当前的AudioRecord对象之前测试配置参数。以下是我使用的程序:

    /**
 * Scan for the best configuration parameter for AudioRecord object on this device.
 * Constants value are the audio source, the encoding and the number of channels.
 * That means were are actually looking for the fitting sample rate and the minimum
 * buffer size. Once both values have been determined, the corresponding program
 * variable are initialized (audioSource, sampleRate, channelConfig, audioFormat)
 * For each tested sample rate we request the minimum allowed buffer size. Testing the
 * return value let us know if the configuration parameter are good to go on this
 * device or not.
 * 
 * This should be called in at start of the application in onCreate().
 * 
 * */
public void initRecorderParameters(int[] sampleRates){

    for (int i = 0; i < sampleRates.length; ++i){
        try {
            Log.i(TAG, "Indexing "+sampleRates[i]+"Hz Sample Rate");
            int tmpBufferSize = AudioRecord.getMinBufferSize(sampleRates[i], 
                            AudioFormat.CHANNEL_IN_MONO,
                            AudioFormat.ENCODING_PCM_16BIT);

            // Test the minimum allowed buffer size with this configuration on this device.
            if(tmpBufferSize != AudioRecord.ERROR_BAD_VALUE){
                // Seems like we have ourself the optimum AudioRecord parameter for this device.
                AudioRecord tmpRecoder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
                                                        sampleRates[i], 
                                                        AudioFormat.CHANNEL_IN_MONO,
                                                        AudioFormat.ENCODING_PCM_16BIT,
                                                        tmpBufferSize);
                // Test if an AudioRecord instance can be initialized with the given parameters.
                if(tmpRecoder.getState() == AudioRecord.STATE_INITIALIZED){
                    String configResume = "initRecorderParameters(sRates) has found recorder settings supported by the device:"  
                                        + "\nSource   = MICROPHONE"
                                        + "\nsRate    = "+sampleRates[i]+"Hz"
                                        + "\nChannel  = MONO"
                                        + "\nEncoding = 16BIT";
                    Log.i(TAG, configResume);

                    //+++Release temporary recorder resources and leave.
                    tmpRecoder.release();
                    tmpRecoder = null;

                    return;
                }                   
            }else{
                Log.w(TAG, "Incorrect buffer size. Continue sweeping Sampling Rate...");
            }
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "The "+sampleRates[i]+"Hz Sampling Rate is not supported on this device");
        }
    }
}

我希望你能够理解。
迪克万

3
如果您没有获取录音权限,请先获取权限。如果您已经获取了权限,但仍然遇到错误,请将手机关闭然后重新开启,再次运行您的应用程序。

3

这也影响三星Galaxy平板GT-P1000及之后的10.1版本。

这个漏洞很难重现,唯一的方法是重新启动以逃脱这种糟糕的状态...

三星有一个bug跟踪器吗?


0

我认为音频硬件无法支持你设定的10个通道作为输入,所以请尝试使用2个通道,并观察是否可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接