使用AVAudioPlayer播放Firebase音频报OSStatus Error 2003334207求助
解决AVAudioPlayer播放Firebase远程音频报错2003334207的问题
你遇到的OSStatus 2003334207错误,本质是AVAudioPlayer不支持直接加载远程HTTPS URL——它只能处理本地文件路径的URL(以file://开头),哪怕Chrome能直接播放这个远程音频,AVAudioPlayer也无法直接解析远程地址。
下面给两种可行的解决方案:
方案一:先下载音频到本地,再用AVAudioPlayer播放
通过URLSession将远程音频下载到App沙盒的临时目录,拿到本地URL后再初始化AVAudioPlayer播放:
func startPlaying(url: URL) { let downloadTask = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in guard let self = self, let audioData = data, error == nil else { Helper.shared.printDebug("音频下载失败:\(error?.localizedDescription ?? "未知错误")") return } // 将音频数据写入沙盒临时文件 let tempDirectory = FileManager.default.temporaryDirectory let localAudioURL = tempDirectory.appendingPathComponent(url.lastPathComponent) do { try audioData.write(to: localAudioURL) // 切回主线程初始化播放器并播放 DispatchQueue.main.async { do { self.audioPlayer = try AVAudioPlayer(contentsOf: localAudioURL) self.audioPlayer.prepareToPlay() self.audioPlayer.play() } catch { Helper.shared.printDebug("本地音频播放失败:\(error.localizedDescription)") } } } catch { Helper.shared.printDebug("本地文件写入失败:\(error.localizedDescription)") } } downloadTask.resume() }
方案二:改用AVPlayer直接播放远程URL
AVPlayer是Apple官方用于处理远程流媒体/音频的播放器,支持直接加载HTTPS URL,更适配这种场景:
首先在ViewModel中声明AVPlayer相关对象:
import AVKit class YourViewModel: ObservableObject { var audioPlayer: AVPlayer? var playerStatusObserver: NSKeyValueObservation? // 其他属性... }
然后修改startPlaying函数:
func startPlaying(url: URL) { let playerItem = AVPlayerItem(url: url) audioPlayer = AVPlayer(playerItem: playerItem) // 监听播放状态,处理加载/失败逻辑 playerStatusObserver = playerItem.observe(\.status, options: [.new]) { [weak self] item, _ in guard let self = self else { return } switch item.status { case .readyToPlay: self.audioPlayer?.play() case .failed: Helper.shared.printDebug("播放失败:\(item.error?.localizedDescription ?? "未知错误")") case .unknown: Helper.shared.printDebug("音频加载中...") @unknown default: break } } }
同时调整按钮的播放/暂停逻辑(通过AVPlayer的rate属性判断播放状态):
Button { if vm.audioPlayer?.rate ?? 0 > 0 { vm.audioPlayer?.pause() } else { if vm.audioPlayer == nil { vm.startPlaying(url: audioURL ?? URL(fileURLWithPath: "")) } else { vm.audioPlayer?.play() } } } label: { Image(systemName: (vm.audioPlayer?.rate ?? 0 > 0) ? "pause.fill" : "play.fill") .foregroundColor(.black) .padding() .background( RoundedRectangle(cornerRadius: 10) .foregroundColor(.gray) .frame(width: 100) ) }
内容的提问来源于stack exchange,提问作者Taimoor Arif
相关产品推荐
相关产品推荐

