Swift 5如何获取MPMediaItem中当前播放Apple Music歌曲歌词
读取Apple Music当前播放歌曲歌词的落地方案
之前方案失效的核心原因
现有的两种读取方法仅适配用户自行导入的、无DRM加密的本地音频文件,对Apple Music生态内的曲目无法正常工作:
MPMediaItem.lyrics仅读取本地音频文件内嵌的歌词元字段,不会同步Apple Music服务器侧托管的动态云歌词内容- 离线下载的Apple Music流媒体曲目带DRM加密,本地资产文件的元数据是受保护的,
AVURLAsset根本没有读取权限,自然拿不到lyrics值 - 纯在线播放的Apple Music流媒体曲目,本地根本不会存储对应的歌词内容,两种读取方法必然返回空结果
有效实现路径(适配iOS 15+)
采用Apple官方的MusicKit框架实现流媒体曲目的歌词读取,步骤如下:
- 权限配置
- 在项目的Info.plist中添加
NSAppleMusicUsageDescription字段,填写访问媒体库的用途说明
- 在项目的Info.plist中添加
- 获取当前播放曲目对应的系统媒体标识
- 对接系统级音乐播放器控制器,拿到当前播放项的唯一持久化ID
import MediaPlayer // 获取系统音乐播放器当前的播放项 guard let nowPlayingItem = MPMusicPlayerController.systemMusicPlayer.nowPlayingItem else { return } let songPersistentID = nowPlayingItem.persistentID
- 通过MusicKit拉取对应曲目的歌词
import MusicKit // 申请媒体访问权限 let authStatus = await MusicAuthorization.request() guard authStatus == .authorized else { // 权限未授权的处理逻辑 return } // 通过本地持久化ID匹配Apple Music目录下的对应歌曲 let idPredicate = Predicate<Song>.persistentID(in: [songPersistentID]) let songQuery = SongRequest(predicate: idPredicate) do { // 拉取匹配的歌曲条目 let matchedSongs = try await songQuery.fetch() guard let targetSong = matchedSongs.items.first else { return } // 拉取该歌曲对应的歌词资源 let lyricsQuery = LyricsRequest(for: targetSong) let lyricsResult = try await lyricsQuery.fetch() // 可选择获取纯文本歌词/带时间轴的逐句歌词 let plainLyrics = lyricsResult.plainText let timedScrollingLyrics = lyricsResult.timedLyrics } catch { // 网络或权限类错误的处理逻辑 }
常见注意事项
- 流媒体歌词拉取依赖当前网络连接,离线状态下无法拉取非本地内嵌的云歌词
- 该方法仅对和Apple Music目录匹配的曲目生效,用户自行导入、无版权匹配的本地文件仍需通过原有的
MPMediaItem.lyrics接口读取内嵌歌词 - 不要直接强制解包
assetURL属性,受DRM保护的流媒体曲目对应assetURL通常为nil,强制解包会触发崩溃
内容的提问来源于stack exchange,提问作者Yogesh Patel
相关产品推荐
相关产品推荐

