Android AudioRecording 丢失最后几秒的音频

Android AudioRecording losing last few seconds of audio

简单的录音机代码会丢失最后几秒的音频。

使用AudioRecordclass我已经把我的麻烦减少到一个非常简单的情况。

一个开始按钮、一个停止按钮和一个从 AudioRecord 对象读取并写入文件的线程。

它运行良好,但在许多设备上,最后三秒的音频不会写入文件,除非我在用户按下停止按钮后继续录制音频 3 秒。

我正在使用 44100 单声道 16 位模式。

设备是 Nexus something 运行ning 5.x 和 Samsung S4 运行ning 5.0.1.

不好的情况:

按下开始按钮,运行线程(.start()),按下停止按钮。 .stop() .release() 在文件上调用 .sync()。最后三秒的音频没有保存到文件中。

好的案例:

按开始,运行 线程,(.start() 按停止。继续记录线程 3 秒,然后调用 .stop() .release() 在文件上调用 .sync()。所有预期数据都在文件中。

开始按钮调用以下 运行nable,停止按钮设置记录 = 0,这会导致线程结束。

(我删除了所有的 try 块以提高可读性)

录音设置

int minAudioBufferSizeInBytes = AudioRecord.getMinBufferSize( 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);

mAudioRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_MONO,  AudioFormat.ENCODING_PCM_16BIT , 4 * minAudioBufferSizeInBytes);

int mFileBufferSizeInBytes = 8 * minAudioBufferSizeInBytes;

recording = 1;

记录线程(运行启用)

mAudioRecorder.startRecording();
while (recording == 1) {
readsize = mAudioRecorder.read(audiodata, 0, mFileBufferSizeInBytes/2);
if (readsize != AudioRecord.ERROR_INVALID_OPERATION && mAudioRecordFos != null) {
    mAudioRecordFos.write(audiodata,0,readsize); // File Output Stream
}
}
if (mRecorderRunOn > 0) {   // RunOn time in milliseconds
Log.d(TAG, "AudioRecord record reading on for " + mRecorderRunOn + "ms ");
long readon_ts = System.currentTimeMillis() + mRecorderRunOn;

while (System.currentTimeMillis() < readon_ts) {
    readsize = mAudioRecorder.read(audiodata, 0, mFileBufferSizeInBytes/2);
    if (readsize>0) {
    mAudioRecordFos.write(bytes,0,readsize); // File Output Stream
    }
}
}

mAudioRecordFos.getFD().sync();

mAudioRecorder.stop();
mAudioRecorder.release();

在另一个版本中,我在调用 .stop() 后继续阅读,直到它报告没有更多数据,但该版本并没有改变丢失数据的数量。

很抱歉,我的 OP 中的代码运行良好。 原来问题出在我的播放机制上。 我通过使用 adb 从 phone 中提取音频来减少未知数,然后使用 alsa aplay 播放录音。

我以为我已经检查过好几次了,但又一次通过测试发现了问题..

基本上

adb pull /storage/extSdCard/6178190842925110523
aplay -r 48000 -c 1 -f S16_LE 6178190842925110523

确定问题不在代码的记录端。