AVAudioPlayer播放MP4音频报错OSStatus 2003334207技术求助
排查AVAudioPlayer播放MP4报错OSStatus 2003334207的问题
首先,这个错误码转成十六进制是0x78CA0007,对应AVFoundation框架里的kAudioFileUnsupportedDataFormatError,核心原因就是AVAudioPlayer无法识别你MP4文件中的音频编码/容器格式。
可能的原因
- 音频编码不在AVAudioPlayer支持列表:AVAudioPlayer只支持有限的音频格式,比如AAC、MP3、WAV、AIFF、ALAC(苹果无损)等。如果你的MP4里封装的是Dolby Atmos、FLAC、或者其他小众编码,就会触发这个错误。
- MP4容器的音频流封装异常:比如音频轨道是非标准的MP4封装、带有加密、或者元数据损坏,导致AVAudioPlayer无法正确解析音频流。
解决办法
办法1:改用AVPlayer替代AVAudioPlayer
AVPlayer对容器格式的支持比AVAudioPlayer全面得多,能直接处理MP4里的各种音频轨道,代码改动也不大:
import AVFoundation var avPlayer: AVPlayer? // 初始化播放逻辑 func playMP4Audio(with url: URL) { let playerItem = AVPlayerItem(url: url) avPlayer = AVPlayer(playerItem: playerItem) avPlayer?.volume = 1.0 avPlayer?.play() // 替换原有的timer逻辑,用AVPlayer的时间监听(更可靠) if timer != nil && timer.isValid { timer.invalidate() timer = nil } timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(checkPlayTime), userInfo: nil, repeats: true) }
注意:如果需要监听播放完成、出错等状态,可以给AVPlayerItem添加KVO监听,或者使用AVPlayerViewController的代理方法。
办法2:提取MP4中的音频为AVAudioPlayer支持的格式
如果你必须用AVAudioPlayer,可以先用AVAssetExportSession把MP4里的音频导出为AAC(.m4a)格式,再进行播放:
import AVFoundation func exportAudioFromMP4(originalURL: URL, completion: @escaping (URL?) -> Void) { let asset = AVAsset(url: originalURL) guard asset.tracks(withMediaType: .audio).first != nil else { print("文件中没有音频轨道") completion(nil) return } // 临时存储导出的音频文件 let outputURL = FileManager.default.temporaryDirectory.appendingPathComponent("exported_audio_\(UUID().uuidString).m4a") guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else { print("创建导出会话失败") completion(nil) return } exportSession.outputURL = outputURL exportSession.outputFileType = .m4a exportSession.shouldOptimizeForNetworkUse = true exportSession.exportAsynchronously { DispatchQueue.main.async { switch exportSession.status { case .completed: completion(outputURL) case .failed: print("导出失败:\(exportSession.error?.localizedDescription ?? "未知错误")") completion(nil) case .cancelled: print("导出被取消") completion(nil) default: completion(nil) } } } } // 使用示例 exportAudioFromMP4(originalURL: yourMP4URL) { exportedURL in guard let url = exportedURL else { return } do { audioPlayer = try AVAudioPlayer(contentsOf: url) audioPlayer.delegate = self audioPlayer.volume = 1.0 audioPlayer.prepareToPlay() audioPlayer.play() // 原有的timer逻辑 if timer != nil && timer.isValid { timer.invalidate() timer = nil } timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(checkPlayTime), userInfo: nil, repeats: true) } catch let error as NSError { print(error.description) } }
办法3:检查并修复MP4文件的音频编码
你可以用工具(比如ffmpeg)查看MP4的音频编码信息,执行命令:
ffmpeg -i your_file.mp4
在输出的Stream #0:1(音频流)部分查看Codec字段,如果编码不在AVAudioPlayer支持列表里,就用ffmpeg重新转码为AAC格式:
ffmpeg -i your_file.mp4 -vn -c:a aac -b:a 192k converted_audio.m4a
转码后的文件就能被AVAudioPlayer正常识别了。
小优化建议
你原代码里的audioPlayer.volume = 1.0建议放在prepareToPlay()之前设置,虽然不影响功能,但逻辑上更合理。
内容的提问来源于stack exchange,提问作者Usman Nisar
相关产品推荐
相关产品推荐

