使用AudioRecord录制内部音频偶现杂音问题求助
解决AudioRecord后台录制内部音频偶发杂音问题
你的代码存在几个核心问题,这些正是导致偶发杂音的主要原因:
- 循环内重复创建IO流与缓冲区:每次循环都新建
FileOutputStream会覆盖已有录制数据,频繁分配ByteBuffer还会引发内存抖动,直接导致音频采样丢帧。 - 忽略
read()实际返回值:直接用AudioRecord.getMinBufferSize()作为写入长度,而read()可能因系统负载没读满缓冲区,写入空数据就会产生杂音。 - 重复计算最小缓冲区大小:
getMinBufferSize()应在初始化阶段计算一次,循环内重复调用可能导致数值不一致,引发录制异常。 - 变量名拼写错误:代码中
konfigurasyon是拼写错误,应使用之前创建的configuration,否则会导致AudioRecord初始化异常(若未编译报错大概率是笔误)。
修复步骤
- 提前初始化核心资源:录制线程启动前,计算好最小缓冲区大小,创建一次性的ByteBuffer和FileOutputStream,避免循环内频繁IO与内存操作。
- 用
read()实际返回值写入文件:仅当read()返回有效长度(>0)时才写入,避免空数据混入。 - 统一资源释放逻辑:录制结束时集中关闭流、释放AudioRecord,避免资源泄漏。
- 优化线程优先级:给录制线程设置高优先级,降低被系统低优先级任务抢占的概率。
修正后的代码示例
初始化部分
// 提前计算最小缓冲区大小,避免循环内重复计算 int minBufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT); // 建议放大缓冲区,降低丢帧概率 int actualBufferSize = minBufferSize * 2; AudioPlaybackCaptureConfiguration configuration = new AudioPlaybackCaptureConfiguration.Builder(mediaProjection) .addMatchingUsage(AudioAttributes.USAGE_MEDIA) .build(); AudioFormat audioFormat = new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setSampleRate(44100) .setChannelMask(AudioFormat.CHANNEL_IN_STEREO) .build(); AudioRecord audioRecord = new AudioRecord.Builder() .setAudioFormat(audioFormat) .setAudioPlaybackCaptureConfig(configuration) // 修正变量名拼写错误 .build(); // 提前创建缓冲区与输出流 ByteBuffer buffer = ByteBuffer.allocateDirect(actualBufferSize); FileOutputStream os = null; try { File audioFile = new File(context.getExternalFilesDir(Environment.DIRECTORY_MUSIC), "tempAudio.pcm"); os = new FileOutputStream(audioFile, true); // 追加模式写入,避免覆盖已有数据 } catch (IOException e) { e.printStackTrace(); audioRecord.release(); return; } audioRecord.startRecording();
录制线程部分
Thread recordingThread = new Thread(() -> { while (recordAudio) { try { // 获取实际读取的音频数据长度 int readSize = audioRecord.read(buffer.array(), 0, actualBufferSize); if (readSize > 0) { // 仅写入有效数据 os.write(buffer.array(), 0, readSize); buffer.clear(); } else if (readSize <= AudioRecord.ERROR_BAD_VALUE) { // 读取错误,终止录制 recordAudio = false; Log.e("Recording", "AudioRecord read error: " + readSize); } } catch (Exception e) { e.printStackTrace(); break; } } // 录制结束统一释放资源 try { if (audioRecord.getState() == AudioRecord.STATE_INITIALIZED) { audioRecord.stop(); audioRecord.release(); } if (os != null) { os.flush(); os.close(); } } catch (IOException e) { e.printStackTrace(); } // 按需清理临时文件(比如录制失败时删除) if (!recordAudio) { new File(context.getExternalFilesDir(Environment.DIRECTORY_MUSIC) + "/tempAudio.pcm").delete(); } showNotification(context); }); // 设置线程高优先级,减少被抢占概率 recordingThread.setPriority(Thread.MAX_PRIORITY); recordingThread.start();
额外注意事项
- 避免录制时同时进行高CPU/IO占用的后台任务(如文件下载、大内存计算)。
- 若杂音仍存在,可尝试调整采样率(如48000Hz)或单声道录制,部分设备对特定格式兼容性更好。
内容的提问来源于stack exchange,提问作者AllahinAskeri
相关产品推荐
相关产品推荐

