You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android录制原始音频字节到变量供AudioTrack播放的实现稳定性咨询

针对Android音频录制writeAudioToLocalVariable方法的稳定性优化建议

现有实现的潜在问题

你的当前代码可以正常运行,但存在4个会影响多设备兼容性和稳定性的风险点:

  • 未处理AudioRecord.read()的返回值:该方法返回的是本次实际读取到的有效字节数,你当前不管返回值直接写满整个缓存数组到输出流,会导致末尾写入大量无效脏数据,出现杂音、音频长度不符的问题。
  • 硬编码缓存大小:你虽然打印了系统返回的最小缓存值,但实际初始化和读取用的是固定的8192,如果某台设备的最小缓存要求大于8192,AudioRecord会直接初始化失败,出现崩溃。
  • 线程可见性问题:isRecording变量没有加volatile修饰,主线程修改该变量后,录音子线程可能感知不到变量更新,导致录音无法停止、循环一直运行。
  • 未处理读取错误:read方法会返回负数代表出现异常(比如录音被抢占、硬件故障),你当前没有判断错误状态,出现问题后会继续循环写入无效数据。

优化后的实现方案

第一步:修改基础变量配置

// 给isRecording加volatile保证线程可见性
volatile boolean isRecording = false;
// 删除硬编码的MY_CHOSEN_BUFFER_SIZE,改用动态计算的缓存大小
private int RECORD_BUFFER_SIZE;

第二步:onCreate里计算合适的缓存大小

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    int minBufferSize = AudioRecord.getMinBufferSize(SAMPLERATE,
            REC_CHANNELS, ENCODING);
    Log.i("ABC", "FYI, min buffer size for this device is : " + minBufferSize);
    // 取最小缓存的2倍,保证所有设备都不会出现缓存不足丢帧的问题
    RECORD_BUFFER_SIZE = Math.max(minBufferSize * 2, 8192);
}

第三步:重写writeAudioToLocalVariable方法

private void writeAudioToLocalVariable() {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] temporaryChunkOfBytes = new byte[RECORD_BUFFER_SIZE];
    while (isRecording) {
        int readResult = recorder.read(temporaryChunkOfBytes, 0, RECORD_BUFFER_SIZE);
        // 读取失败直接退出循环
        if (readResult < 0) {
            Log.e("ABC", "Recording read error, code: " + readResult);
            break;
        }
        // 只写入实际读到的有效字节数
        if (readResult > 0) {
            baos.write(temporaryChunkOfBytes, 0, readResult);
        }
    }
    recordedAudioAsBytes = baos.toByteArray();
    try {
        baos.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

第四步:同步修改AudioRecord初始化、AudioTrack初始化的缓存参数为RECORD_BUFFER_SIZE即可。

额外优化建议

  • 播放完成后记得调用player.stop()、player.release()释放AudioTrack资源,避免出现内存泄露、音频设备被占用的问题。
  • 短音频播放可以改用AudioTrack.MODE_STATIC,你之前无法使用大概率是因为之前的音频数据末尾有脏数据,优化数据后即可正常使用,延迟更低。

内容的提问来源于stack exchange,提问作者Nerdy Bunz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 09:54:04