4. CarService 音频路由策略详解

音频路由是车载语音助手与 CarService 协同的核心环节。CarService 通过 CarAudioManager 和 AudioPolicy 提供了一套多层次的音频路由策略,确保不同场景下的音频流能够正确、无冲突地输出到目标设备。本章将深入解析默认路由规则、基于应用的路由以及基于上下文的动态路由机制。

4.1 默认路由规则

默认路由规则是音频路由的基础,定义了当没有特定上下文或应用约束时,音频流如何被分配到物理输出设备。CarService 在启动时根据车辆硬件配置(如扬声器、蓝牙、AUX 等)建立默认的音频设备映射表。

音频设备类型 默认路由目标 典型使用场景
主扬声器 (Primary Speaker) 全车扬声器系统 媒体播放、系统提示音
蓝牙 (Bluetooth A2DP) 已配对的蓝牙设备 电话通话、流媒体音乐
AUX 输入 外部音源直连 手机有线连接播放
USB 音频 USB 音频设备 USB 耳机、外置 DAC

默认路由规则遵循“最近优先”原则:系统会优先将音频路由到当前处于活跃状态的、优先级最高的设备。例如,当蓝牙未连接时,媒体音频默认走主扬声器;一旦蓝牙连接,媒体音频自动切换至蓝牙设备。

关键点: 默认路由规则由 audio_policy_configuration.xml 文件定义,OEM 可根据车辆硬件定制该文件,以调整默认路由行为。

4.2 基于应用的路由

基于应用的路由允许系统根据发起音频请求的应用类型(如导航、电话、媒体)来动态调整路由目标。CarService 通过 CarAudioContext 将应用音频流分类,并映射到对应的音频焦点组和设备组。

4.2.1 音频上下文与设备映射

每个应用在请求音频时,必须指定其 CarAudioContext。CarService 根据该上下文选择预定义的设备组。以下为常见的映射关系:

CarAudioContext 对应设备组 路由行为
MUSIC 主扬声器 / 蓝牙 默认路由至全车扬声器,蓝牙连接时切换
NAVIGATION 驾驶位扬声器 / 头枕扬声器 仅驾驶员区域播放,避免干扰乘客
CALL 蓝牙 / 车载麦克风+扬声器 优先蓝牙,无蓝牙时使用车载免提
VOICE_COMMAND 驾驶位扬声器 + 麦克风阵列 语音助手交互,需低延迟回采
SYSTEM_SOUND 全车扬声器 系统提示音、警告音
实践建议: 语音助手应用应使用 VOICE_COMMAND 上下文,以确保音频路由至驾驶位扬声器并启用麦克风回采,实现高效的语音交互。

4.2.2 应用路由优先级

当多个应用同时请求音频时,CarService 根据音频焦点策略决定路由优先级。高优先级应用(如电话、导航)可以抢占低优先级应用(如媒体)的音频通道。

  1. 电话 (CALL) — 最高优先级,可暂停所有其他音频。
  2. 导航 (NAVIGATION) — 高优先级,可混音或短暂打断媒体。
  3. 语音命令 (VOICE_COMMAND) — 高优先级,通常与导航同级。
  4. 系统提示 (SYSTEM_SOUND) — 中优先级,可短暂打断媒体。
  5. 媒体 (MUSIC) — 最低优先级,可被其他音频打断或衰减。

4.3 基于上下文的动态路由

动态路由策略根据车辆当前状态(如行驶模式、乘客位置、通话状态)实时调整音频输出路径。这是车载音频系统智能化的核心体现。

4.3.1 导航场景动态路由

导航音频需要在不干扰媒体播放的前提下,清晰传达给驾驶员。CarService 支持以下动态路由策略:

  • 驾驶位独占路由: 导航提示音仅从驾驶位扬声器或头枕扬声器输出,乘客区域的媒体音频不受影响。
  • 混音衰减: 导航提示期间,媒体音频自动降低音量(Ducking),导航结束后恢复。
  • 蓝牙导航: 若车辆连接了蓝牙耳机,导航音频可单独路由至蓝牙设备,实现私密导航。
导航场景动态路由流程 导航应用请求音频 CarAudioManager 音频焦点检查 驾驶位扬声器 混音衰减媒体 蓝牙设备路由 动态路由根据车辆状态(行驶模式、蓝牙连接、乘客位置)选择最优输出路径 导航提示结束后,媒体音频自动恢复原始音量

4.3.2 电话场景动态路由

电话通话对音频路由有严格的要求:必须保证双向音频(上行麦克风、下行扬声器)的稳定性和隐私性。

  • 蓝牙优先: 当蓝牙免提设备(HFP)可用时,通话音频自动路由至蓝牙,提供更好的音质和隐私。
  • 车载免提: 无蓝牙时,通话音频路由至车载麦克风和扬声器,系统自动启用回声消除(AEC)和噪声抑制(NS)。
  • 隐私模式: 若车辆检测到乘客存在,通话音频可仅从驾驶位扬声器输出,避免隐私泄露。

4.3.3 媒体场景动态路由

媒体音频的路由相对灵活,但需要与其他音频源协调。

媒体源 动态路由策略 说明
本地媒体 全车扬声器 / 区域扬声器 可根据乘客选择播放区域(如仅后排播放)
蓝牙流媒体 蓝牙设备 / 全车扬声器 蓝牙连接时优先蓝牙,断开后自动切换回扬声器
USB 媒体 USB 音频设备 / 扬声器 USB 设备插入时自动路由,拔出后恢复默认
在线流媒体 全车扬声器 通常固定路由至主扬声器系统
注意: 媒体音频在动态路由中应避免与导航、电话音频产生冲突。建议在代码中实现音频焦点监听,当检测到高优先级音频时,媒体应用主动暂停或降低音量。

4.4 动态路由的代码实现示例

以下示例展示了如何在 CarService 中为导航应用设置动态路由:

// 获取 CarAudioManager 实例
CarAudioManager carAudioManager = (CarAudioManager) getSystemService(Context.CAR_AUDIO_SERVICE);

// 创建音频请求,指定上下文为 NAVIGATION
CarAudioRequest request = new CarAudioRequest.Builder(context)
    .setCarAudioContext(CarAudioContext.NAVIGATION)
    .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
    .build();

// 注册音频焦点监听器,实现动态路由
carAudioManager.registerCarAudioFocusListener(new CarAudioFocusListener() {
    @Override
    public void onAudioFocusChange(int focusChange, CarAudioRequest request) {
        if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
            // 导航获得焦点,路由至驾驶位扬声器
            carAudioManager.setPreferredDeviceForCarAudioContext(
                CarAudioContext.NAVIGATION, 
                getDriverSeatSpeakerDevice()
            );
        } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
            // 导航失去焦点,恢复默认路由
            carAudioManager.clearPreferredDeviceForCarAudioContext(
                CarAudioContext.NAVIGATION
            );
        }
    }
});

// 请求音频焦点
carAudioManager.requestAudioFocus(request, null, 
    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
最佳实践: 动态路由应结合车辆传感器数据(如座椅占用检测、车速、蓝牙连接状态)进行决策。建议在 CarService 中维护一个 AudioRoutingPolicy 类,集中管理所有路由规则,便于调试和扩展。

4.5 路由策略对比总结

路由策略 触发条件 路由粒度 典型应用
默认路由 系统启动 / 无特定上下文 设备级别 系统提示音、未分类音频
基于应用的路由 应用指定 CarAudioContext 应用级别 导航、电话、媒体
基于上下文的动态路由 车辆状态变化 / 音频焦点事件 场景级别 导航提示、电话通话、语音交互