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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:02:46