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

Swift中AVAudioPlayer加载已有录制可播放文件失败问题求助

解决iOS语音录制后后续播放报错NSOSStatusErrorDomain Code=1685348671的问题

这个错误码1685348671对应的是Core Audio的kAudioFileInvalidFileError,本质是系统认为你要播放的音频文件无效、损坏,或者找不到正确的文件路径。结合你描述的「录制后立即播放正常,后续加载旧文件失败」的场景,大概率是文件写入不完整或者路径处理错误导致的,下面给你具体的排查和解决思路:

一、先排查文件路径是否正确

你提到是从另一个ViewController更新文件名,这里很容易踩坑:

  • 不要只保存文件名,一定要保存完整的文件URL路径(比如Documents目录下的全路径)。如果只存文件名,后续加载时如果目录上下文变了(比如误拼接到tmp目录),就会找到错误的文件或者找不到文件。
  • 验证加载时的路径是否正确:可以打印你要播放的文件URL,然后用FileManager检查文件是否存在:
    let targetURL = ... // 你要播放的文件URL
    print("Target file path: \(targetURL.path)")
    print("File exists: \(FileManager.default.fileExists(atPath: targetURL.path))")
    
    如果文件不存在,那就是路径拼接错误,重新确认录制时的存储目录和加载时的目录是否一致。

二、确保录制完成后文件完全写入磁盘

录制后立即播放正常,可能是因为AVAudioRecorder还在内存中持有未完全写入的数据,直接播放时读的是内存缓存;但关闭APP或者过一段时间后,磁盘上的文件其实是不完整的,导致后续播放报错。

解决方法:

  • 必须等待AVAudioRecorder的代理回调确认录制完成,再进行文件的后续操作(比如保存路径):
    // 实现AVAudioRecorderDelegate
    func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
        if flag {
            // 确认文件完全写入后,再保存路径
            UserDefaults.standard.set(recorder.url.path, forKey: "SavedRecordingPath")
            print("Recording saved to: \(recorder.url)")
        } else {
            print("Recording failed to save properly")
        }
    }
    
    // 停止录制时要调用stop(),不要直接销毁recorder
    func stopRecording() {
        audioRecorder?.stop()
    }
    
  • 不要在调用stop()后立即去读取文件,一定要等代理回调触发,确保文件写入完成。

三、检查文件权限与完整性

  1. 权限问题:确保你的APP已经获取了麦克风权限(iOS 10+需要在Info.plist中添加NSMicrophoneUsageDescription),同时如果开启了iCloud同步,可能会导致文件还在同步中无法读取,可以暂时关闭iCloud同步测试。
  2. 文件完整性验证:把录制的文件导出到Mac,用QuickTime或者音频编辑工具打开,如果无法播放,说明录制过程中文件已经损坏,需要检查AVAudioRecorder的设置是否正确:
    // 推荐的录制设置(确保生成标准的M4A文件)
    let recordingSettings: [String: Any] = [
        AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
        AVSampleRateKey: 44100.0,
        AVNumberOfChannelsKey: 1,
        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
    ]
    

四、正确的播放代码示例

确保播放时使用正确的文件URL,而不是错误的路径:

var audioPlayer: AVAudioPlayer?

func playSavedRecording() {
    guard let savedPath = UserDefaults.standard.string(forKey: "SavedRecordingPath"),
          let audioURL = URL(fileURLWithPath: savedPath) else {
        print("Invalid recording path")
        return
    }

    do {
        audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
        audioPlayer?.play()
    } catch {
        print("Playback error: \(error)")
    }
}

按照上面的步骤排查,应该能解决你遇到的问题。如果还是不行,可以检查录制时的错误日志,看看有没有写入失败的提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:52:56