调用startRecording()方法时,Android AudioRecord失败 [英] Android AudioRecord failing when calling the startRecording() method

查看:1536
本文介绍了调用startRecording()方法时,Android AudioRecord失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在android中录制音频并将其存储在字节数组中,为此,我使用了Android的AudioRecord内置类.
我以前已经使用过此类,并且一切都很好,但是由于某种原因,似乎AudioRecord将不再起作用.

I'm trying to record audio in android and store it in an array of bytes, and for that I use Android's AudioRecord built-in class.
I've already used this class before, and all was good, but for some reason, it seems the AudioRecord won't work anymore.

问题是AudioRecord被初始化并且没有显示错误,但是当是时候实际录制东西的时候,通过调用它的'startRecording()方法,事情就失败了,我什至没有得到一个正确的理由.

The problem is that the AudioRecord gets initialized and shows no errors, but when it's time to actually record something, by calling its' startRecording() method, something is failing and I don't even get a proper reason why.

调用此方法后,这是Logcat的输出 ALL :

This is ALL the output from Logcat after calling this method:

01-18 18:54:49.545  11303-11338/com.mypackage E/android.media.AudioRecord﹕ MediaRecorder prepare   CallingPid =  11303  Callinguid=  10128

01-18 18:54:49.545  11303-11338/com.mypackage E/android.media.AudioRecord﹕ java.lang.Throwable
        at android.media.AudioRecord.startRecording(AudioRecord.java:631)
        at mypackage.AudioRecorder.record(AudioRecorder.java:179)

在那之后,当然没有音频被记录下来,对于那些想知道这是否只是内部错误消息的人.

Of course no audio gets recorded after that, for those wondering if it's just an internal error message.

这是用于初始化AudioRecord类的代码:

This is the code for initializing the AudioRecord class:

int bufferSize = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, RECORDER_CHANNEL, RECORDER_AUDIO_ENCODING);

        if (bufferSize != AudioRecord.ERROR_BAD_VALUE && bufferSize > 0)
        {
            // check if we can instantiate and have a success
            AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, AUDIO_SAMPLE_RATE, RECORDER_CHANNEL,
                    RECORDER_AUDIO_ENCODING, bufferSize);

            if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
            {
                m_Recorder = recorder;
                m_RecordingThread = Executors.newSingleThreadExecutor();
                m_IsInitialized = true;
                return;
            }
        }

使用的常量为:

/**
 * Recorded audio's sample rate.
 */
private static final int AUDIO_SAMPLE_RATE = 44100;

/**
 * Recorded audio's channel.
 */
private static final int RECORDER_CHANNEL = AudioFormat.CHANNEL_IN_MONO;

/**
 * Recorded audio's encoding.
 */
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

错误在这里发生:

if (m_Recorder != null)
            m_Recorder.startRecording();

因此,在看到这种情况发生了几次之后,我决定更深入地尝试调试它,使用Jetbrain的反编译器,尽可能深入地调试到AudioRecord类本身的错误源.
由于某些奇怪的原因,一旦应用程序到达错误源处的断点,就无法完成下一个过渡,因为AudioRecord再次崩溃,并显示相同的错误消息.

So after seeing this happen a couple of times, I decided to go deeper and try to debug it, going as deep as I can, to the source of error in the AudioRecord class itself, using Jetbrain's decompiler.
For some strange reason, as soon as the app hit the breakpoint located at the source of error, the next step-over couldn't be completed, as the AudioRecord has crashed yet again, with the same error message.

对我来说,下一步是创建一个示例项目,只是为了测试AudioRecord的功能,但是这次我还添加了一个AudioTrack,以在AudioRecord类管理的情况下立即输出我的所有录音(一种回送).记录某些东西,不管有无错误.
因此,魔术发生了-应用程序正在运行,AudioRecord正在录制,而AudioTrack正在播放.
AudioTrack类突然解决了我所有的问题,这真的很奇怪,因此我将其从代码中删除,然后尝试再次运行该应用程序.
这次,AudioRecord可以正常工作,即使我听不到它的输出,也可以向您保证它已经在录音.

The next step for me was creating a sample project just to test AudioRecord's functionality, but this time I added an AudioTrack as well, that will output all my recordings instantly (a kind of a loopback), in case the AudioRecord class manages to record something, with or without the error.
And so the magic has happened - The app is working, AudioRecord is recording, and AudioTrack is playing.
It seemed really strange that the AudioTrack class suddenly resolved all my issues, so I removed it from my code and tried running the app yet again.
This time, the AudioRecord worked without all problems, and even though I couldn't hear its' output, I can assure you it has been recording.

有点松了一口气,我以为自己终于克服了这个问题,现在可以继续前进了,所以我添加了一些额外的代码来编码和解码记录的音频数据.
为了听到输出,我使用AudioTrack类返回了代码,并运行了该应用程序.

With a bit of relief, I thought to my myself that I've finally overcame this issue, and I'm ready to move forward, so I added some extra code to encode and decode the recorded audio data.
To hear an output, I returned the code using the AudioTrack class, and ran the app.

想听到有趣的事吗?该应用程序已崩溃,并出现相同的错误,再次.

Wanna hear a funny thing? The app has crashed with the same error, AGAIN.

现在从理论上讲,问题可能出在使用完AudioRecord实例后就不会释放出来,但我从一开始就已经介绍过了.

Now theoretically the problem could be not releasing the AudioRecord instance when done using it, but I've covered that too from the very beginning.

我已经尝试在互联网上的几乎所有地方寻找解决方案,但是似乎以前没有人遇到过这样的问题.

I've tried looking practically everywhere on the internet for a solution, but it seems as if no one has even encountered a problem like this before.

此外,我想指出的是,我尝试重置设备,ADB插件并重建所有项目.

Also, I'd like to point out that I've tried resetting my device, the ADB plugin, and rebuilding all projects.

我正在使用配备Android Lollipop(API 21)的魅族MX5手机.

I'm using a Meizu MX5 phone, with Android Lollipop(API 21).

推荐答案

好吧,我解决了这个问题,或者至少解决了一部分,导致它现在可以工作了. 问题是,在调用AudioRecord类的read()方法时,我尝试读取的字节数超过了预分配缓冲区的大小. 尽管它不能解决这篇文章的主要问题,即奇怪的错误消息和未捕获的异常,但它使AudioRecord完美地工作了,因此对我来说,该线程可以看成是已回答并已关闭!

Well, I solved the problem, or at least a part of it, causing it to work now. The thing is I tried to read more bytes than the size of my pre-allocated buffer, upon calling the read() method of the AudioRecord class.
Although it didn't solve the main issue of this post, which is the strange error message and the uncaught exception, it made the AudioRecord work perfectly, so for me this thread can be seen as answered and closed!

这篇关于调用startRecording()方法时,Android AudioRecord失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆