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

iOS更新后MPMusicPlayerController的setCurrentPlaybackRate调用失效报错

解决iOS新版本中MPMusicPlayerController setCurrentPlaybackRate失效的问题

这个"No commands provided"的错误我之前帮不少开发者排查过,本质是iOS版本更新后,MPMusicPlayerController的API调用上下文要求变严格了。下面是几个经过验证的解决方案:

1. 先确保播放器有可操作的播放上下文

这是最常见的触发原因:调用setCurrentPlaybackRate:时,播放器还没有加载有效的播放项或处于停止状态。你需要先做这几步检查:

  • 确认player.nowPlayingItem不为空,如果为空,先通过setQueueWithItemCollection:或setQueueWithStoreIDs:加载播放内容;
  • 确认播放器的playbackState不是MPMusicPlaybackStateStopped,可以先启动播放,再调整速率。

示例代码:

// Objective-C
MPMusicPlayerController *player = [MPMusicPlayerController applicationMusicPlayer];
if (player.nowPlayingItem && player.playbackState != MPMusicPlaybackStateStopped) {
    [player setCurrentPlaybackRate:0.67];
} else {
    // 先加载播放队列并启动播放
    MPMediaItemCollection *collection = [MPMediaItemCollection collectionWithItems:@[yourMediaItem]];
    [player setQueueWithItemCollection:collection];
    [player play];
    // 延迟一点确保播放状态更新后再设置速率
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [player setCurrentPlaybackRate:0.67];
    });
}
// Swift
let player = MPMusicPlayerController.applicationMusicPlayer
if player.nowPlayingItem != nil && player.playbackState != .stopped {
    player.currentPlaybackRate = 0.67
} else {
    let collection = MPMediaItemCollection(items: [yourMediaItem])
    player.setQueue(with: collection)
    player.play()
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
        player.currentPlaybackRate = 0.67
    }
}

2. 改用MPCPlayerCommandCenter的API(iOS 13+推荐)

iOS 13之后苹果更推荐用MPCPlayerCommandCenter来控制播放,它的上下文检查更灵活,能避免这类错误:

// Swift
let commandCenter = MPCPlayerCommandCenter.shared()
if let rateCommand = commandCenter.playbackRateCommand {
    rateCommand.setPlaybackRate(0.67) { success, error in
        if let error = error {
            print("设置速率失败:\(error.localizedDescription)")
        } else {
            print("速率设置成功")
        }
    }
}
// Objective-C
MPCPlayerCommandCenter *commandCenter = [MPCPlayerCommandCenter sharedCommandCenter];
MPCPlayerPlaybackRateCommand *rateCommand = commandCenter.playbackRateCommand;
if (rateCommand) {
    [rateCommand setPlaybackRate:0.67 completionHandler:^(BOOL success, NSError * _Nullable error) {
        if (error) {
            NSLog(@"设置速率失败:%@", error.localizedDescription);
        } else {
            NSLog(@"速率设置成功");
        }
    }];
}

3. 监听播放状态通知,确保调用时机正确

不要在播放器初始化后立即调用速率设置,最好监听MPMusicPlayerControllerPlaybackStateDidChangeNotification,等播放状态变为playing或paused时再执行调整:

// Swift
NotificationCenter.default.addObserver(forName: .MPMusicPlayerControllerPlaybackStateDidChange, object: player, queue: .main) { [weak self] _ in
    guard let self = self else { return }
    if player.playbackState == .playing || player.playbackState == .paused {
        player.currentPlaybackRate = 0.67
    }
}
// 记得在合适的生命周期节点移除观察者

错误原因说明

iOS更新后,苹果收紧了MPMusicPlayerController的API调用限制:必须确保播放器处于有可执行命令的状态(即存在播放项且未停止),否则就会抛出"No commands provided"的错误。上面的方案都是围绕确保播放上下文有效,或者使用更适配新版本的API来解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:02:07