Meet the Music Understanding framework
Graphics, Games & Media 进阶 16m

了解 Music Understanding 框架

Meet the Music Understanding framework

2026年6月8日

在 Apple 官方观看视频

一句话判断

这场 Session 最值得关注的一件事是:苹果终于把 Final Cut Pro 里那套极其好用的音频节拍和结构分析能力,剥离出来做成了系统级的 MusicUnderstanding 框架,第三方 App 终于不用自己手搓 FFT(快速傅里叶变换)或买昂贵的第三方 SDK 来做音乐卡点了。

这场 Session 讲了什么

以前你要在 iOS 上做个“根据音乐节奏自动切换视频画面”的功能,要么自己啃 DSP(数字信号处理)写算法,要么把音频传到服务器用 Python 的 librosa 跑一遍再拿结果,体验极差且依赖网络。现在苹果直接给了 MusicUnderstanding 框架,纯设备端离线运行,把脏活累活全包了。

你只需要把 AVAsset 扔给 MusicUnderstandingSession,它就能吐出 6 个维度的数据:调性(Key)、节奏(Rhythm)、结构(Structure)、速度(Pace)、乐器活动(Instrument Activity)和响度(Loudness)。这对做视频剪辑、音乐播放器、甚至是健身卡点 App 的开发者来说简直是降维打击,直接省掉几个月的算法研发时间。

值得深挖的点

按需分析是保命指南,别被默认 API 坑了

Session 里提到一个很容易被忽略的细节:调用 session.analyze() 默认会跑全部 6 个维度的分析。苹果在设备端塞了一个能识别乐器、调性和段落结构的机器学习模型,这玩意的算力开销绝对不小。如果你只是想拿个 BPM(每分钟节拍数)做个简单的跑步歌单,跑全量分析会让用户的手机发热且耗时漫长。

苹果为此提供了 analyze(for:) 这个 targeted API。这里的 trade-off 很明显:全量分析能拿到完整的 SessionResult,但按需分析只会返回你请求的字段,其他的全是 nil。在实际业务中,强烈建议在后台队列明确指定需要的 feature,比如只传 [.rhythm, .pace]。别为了图省事用默认 API,否则在分析长达 10 分钟的播客或 DJ Set 时,你的 App 会被系统直接杀掉后台进程。

时间轴数据结构与 AVFoundation 的完美缝合

做音视频开发最烦的就是时间戳对齐。苹果这次没有用简单的 [Double: Value] 字典,而是专门设计了 TimedValueRangedValue 两个泛型结构体,把数据和 CMTime / CMTimeRange 强绑定。

这个设计非常老道。CMTime 是 AVFoundation 的底层时间单位,拿到 RangedValue<KeySignature> 后,你可以直接把 range.startrange.end 喂给 AVPlayerseek(to:),或者用来裁剪 AVMutableComposition。如果是简单的浮点数时间戳,你还得自己处理采样率转换和精度丢失的问题。苹果把时间轴对齐的坑在框架底层填平了,你直接拿来驱动 UI 或者控制播放器,严丝合缝。

代码片段

1. 初始化 Session 与精准时间配置

场景:从本地导入音频文件并初始化分析会话。

import MusicUnderstanding
import AVFoundation

// 获取到本地音频 URL 后
let asset = AVURLAsset(url: audioURL, 
                       // 必须开启精准时间,否则节拍对齐会有几百毫秒的误差
                       options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])

// 初始化 Session,这一步会加载音频和模型
let session = try await MusicUnderstandingSession(asset: asset)

坑:AVURLAssetPreferPreciseDurationAndTimingKey 设为 true 会导致 asset 加载变慢,因为系统要解码整个文件来计算精确时长。如果是超长音频,记得在 UI 上加个 Loading 状态。

2. 按需分析避免性能陷阱

场景:只获取节奏和速度信息,用于视频卡点剪辑。

// 明确指定只分析节奏和速度,跳过调性、乐器等耗时计算
let results = try await session.analyze(for: [.rhythm, .pace])

// 安全解包,因为没请求的字段会是 nil
if let rhythm = results.rhythm {
    // BPM 可能是 nil(比如纯人声朗读),给个默认值兜底
    let bpm = rhythm.beatsPerMinute ?? 120.0 
    let beatTimes = rhythm.beats // CMTime 数组,直接拿去给 AVPlayer 做卡点
    print("BPM: \(bpm), 节拍数: \(beatTimes.count)")
}

坑:beatsPerMinute 是 optional 的。如果音频是纯人声朗读或者没有明显节奏的白噪音,框架算不出 BPM,这里会返回 nil,必须做好判空处理。

最佳实践

老项目如果之前用了第三方音频分析库(比如 Essentia 的 iOS 移植版),建议直接拔掉。MusicUnderstanding 是系统级框架,不仅包体零增加,而且苹果针对 Apple Silicon 和 Neural Engine 做了底层优化,能耗比完胜第三方。

新项目中,音频分析一定要扔进后台 Task 里跑。虽然框架是异步的(async/await),但它属于 CPU/GPU 密集型任务。千万别在主线程或者普通的 Task { } 里直接 await,建议用 Task.detached(priority: .utility) 来跑,把主线程留给 UI 渲染。另外,利用 TimedValueRangedValue 配合 SwiftUI 的 Canvas 画波形和结构图,比用传统的 UIView 绘制性能好得多。

还有什么值得关注

  • Final Cut Pro 亲测好用:iPad 版 FCP 的自动蒙太奇(Montage)功能就是拿这个框架做的,说明其工业级可靠性已经验证过了。
  • 支持 Custom Audio Provider:除了传 AVAsset,你还能传自定义的音频提供者,这意味着你可以对麦克风实时输入的音频流做特征提取。
  • 官方送了个可视化外挂:Session 提到的 “Music Understanding Lab” 示例 App 直接把 6 个维度的 UI 画好了,抄它的 SwiftUI 可视化代码能省一周时间。
MusicUnderstanding AVFoundation AudioAnalysis SwiftUI