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

解决从FileManager下载的歌曲无法通过AVPlayer播放的问题

AVPlayer无法播放Documents目录本地音频的排查方案

以下是针对你遇到的问题的具体排查方向和解决办法:

1. 验证文件完整性

下载后移动文件的过程可能出现写入不完整的情况,导致文件损坏无法播放。在moveItem后添加文件大小校验:

try FileManager.default.moveItem(at: location, to: destinationUrl)
// 校验源文件与目标文件大小一致
guard let sourceSize = try? FileManager.default.attributesOfItem(atPath: location.path)[.size] as? Int64,
      let destSize = try? FileManager.default.attributesOfItem(atPath: destinationUrl.path)[.size] as? Int64,
      sourceSize == destSize else {
    print("文件移动不完整,可能已损坏")
    return
}
print("File moved to documents folder")
completion(destinationUrl)

2. 监听AVPlayerItem加载状态

直接初始化AVPlayer可能无法及时获取资源状态,通过监听status可以明确失败原因:

audioDownloader.downloadTrack(url: urlString) { url in
    DispatchQueue.main.async {
        let asset = AVURLAsset(url: url)
        let playerItem = AVPlayerItem(asset: asset)
        playerItem.addObserver(self, forKeyPath: "status", options: .new, context: nil)
        self.player = AVPlayer(playerItem: playerItem)
    }
}

// 在当前类中添加监听回调
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard keyPath == "status", let item = object as? AVPlayerItem else {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        return
    }
    
    switch item.status {
    case .readyToPlay:
        self.player?.play()
        self.player?.volume = 1.0
    case .failed:
        print("播放失败原因:\(item.error?.localizedDescription ?? "未知错误")")
    case .unknown:
        print("资源正在加载")
    @unknown default:
        break
    }
}

// 记得在deinit中移除监听
deinit {
    self.player?.currentItem?.removeObserver(self, forKeyPath: "status")
}

3. 修复文件权限

iOS 13+中,临时目录文件移动到Documents后可能存在权限问题,手动设置文件权限:

try FileManager.default.moveItem(at: location, to: destinationUrl)
// 设置文件可读可写权限
try FileManager.default.setAttributes([.posixPermissions: 0o644], ofItemAtPath: destinationUrl.path)

4. 确保Player的生命周期

确认player是类级别属性而非闭包内的局部变量,否则会被立即释放导致播放终止:

class YourClass: UIViewController {
    var player: AVPlayer? // 必须声明在类作用域内
    // ...
}

5. 配置音频会话

iOS需要正确激活音频会话才能播放声音,尤其是静音或后台场景:

// 在播放前添加
do {
    try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
    try AVAudioSession.sharedInstance().setActive(true)
} catch {
    print("音频会话配置失败:\(error)")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:13:21