音频路由使用说明
本文档基于rtc/src/main/java/cn/seastart/rtc/media/audioRouter/AudioRouterManager.java 的实际实现整理,适用于在通话、会议、语音互动等场景中管理扬声器 / 听筒 / 有线耳机 / 蓝牙耳机路由。
1. 获取 AudioRouterManager
rtcEngine.getAudioRouterManager() 会返回单例对象;对应释放方法为:
2. 推荐初始化顺序
推荐在进入房间 / 开始通话时按下面顺序初始化:- 获取
AudioRouterManager - 设置回调监听
- 设置音频模式
setMode(...) - 设置自动切换策略
setAutoChangeAudioRouter(...) - 调用
init()启动路由监听
3. setMode 使用说明
AudioManager 为准,常用值包括:
AudioManager.MODE_NORMALAudioManager.MODE_RINGTONEAudioManager.MODE_IN_CALLAudioManager.MODE_IN_COMMUNICATIONAudioManager.MODE_CALL_SCREENINGAudioManager.MODE_CALL_REDIRECTAudioManager.MODE_COMMUNICATION_REDIRECT
说明
- 当前项目
minSdk = 24,实际走的是 Android 6.0+ 路径。 - 在 6.0+ 实现中,
init()不会自动设置音频模式,需要业务层主动调用setMode(...)。 - 因此建议:每次切换场景前都重新设置一次 mode,例如语聊、会议、媒体播放等场景切换时都重新调用。
4. setAutoChangeAudioRouter 自动切换策略
4.1 简单用法
- 开启自动切换
- 听筒优先级高于扬声器
- 蓝牙耳机优先级高于有线耳机
4.2 完整用法
isAutoChangetrue:由内部自动切换音频路由false:仅监听设备变化,不自动切换,由业务层手动调用switchAudioRouter(...)
isPrioritySpeakertrue:扬声器优先级高于听筒false:听筒优先级高于扬声器
isPriorityWiredEarphonetrue:有线耳机优先级高于蓝牙耳机false:蓝牙耳机优先级高于有线耳机
4.3 自动切换规则(基于代码实现)
自动切换总体遵循以下策略:- 后接入的设备通常会触发一次重新选路。
- 大类优先级:蓝牙耳机 / 有线耳机 > 听筒 / 扬声器。
- 同组内优先级可通过参数自定义:
- 蓝牙耳机 vs 有线耳机:由
isPriorityWiredEarphone控制 - 听筒 vs 扬声器:由
isPrioritySpeaker控制
- 蓝牙耳机 vs 有线耳机:由
- 设备移除后,会按照剩余设备重新选择可用路由。
- 同时存在蓝牙耳机和有线耳机:
isPriorityWiredEarphone = false时,优先蓝牙耳机isPriorityWiredEarphone = true时,优先有线耳机
- 没有耳机类设备时:
isPrioritySpeaker = false时,优先听筒isPrioritySpeaker = true时,优先扬声器
5. 回调说明
5.1 当前存在的输出设备变化
- 连接 / 断开蓝牙耳机
- 插入 / 拔出有线耳机
- 系统可用输出设备发生变化
AudioOutputDeviceType:
SPEAKER:扬声器EARPIECE:听筒WIRED_EARPHONE:有线耳机BLUETOOTH_HEADSET:蓝牙耳机UN_KNOW:未知 / 自动选择占位值
当前项目minSdk = 24,因此这里的AudioDeviceInfo在实际项目中通常可用;源码中“低于 Android 6.0 时可能为 null”的说明主要是兼容性保留。
5.2 当前活跃输出设备变化
5.3 路由变化可能产生噪音
- 暂停播放器
- 降低音量
- 弹提示给用户
6. 获取当前可用设备和当前生效设备
6.1 获取当前存在的输出设备
6.2 获取当前活跃输出设备
6.3 蓝牙名称纠正(可选)
部分机型通过AudioDeviceInfo.getProductName() 获取到的蓝牙名称可能不准确,此时可以使用:
如果要获取更准确的蓝牙设备名称,请确保蓝牙相关权限已授权;Android 12 及以上需要关注 BLUETOOTH_CONNECT 权限。
7. 手动切换路由
大多数情况下,这一步是用户点击 UI 按钮触发的。selectType 为 AudioOutputDeviceType 枚举值,例如:
特殊值:UN_KNOW
UN_KNOW 时,不表示切换到“未知设备”,而是表示:按当前自动选路策略重新选择一个最合适的路由。
适合以下场景:
- 用户点“恢复系统推荐路由”
- 插拔设备后,主动要求 SDK 重新计算最佳设备
8. 释放资源
推荐通过rtcEngine 统一释放:
RTCEngineImpl 的实现,releaseAudioRouterManager() 内部会调用:
- 停止音频路由监听
- 注销相关广播 / 回调
- 将音频模式恢复为
AudioManager.MODE_NORMAL - 将输出切回扬声器
9. 常用设备枚举
UN_KNOW:未知 / 触发自动选择SPEAKER:扬声器EARPIECE:听筒WIRED_EARPHONE:有线耳机BLUETOOTH_HEADSET:蓝牙耳机
10. 推荐实践
- 进入房间时初始化,退出房间时释放,不要在每次按钮点击时重复创建。
- 每次切换业务场景都调用一次
setMode(...)。 - UI 上展示“当前正在使用哪个设备”时,优先以
activeOutputDeviceChange(...)为准。 - 需要展示“用户可选哪些设备”时,以
exitOutputDeviceChange(...)或getExitAudioOutputDevices()为准。 - 使用蓝牙设备时,建议在真机上验证:
- 连接蓝牙耳机
- 断开蓝牙耳机
- 插入 / 拔出有线耳机
- 手动切换扬声器 / 听筒 / 蓝牙
- 如果业务中同时存在多种音频播放/通话状态,建议重点验证不同设备切换下的实际表现。
11. Demo 中的实际初始化方式
app/src/main/java/cn/seastart/rtcdemo/activity/RoomActivity.kt 中实际使用方式如下: