WWDC Quick Look 💓 By SwiftGGTeam
Enhance your app’s audio recording capabilities

Enhance your app’s audio recording capabilities

观看原视频

Highlight

iOS 26 给录音类 app 带来四件事:app 内切麦克风、AirPods 高质量蓝牙录音、AVAssetWriter 录制空间音频、播放时用 Audio Mix 调节人声与环境音的平衡。


核心内容

录音 app 长期被一个尴尬卡住:用户接上一支新麦克风,却必须退出 app、回到「设置」里挑设备,再切回来。AirPods 也同样别扭——蓝牙链路为通话优化,录出来的人声压得很扁,背景却又灌得很满。空间音频则是另一头:iOS 18 只让 AVCaptureMovieFileOutput 录得动,纯音频 app(像 Voice Memos)想录空间音频根本没接口。

iOS 26 一次性回应了这四个痛点。AVInputPickerInteraction 把输入设备选择搬进 app 内部,带实时音量条和麦克风模式,系统会记住选择。bluetoothHighQualityRecording 给 AirPods 打开一条专为内容创作调过音的蓝牙链路,平衡人声与环境。AVAssetWriter 现在能写出符合 Spatial Audio 规范的 .qta 文件,包含一条 AAC 立体声轨、一条 APAC 空间音频轨、外加 metadata 轨。播放端则是 Cinematic 框架开放的 Audio Mix——和 Photos app 编辑空间音频视频时同款的能力,让用户在 Cinematic / Studio / In-Frame 三种风格间切换,再加一根强度滑杆调节前景与背景比重。


详细内容

输入设备选择(02:10)。 AVInputPickerInteraction 是一个 NSObject 子类,挂到任意 UIView 上即可弹出输入选择 UI。Audio Session 必须先配置好,否则列表会不准。

import AVKit

class AppViewController {

    // Configure AudioSession

    // AVInputPickerInteraction is a NSObject subclass that presents an input picker
    let inputPickerInteraction = AVInputPickerInteraction()
    inputPickerInteraction.delegate = self

    // connect the PickerInteraction to a UI element for displaying the picker
    @IBOutlet weak var selectMicButton: UIButton!
    self.selectMicButton.addInteraction(self.inputPickerInteraction)

    // button press callback: present input picker UI
    @IBAction func handleSelectMicButton(_ sender: UIButton) {
        inputPickerInteraction.present()
    }
}

关键点:

  • AVInputPickerInteraction() 创建 picker 实例;delegate 必须设为承载它的 view controller。
  • addInteraction 把它挂到一个真实的 UI 控件上(这里是 UIButton)。
  • present() 在用户点击时调出选择菜单,包含可用设备列表、实时音量表和麦克风模式视图。
  • 调用前要先完成 audio session 配置,picker 才会显示正确的设备集合。

AirPods 高质量录音(03:57)。 这是一条专门给内容创作调过音的蓝牙链路,介于 LAV 麦克风的人声与环境平衡之间。AVAudioSession 通过 category option 启用,AVCaptureSession 通过 capture session 属性启用。

// AVAudioSession clients opt-in - session category option
AVAudioSessionCategoryOptions.bluetoothHighQualityRecording

// AVCaptureSession clients opt-in - captureSession property
session.configuresApplicationAudioSessionForBluetoothHighQualityRecording = true

关键点:

  • bluetoothHighQualityRecordingAVAudioSessionCategoryOptions 上的新选项,与已有的 allowBluetoothHFP 并存;同时打开时高质量为默认,HFP 作为回退。
  • configuresApplicationAudioSessionForBluetoothHighQualityRecording = true 让 capture session 自动接管 audio session 配置,省去手工设置。
  • 启用后,系统级输入菜单会在设备列表里展示「高质量 AirPods」条目。

空间音频捕获(05:11 起)。 iOS 26 给 AVAssetWriter 路径开了空间音频写入。一份合格的空间音频文件包含两条音频轨(AAC 立体声 + APAC FOA)和至少一条 metadata 轨。FOA(First Order Ambisonics)有 4 个通道:1 个全向分量 + 3 个分别指向 X/Y/Z 的偶极分量。

实操关键 API:

  • AVCaptureDeviceInput.multichannelAudioMode = .firstOrderAmbisonics 把麦克风阵列切到 FOA 模式。
  • AVCaptureSession 在 FOA 模式下最多挂两个 AudioDataOutput,一个输出 FOA、一个输出 Stereo,分别对应两条音频轨。
  • 新属性 spatialAudioChannelLayoutTag 决定每个 ADO 的输出格式(Stereo 或 FOA)。
  • AVCaptureSpatialAudioMetadataSampleGenerator 接收 FOA buffer,录制结束时生成带时间戳的 metadata sample,再写入第三个 AVAssetWriterInput
  • iOS 26 还允许 AVCaptureMovieFileOutputAVAudioDataOutput 同时跑,一边落盘一边实时绘制波形或加效果。

Audio Mix 播放(13:26)。 Audio Mix 用一个强度(0~1)和一个风格枚举控制人声与环境音的比重。

import Cinematic

// Audio Mix parameters (consider using UI elements to change these values)
var intensity: Float32 = 0.5 // values between 0.0 and 1.0
var style = CNSpatialAudioRenderingStyle.cinematic

// Initializes an instance of CNAssetAudioInfo for an AVAsset asynchronously
let audioInfo = try await CNAssetSpatialAudioInfo(asset: myAVAsset)

// Returns an AVAudioMix with effect intensity and rendering style.
let newAudioMix: AVAudioMix = audioInfo.audioMix(effectIntensity: intensity,
                                                 renderingStyle: style)

// Set the new AVAudioMix on your AVPlayerItem
myAVPlayerItem.audioMix = newAudioMix

关键点:

  • CNAssetSpatialAudioInfo(asset:) 异步从 asset 读出空间音频元信息。
  • audioMix(effectIntensity:renderingStyle:) 返回一个 AVAudioMix,可直接挂到 AVPlayerItem.audioMix 上播放。
  • CNSpatialAudioRenderingStyle 包含 Photos app 同款的 Cinematic / Studio / In-Frame,加上 6 个额外模式(如纯人声 mono stem、纯环境 FOA stem)。
  • intensity 推荐用 UI slider 实时驱动,匹配 demo 中的滑杆体验。

底层:从输入文件取 remix metadata(16:45)。AUAudioMix AudioUnit 路径时,需要把录制时埋入的调音参数传给 AU。

// Get Spatial Audio remix metadata from input AVAsset

let audioInfo = try await CNAssetSpatialAudioInfo(asset: myAVAsset)

// extract the remix metadata. Set on AUAudioMix with AudioUnitSetProperty()
let remixMetadata = audioInfo.spatialAudioMixMetadata as CFData

关键点:

  • spatialAudioMixMetadata 返回录制阶段写入文件的调音参数,类型为 CFData
  • 通过 AudioUnitSetProperty() 设给 AUAudioMix,AU 才会按录制时的 tuning 工作;不设的话效果会偏离录制意图。
  • 这条路径适合需要在自定义渲染图里精确控制 Audio Mix 的 app;常规播放走上面 AVPlayer 那条更省事。

核心启发

  • 做什么:在录音/播客 app 里加一颗「选麦克风」按钮,调用 AVInputPickerInteraction

    • 为什么值得做:用户最常见的弃用场景就是「插了麦却切不过去」,省一次跳出系统设置就能留住一次录音。
    • 怎么开始:先把 audio session 配置点抽出来,再把 picker 挂到现有录音工具栏的某个按钮上,遵循 02:10 的四行写法。
  • 做什么:给所有用 AirPods 的录音流程打开 bluetoothHighQualityRecording

    • 为什么值得做:代码改动只是加一个 option 或一个 bool,但音质从「通话级」直接跳到「内容创作级」,对采访、播客、Vlog 旁白尤其明显。
    • 怎么开始:盘点 app 里所有 AVAudioSessionCategoryOptions 组合处,把 HFP 和高质量并列加上;AVCaptureSession 路径设 configuresApplicationAudioSessionForBluetoothHighQualityRecording = true,依赖系统回退到 HFP。
  • 做什么:把 Voice Memos 类纯音频 app 升级为空间音频录制。

    • 为什么值得做:iOS 26 才让 AVAssetWriter 写得出合规的 .qta,先做的人能拿到 Audio Mix、AirPods 头追踪等下游能力的红利。
    • 怎么开始:参考 sample 工程「Capturing Spatial Audio in your iOS app」搭骨架——一个 FOA AudioDataOutput + 一个 Stereo AudioDataOutput + 一个 metadata generator + 三个 AVAssetWriterInput,按 TN3177 配 alternate track group。
  • 做什么:在已有空间音频播放器上加一根「人声/环境」滑杆。

    • 为什么值得做:让用户自己救回嘈杂场景下录的素材,减少用户因噪音放弃保存的内容。
    • 怎么开始:用 CNAssetSpatialAudioInfo + audioMix(effectIntensity:renderingStyle:) 路径,UI 出三档 style 加一根 slider 直接驱动 intensity,详见 13:26
  • 做什么:把录制和实时波形/效果合并到同一个 AVCaptureSession

    • 为什么值得做:iOS 26 起 MovieFileOutputAudioDataOutput 可以并存,省掉双 session 的同步麻烦,也省一倍的 CPU。
    • 怎么开始:合并现有两条管线,让 AudioDataOutput 只负责 UI 反馈,MovieFileOutput 专注落盘。

关联 Session

评论

GitHub Issues · utterances