Android:AudioRecord/AudioTrack跨设备音频录放异常求助
Android AudioRecord与AudioTrack指定不同设备路由异常问题解析
问题原因
- 通话类音频属性的强制绑定策略:你使用了
USAGE_VOICE_COMMUNICATION(通话用途)的音频属性,这类场景下Android系统会默认强制输入输出设备绑定,目的是保证通话场景的音频同步(比如蓝牙通话时必须配套使用蓝牙的麦克风和扬声器)。当你设置AudioTrack的播放设备后,系统会自动调整AudioRecord的路由与其保持一致,优先满足通话场景的一致性要求。 - preferredDevice的"偏好"特性:
preferredDevice并非强制指定设备,它只是向系统传递你的设备选择偏好。当存在音频策略冲突(比如通话类场景的绑定要求)时,系统会忽略该偏好,按照预设的策略调整实际路由。
Android是否支持输入输出设备分离?
支持,但需要满足以下条件:
- 避免使用通话类音频属性:将AudioRecord的音频源从
VOICE_COMMUNICATION改为MIC,AudioTrack的用途从USAGE_VOICE_COMMUNICATION改为USAGE_MEDIA、USAGE_GAME等非通话类属性。这类非通话场景下,系统允许输入输出设备独立选择。 - 设备硬件支持:部分低端设备或定制系统可能限制多音频设备同时工作,需要设备本身具备多音频通路的硬件能力。
- Android版本要求:Android 10(API 29)及以上版本对多音频设备路由的支持更完善,低版本可能存在兼容性问题。
修复代码示例
修改音频属性和源,解除通话场景的强制绑定:
// 初始化AudioRecord时使用普通MIC源 audioRecord = AudioRecord( MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_FLOAT, frameSize * Float.SIZE_BYTES ) audioRecord?.preferredDevice = mic // 初始化AudioTrack时使用媒体类用途 audioTrack = AudioTrack.Builder() .setAudioAttributes( AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) .build() ) .setAudioFormat( AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_FLOAT) .setSampleRate(PLAYBACK_SAMPLE_RATE) .setChannelMask(AudioFormat.CHANNEL_OUT_MONO) .build() ) .setBufferSizeInBytes(frameSize * Float.SIZE_BYTES * 2) .build() audioTrack?.preferredDevice = speaker
额外注意事项
- 可以通过
AudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS/GET_DEVICES_OUTPUTS)获取当前可用的输入输出设备列表,确保指定的设备处于可用状态。 - 监听设备连接状态变化(通过
AudioManager.ACTION_AUDIO_BECOMING_NOISY或AudioDeviceCallback),动态调整AudioRecord和AudioTrack的设备路由,避免设备断开后出现异常。
内容的提问来源于stack exchange,提问作者ajw
相关产品推荐
相关产品推荐

