Audio Session — 这是什么,类别及 iOS 中的配置

作者: IT Sectr 发布日期: 2026-05-24 阅读时间: 8 分钟

Audio Session — iOS 用于管理应用程序音频行为的中央机制:与系统交互、处理中断和音频路由。每个 iOS 应用程序获得一个唯一的音频会话,它决定了声音在屏幕锁定、来电和蓝牙连接时的行为。根据 Apple Developer Documentation, 2026Audio Session 通过类别和模式进行配置 — 没有正确的配置,应用程序可能无法在后台播放声音。

要点

  • Audio Session (AVAudioSession) — iOS 系统对象,在操作系统级别管理应用程序的音频行为。
  • 会话类别决定基本行为:playbackrecordambientplayAndRecord 等。
  • 模式和选项进一步明确行为:defaultvoiceChatvideoRecordingallowBluetooth
  • 在中断时(来电、闹钟)会话通过 NotificationCenter 接收带有 interruptionType 类型的通知。
  • 要在后台播放,需要激活 Background Modes — Audio, AirPlay and Picture in Picture

什么是 Audio Session?

Audio Session — 是系统在应用程序启动时创建的一个 AVAudioSession 实例,并在其整个生命周期中存在。它充当应用程序和 iOS 音频系统之间的中介:类别配置决定应用程序是否可以在后台播放声音、在通话时声音是否会被调低以及音频输出到哪些设备。

与 Android Audio Focus 不同(每个应用程序独立请求和释放焦点),iOS Audio Session 通过每个应用程序一个会话进行集中管理。当会话激活时,系统会自动停用前一个应用程序的会话,并向其发送中断通知。这种架构差异决定两个平台上音频处理的不同方法。

根据 WWDC 2024 Session 211,约 40% 的 iOS 应用程序音频问题是由 Audio Session 配置不当引起的。最常见的错误 — 选择 ambient 类别而不是 playback,导致屏幕锁定后声音消失。

AVAudioSession 的工作原理

启动时,应用程序获取会话的共享实例,通过调用 setCategory(_:mode:options:) 设置类别,并通过 setActive(true) 激活会话。激活后,iOS 考虑类别策略进行路由。如果另一个应用程序激活了自己的会话,当前应用程序会通过 Notification.Name.AVAudioSessionInterruption 接收 AudioSessionInterruptionType.began 通知。

Audio Session 类别

类别 — Audio Session 的主要参数,定义了六种预定义的行为变体。选择类别是 iOS 中音频配置的第一个也是最重要的决定。

类别何时使用后台音频静音时降低
ambient游戏、背景效果
playback音乐、播客、有声书
record录音机、声音录制不适用
playAndRecordVoIP、语音消息
multiRouteDJ 混音器、卡拉 OK
soloAmbient默认(iOS 默认)

Playback 类别 — 播放器的主要选择

对于音乐和视频播放器,始终使用 playback。此类别允许:在屏幕锁定、静音开关关闭(iPhone 机身上的物理按钮)和应用程序最小化时播放声音。没有 playback 类别,会话会在屏幕锁定或应用程序最小化时停用。

Ambient 类别适用于游戏和带有背景音的应用程序 — 允许其他应用程序继续播放。例如,如果用户正在听音乐并打开带有 ambient 会话的游戏,音乐会继续在游戏音效之上播放。这是与 Android 的根本区别,在 Android 中,这种场景需要明确的 duck 许可。

如何配置 Audio Session

Audio Session 配置应在任何播放开始之前执行。建议在 application(_:didFinishLaunchingWithOptions:) 方法或播放器初始化器中配置会话。配置类别后,需要激活会话。

Swift 中的 Audio Session 基本配置

swift
import AVFAudio

let session = AVAudioSession.sharedInstance

do {
    try session.setCategory(
        playback,
        mode: default,
        options: [allowBluetooth, defaultToSpeaker]
    )
    try session.setActive(true)
} catch {
    print("Audio Session 设置失败:\(error.localizedDescription)")
}

Options 参数包括 allowBluetooth(输出到蓝牙耳机)和 defaultToSpeaker(通过扬声器播放,而不是听筒)。allowBluetooth 选项对于支持蓝牙耳机的应用程序是必需的 — 没有它,即使连接了耳机,声音也可能通过内置扬声器输出。

录音和播放配置(VoIP)

swift
let session = AVAudioSession.sharedInstance
try session.setCategory(
    playAndRecord,
    mode: voiceChat,
    options: [allowBluetooth, allowBluetoothA2DP]
)

try session.overrideOutputAudioPort(speaker)
try session.setActive(true)

PlayAndRecord 类别配合 voiceChat 模式优化语音通信的音频路径:包括回声抑制、自动增益控制(AGC)和选择最佳编解码器。OverrideOutputAudioPort(.speaker) 强制通过扬声器输出,即使连接了耳机 — 适用于免提通话。

会话的激活和停用

调用 setActive(true) 激活会话并通知系统应用程序将使用音频。暂停播放时,建议停用会话以便其他应用程序可以获取音频流。例外 — 具有长时间后台播放的应用程序(音乐、播客),会话在整个曲目期间保持活跃。

处理 setActive 的错误很重要。如果另一个高优先级会话处于活动状态(例如通话中的电话),setActive 可能会报错。在这种情况下,需要等待 AudioSessionInterruptionType.ended 通知并重试激活。

Audio Session 模式和策略

模式进一步细化类别并针对特定使用类型优化音频路径。每种模式更改 AGC、回声抑制和编解码器的行为。模式不取代类别,而是补充类别 — 一个类别可以与不同模式一起使用。

  • default — 音乐和视频的标准模式。AGC 关闭,回声抑制最小。
  • voiceChat — 针对 VoIP 的优化。包括回声抑制、AGC、降噪。与 playAndRecord 类别一起使用。
  • videoRecording — 用于视频录制。录制质量优先于播放。与 record 或 playAndRecord 类别一起使用。
  • measurement — 用于音频测量。最小信号处理,无 AGC 或回声抑制。
  • gameChat — 用于游戏中的语音聊天。类似于 voiceChat,但优先考虑游戏音效。
  • moviePlayback — 用于观看电影。优化多声道音频(5.1、7.1)和 Dolby Atmos。

Audio Session 类别选项

选项提供会话行为的微调。每个选项是一个标志,可以在数组中与其他选项组合。例如,[.allowBluetooth, .defaultToSpeaker, .interruptSpokenAudioAndMix] 允许将声音输出到蓝牙耳机、默认使用扬声器并与有声书混音。

在 iOS 17+ 中出现了 spatialAudio 选项,它通过 AVAudioSessionSpatialPreferences 为 AirPods 激活个性化空间音频。根据 WWDC 2024,空间音频在 Apple 测试中将音乐应用程序用户的参与度提高了 25%。

处理中断和来电

中断 — Audio Session 与 Android Audio Focus 的主要区别。在 iOS 中,中断通过 NotificationCenter 订阅 AVAudioSession.interruptionNotification 来处理。通知包含一个带有中断类型的字典:began 或 ended。

订阅中断通知

swift
override func viewDidLoad() {
    super.viewDidLoad()
    let center = NotificationCenter.default
    center.addObserver(
        self,
        selector: #selector(handleInterruption),
        name: AVAudioSession.interruptionNotification,
        object: nil
    )
}

@objc func handleInterruption(_ notification: Notification) {
    guard let userInfo = notification.userInfo,
        let type = userInfo[AVAudioSession.interruptionTypeKey]
            as? AVAudioSessionInterruptionType
    else { return }

    switch type {
    case began:
        pausePlayback()
    case ended:
        guard let options = userInfo[AVAudioSession.interruptionOptionKey]
            as? AVAudioSessionInterruptionOptions
        else { return }

        if options.contains(shouldResume) {
            resumePlayback()
        }
    }

收到 interruptionType.began 时,播放器应暂停播放。在 interruptionType.ended 时,interruptionOptionKey 属性指示播放器是否可以自动恢复(shouldResume)。如果用户结束了通话,shouldResume = true。如果通话因超时而结束 — shouldResume = false,不允许恢复。

处理来自其他应用程序的中断

当另一个应用程序以 playback 类别激活其 Audio Session 时,当前会话会收到中断通知。如果其他应用程序使用 ambient,则不会发生中断 — 声音会混合。这种行为与 Android 截然不同,在 Android 中,任何 Audio Focus 激活都会触发 LOSS 事件。

对于应在其他会话激活时继续播放的应用程序(例如,音乐播放时的导航),请使用 .mixWithOthers 选项。此选项允许与其它应用程序混合声音,并且不会发送中断。MixWithOthers — iOS 中 Android duck 模式的对应。

音频路由和蓝牙

Audio Session 自动管理内置扬声器、耳机、蓝牙耳机和 AirPlay 设备之间的音频路由。应用程序可以通过 currentRoute 属性跟踪当前路由,并通过 AVAudioSession.routeChangeNotification 接收更改通知。

连接蓝牙耳机时,如果会话配置了 allowBluetooth 选项,iOS 会自动将音频输出切换到它们。没有此选项,声音继续通过内置扬声器输出。从 iOS 16 开始,连接 AirPods Pro 时,系统会自动启用 ProMotion 同步以减少延迟。

监控路由变化

订阅 routeChangeNotification 可以响应耳机的连接和断开。当蓝牙耳机断开时,播放器应暂停播放 — 用户可能不希望声音从电话扬声器开始播放。根据 Apple HIG(2026),这是音乐应用程序的强制行为。

AvailableInputsavailableOutputs 属性返回可用音频设备列表及其类型(builtInSpeaker、headphones、bluetoothA2DP、hdmi)。开发人员可以通过 overrideOutputAudioPort 以编程方式选择特定设备以实现自定义路由方案。

常见问题

Audio Session 和 Android Audio Focus 有什么区别?

主要区别 — 架构。Audio Session 是每个应用程序一个集中式会话,配置一次。Android 中的 Audio Focus 每次播放都需要手动请求焦点。此外,iOS 通过 mixWithOthers 选项支持混音,而在 Android 中 duck 是完全停止的唯一替代方案。

为什么 iPhone 屏幕锁定后声音消失了?

最常见的原因 — Audio Session 的 类别不正确。如果选择了 ambient 或 soloAmbient,声音会在屏幕锁定时停止。切换类别为 playback,并确保在 Info.plist 中添加了 Background Modes — Audio, AirPlay, and Picture in Picture。

如何允许两个应用程序在 iOS 中同时播放?

在 setCategory 中添加 .mixWithOthers 选项。这将允许您的应用程序的声音与其他活跃会话混合。没有此选项,新应用程序会中断当前应用程序。MixWithOthers — Android 中 duck 模式的对应,但完全保留音量。

如何以编程方式将声音切换到蓝牙扬声器?

使用带有 nil 的 overrideOutputAudioPort 进行自动选择。强制输出到蓝牙:从 availableOutputs 获取 AVAudioSessionRouteDescription,选择类型为 .bluetoothA2DP 的端口并传递给 overrideOutputAudioPort。确保会话配置了 allowBluetooth。

暂停播放器时需要调用 setActive(false) 吗?

对于大多数应用程序 — 是的。暂停时停用会话允许其他应用程序获得音频焦点。例外 — 具有长时间后台播放的音乐播放器。如果暂停时间短(少于 5 秒),最好保持会话活跃以便快速恢复。

总结

  • Audio Session (AVAudioSession) — iOS 中每个应用程序一个音频会话,在操作系统级别管理声音行为。
  • 六种类别:ambientplaybackrecordplayAndRecordmultiRoutesoloAmbient — 确定基本音频行为。
  • 要在后台播放,必须使用 playback 类别和 Info.plist 中的 Background Modes
  • 中断通过 NotificationCenter 处理,类型为 began(暂停)和 ended(在 shouldResume 时恢复)。
  • .MixWithOthers 选项启用与其他应用程序的声音混合而不中断。
  • 路由自动管理,但通过 routeChangeNotification 监控以在耳机断开时暂停。
  • PlayAndRecord 类别配合 voiceChat 模式 — 具有回声抑制和 AGC 的 VoIP 应用程序的标准。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读