You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI+AVAudioPlayer中MPNowPlayingInfo仅在播放状态变更后显示问题

锁屏/控制中心MPNowPlayingInfo显示异常问题

问题现象

  • 首次启动音频播放并切换至后台/锁屏/控制中心时,仅显示播放/暂停控制按钮,无歌曲标题、艺人等播放信息
  • 点击锁屏上的播放/暂停按钮后,播放信息会短暂显示几秒后消失

锁屏状态说明:

  • 初始锁屏:仅控制按钮,无任何播放信息
  • 点击暂停后:播放信息短暂出现后消失

已配置项

已开启的后台模式:

Audio, AirPlay, and Picture in Picture

相关代码

AppDelegate代码

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()

        do {
            try AVAudioSession.sharedInstance().setCategory(.playback)
            try AVAudioSession.sharedInstance().setActive(true)
        } catch {
            print("Error configuring audio session: \(error)")
        }

        return true
    }
}

已正确设置音频会话类别为.playback并激活会话,核心播放逻辑在MusicPlayerManager类中,主视图onAppear时调用setPlayer(withURL:)方法。

MusicPlayerManager代码

class MusicPlayerManager: ObservableObject {
    @Published var audioPlayer: AVAudioPlayer? = nil
    @Published var isPlaying: Bool = false {
        didSet {
            if isPlaying {
                audioPlayer?.play()
            } else {
                audioPlayer?.pause()
            }

            setupNowPlayingInfo() /// 此处调用能更新信息(有效)
        }
    }

    /// 创建AVAudioPlayer
    func setPlayer(withURL: URL) {
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: withURL)
            isPlaying = true

            setupRemoteControlCenter()
            setupNowPlayingInfo() /// 此处调用无效
            print(MPNowPlayingInfoCenter.default().nowPlayingInfo) /// 日志能正确打印播放信息
        } catch {
            print("Failed to set audio player: \(error)")
        }
    }

    /// 配置远程控制
    private func setupRemoteControlCenter() {
        let commandCenter = MPRemoteCommandCenter.shared()

        commandCenter.playCommand.addTarget { event in
            self.isPlaying = true
            return .success
        }

        commandCenter.pauseCommand.addTarget { event in
            self.isPlaying = false
            return .success
        }
    }

    /// 设置播放信息
    private func setupNowPlayingInfo() {
        var nowPlayingInfo: [String: Any] = [:]

        nowPlayingInfo[MPMediaItemPropertyTitle] = "Your Track Title"
        nowPlayingInfo[MPMediaItemPropertyArtist] = "Your Artist"

        if let albumArtwork = UIImage(named: "app-icon") {
            nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: albumArtwork.size) { _ in albumArtwork }
        }

        nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = true

        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
    }
}

关键细节

  • setPlayer(withURL:)中首次调用setupNowPlayingInfo()时,日志能正确输出播放信息,但锁屏/控制中心无显示
  • 点击锁屏控制按钮触发isPlaying状态变化时,setupNowPlayingInfo()能让播放信息短暂显示
  • App内切换播放/暂停时,播放信息无法在锁屏显示;尝试添加播放时长等参数后仍无效

测试环境

  • Xcode版本:15.0.1、15.1
  • 测试设备:iPhone 14 Pro Max(iOS 17.1.2)、iPhone 11 Pro Max(iOS 16.6.1)

补充日志

首次设置播放信息时出现以下日志:

Entitlement: com.apple.mediaremote.external-artwork-validation - Entitled: NO - Error: (null)

疑问

即使封面加载失败,为何歌曲标题、艺人等其他播放信息也无法显示?

内容的提问来源于stack exchange,提问作者Trevor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:45:15