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

Android系统内部音频实时采集延迟问题求助

解决Android音频播放捕获延迟问题

1. 优化缓冲区大小

硬编码固定缓冲区大小是导致延迟的核心原因之一,应使用系统推荐的最小缓冲区大小,避免过大缓冲堆积:

val minBufferSize = AudioRecord.getMinBufferSize(
    sampleRate,
    AudioFormat.CHANNEL_IN_MONO,
    AudioFormat.ENCODING_PCM_16BIT
)
// 可将最小缓冲区放大1.5-2倍避免溢出,但不要超过最小的3倍
internalRecorder = AudioRecord.Builder()
    .setAudioFormat(audioFormat)
    .setBufferSizeInBytes(minBufferSize * 2)
    .setAudioPlaybackCaptureConfig(config)
    .build()

2. 检查音频格式参数

确保audioFormat采用低延迟友好的配置:

  • 采样率:优先选择44100Hz或48000Hz(设备原生支持的采样率,避免重采样开销)
  • 声道:使用CHANNEL_IN_MONO(单声道数据量更小,处理更快)
  • 编码:ENCODING_PCM_16BIT(高效通用的编码格式)

示例配置:

val audioFormat = AudioFormat.Builder()
    .setSampleRate(44100)
    .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
    .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
    .build()

3. 提升捕获线程优先级

将音频读取操作放在高优先级线程执行,确保系统优先分配CPU资源:

val captureThread = HandlerThread("AudioCaptureThread", Process.THREAD_PRIORITY_AUDIO)
captureThread.start()
val handler = Handler(captureThread.looper)

handler.post {
    val buffer = ShortArray(minBufferSize / 2) // 16位PCM每个样本占2字节
    while (internalRecorder.recordingState == AudioRecord.RECORDSTATE_RECORDING) {
        val readSize = internalRecorder.read(buffer, 0, buffer.size)
        if (readSize > 0) {
            // 在此处理波形振幅计算逻辑
        }
    }
}

4. 精简捕获配置

只添加实际需要的音频Usage,减少系统筛选音频流的开销:

val config = AudioPlaybackCaptureConfiguration.Builder(mediaProjection!!)
    .addMatchingUsage(AudioAttributes.USAGE_MEDIA)
    .addMatchingUsage(AudioAttributes.USAGE_GAME)
    // 移除USAGE_UNKNOWN,避免捕获无关音频流
    .build()

5. 系统层面额外优化

部分厂商为功耗优化默认增大了音频缓冲区,可引导用户在开发者选项中尝试:

  • 开启「禁用音频效果」
  • 开启「低延迟音频」(设备支持时)
  • 关闭「绝对音量」(部分设备会影响音频处理链路)

内容的提问来源于stack exchange,提问作者Diego M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:31:06