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

使用AVPlayer播放PlayerItem时触发async_runAsynchronousCommandOnQueue错误

解决AVPlayer播放时出现async_runAsynchronousCommandOnQueue错误的方法

这个错误我之前在处理AVPlayer播放逻辑时也碰到过,虽然不影响视频正常播放,但控制台的报错确实挺闹心的。结合我的实践经验,给你几个可行的解决方案:

1. 等待AVAsset加载完成后再创建PlayerItem

你当前的代码直接用AVAsset初始化PlayerItem,但AVAsset的轨道、元数据等信息是异步加载的,直接创建可能触发内部队列的异常。可以通过loadValuesAsynchronously(forKeys:)等待资产加载完成后再处理:

let avAsset = AVAsset(url: url)
// 等待资产加载关键信息(比如音视频轨道)
avAsset.loadValuesAsynchronously(forKeys: ["tracks"]) { [weak self] in
    guard let self = self else { return }
    var error: NSError?
    let status = avAsset.statusOfValue(forKey: "tracks", error: &error)
    if status == .loaded {
        // 加载完成后再创建PlayerItem和Player
        let playerItem = AVPlayerItem(asset: avAsset)
        self.avPlayer = AVPlayer()
        self.playerLayer = AVPlayerLayer(player: self.avPlayer)
        self.playerLayer.videoGravity = .resizeAspectFill
        self.avPlayer.replaceCurrentItem(with: playerItem)
        // 记得把playerLayer添加到视图层级
        self.view.layer.addSublayer(self.playerLayer)
        self.playerLayer.frame = self.view.bounds
        self.avPlayer.seek(to: .zero)
        self.avPlayer.play()
    } else {
        print("Asset加载失败: \(error?.localizedDescription ?? "未知错误")")
    }
}

2. 确保Player和PlayerLayer的生命周期正确

如果avPlayer或playerLayer是局部变量,可能会被提前释放,导致内部异步任务抛出错误。建议把它们声明为类的属性,持有强引用:

class YourPlayerViewController: UIViewController {
    // 用属性持有,避免提前释放
    private var avPlayer: AVPlayer!
    private var playerLayer: AVPlayerLayer!
    
    func setupPlayer(with url: URL) {
        // 这里写上面的加载逻辑
    }
}

3. 调整seek和play的调用时机

你当前在replaceCurrentItem后立刻调用seek和play,此时PlayerItem可能还未准备就绪。可以监听PlayerItem的状态,在它准备好后再执行播放操作:

// 给PlayerItem添加就绪监听
NotificationCenter.default.addObserver(self, selector: #selector(onPlayerItemReady(_:)), 
                                       name: .AVPlayerItemNewAccessLogEntry, 
                                       object: playerItem)

// 监听回调
@objc private func onPlayerItemReady(_ notification: Notification) {
    guard let playerItem = notification.object as? AVPlayerItem, 
          playerItem.status == .readyToPlay else {
        return
    }
    avPlayer.seek(to: .zero)
    avPlayer.play()
    // 记得在合适的时机移除监听
    NotificationCenter.default.removeObserver(self, name: .AVPlayerItemNewAccessLogEntry, object: playerItem)
}

4. 验证视频文件本身的有效性

有时候这个错误也可能是视频文件损坏、格式不被AVPlayer支持导致的。可以先检查URL是否有效,或者用系统QuickTime打开视频文件,确认文件本身没有问题。

一般来说,按照上面的方法调整后,这个异步队列的错误就会消失了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:52:05