Swift使用AVAudioPlayer播放音频报OSStatus 2003334207错误如何解决
错误根因
- 调用逻辑时序错误:
downloadTask是异步执行的,你启动任务后立刻调用play方法时,音频文件还未完成下载,同时AVAudioPlayer本身不支持直接播放远程HTTP URL,仅支持播放本地已存在的音频文件,你传入的远程地址无法被解析识别,就会抛出2003334207错误,对应的就是音频文件格式/类型不支持的系统错误码。 AVAudioPlayer生命周期错误:你将player定义为play方法内的局部变量,方法执行完毕后player会被系统自动回收,即便后续文件下载完成,也会出现播放刚启动就中断的问题。- 多余请求冗余:你针对同一个音频资源同时发起了
dataTask和downloadTask两次请求,完全没有必要,还会占用额外带宽。 - ATS安全限制:iOS默认的应用传输安全(ATS)策略禁止HTTP协议的网络请求,你使用的
http://127.0.0.1地址如果没有在Info.plist中配置豁免规则,也会导致资源加载失败。
修复方案
- 把
AVAudioPlayer提升为类的全局属性,避免被提前释放 - 删除无用的
dataTask请求,仅保留downloadTask - 等待
downloadTask下载完成、文件成功移动到沙盒之后,再传入本地文件URL调用播放方法 - 在Info.plist中添加ATS配置,允许本地HTTP请求:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsLocalNetworking</key> <true/> </dict>
修正后可运行代码:
// 把player定义为全局属性 var player: AVAudioPlayer? func fu(){ let randomCode = Int.random(in: 0...5000) let randomString = randomCode.description guard let url = URL(string: "http://127.0.0.1:5000/\(randomString)") else { return } let downloadTask = URLSession.shared.downloadTask(with: url) { [weak self] urlOrNil, responseOrNil, errorOrNil in guard let fileURL = urlOrNil, let response = responseOrNil as? HTTPURLResponse, (200..<299).contains(response.statusCode), errorOrNil == nil else { print("下载失败:\(errorOrNil?.localizedDescription ?? "未知错误")") return } do { let documentsURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) let savedURL = documentsURL.appendingPathComponent(response.suggestedFilename ?? fileURL.lastPathComponent) // 如果同名文件已存在先删除 if FileManager.default.fileExists(atPath: savedURL.path) { try FileManager.default.removeItem(at: savedURL) } try FileManager.default.moveItem(at: fileURL, to: savedURL) // 下载完成后回到主线程调用播放,传入本地文件URL DispatchQueue.main.async { self?.play(url: savedURL) } } catch { print ("文件操作错误: \(error)") } } downloadTask.resume() } func play(url:URL) { print("正在播放本地文件:\(url)") do { player = try AVAudioPlayer(contentsOf: url) player?.prepareToPlay() player?.volume = 1.0 player?.play() print("播放启动成功") } catch let error as NSError { print("播放失败:\(error.localizedDescription),错误码:\(error.code)") } }
内容的提问来源于stack exchange,提问作者Ulto 4
相关产品推荐
相关产品推荐

