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

如何在iOS上使用AVAssetWriter导出32位WAV文件?

解决32位WAV文件导出时AVAssetWriter无法添加输入的问题

问题分析

你的代码存在两个核心问题:

  • 变量名不匹配:定义了setting字典,但创建AVAssetWriterInput时误用了未定义的exportSetting
  • 音频格式不兼容:AVAssetReader输出的音频格式与AVAssetWriter期望的输入格式不匹配,导致canAdd返回false

解决方案

  1. 修正变量名错误,确保使用正确的输出设置字典
  2. 让AVAssetReader的输出格式与AVAssetWriter的输入格式保持一致,避免格式不兼容问题
  3. 补充完整的读写流程逻辑

以下是修正后的完整代码:

// 定义32位浮点WAV的输出设置
let audioSettings: [String: Any] = [
    AVFormatIDKey: kAudioFormatLinearPCM,
    AVSampleRateKey: 44100,
    AVNumberOfChannelsKey: 2,
    AVLinearPCMBitDepthKey: 32,
    AVLinearPCMIsNonInterleaved: false,
    AVLinearPCMIsFloatKey: true,
    AVLinearPCMIsBigEndianKey: false
]

do {
    // 初始化AssetReader
    let reader = try AVAssetReader(asset: composition)
    // 设置Reader输出格式与Writer一致,确保兼容性
    let readerOutput = AVAssetReaderAudioMixOutput(audioTracks: composition.tracks(withMediaType: .audio),
                                                   audioSettings: audioSettings)
    readerOutput.audioMix = mix
    
    guard reader.canAdd(readerOutput) else {
        print("无法添加Reader输出")
        return
    }
    reader.add(readerOutput)
    
    // 初始化AssetWriter
    let writer = try AVAssetWriter(outputURL: outputTempURL, fileType: .wav)
    let writerInput = AVAssetWriterInput(mediaType: .audio, outputSettings: audioSettings)
    
    guard writer.canAdd(writerInput) else {
        print("无法添加Writer输入")
        return
    }
    writer.add(writerInput)
    
    // 启动读写流程
    reader.startReading()
    writer.startWriting()
    writer.startSession(atSourceTime: .zero)
    
    // 处理音频数据回调
    writerInput.requestMediaDataWhenReady(on: DispatchQueue.global()) {
        while writerInput.isReadyForMoreMediaData {
            if let sampleBuffer = readerOutput.copyNextSampleBuffer() {
                writerInput.append(sampleBuffer)
            } else {
                writerInput.markAsFinished()
                writer.finishWriting {
                    // 导出完成后的处理
                    if writer.status == .completed {
                        print("32位WAV导出成功")
                    } else {
                        print("导出失败: \(writer.error?.localizedDescription ?? "未知错误")")
                    }
                }
                break
            }
        }
    }
} catch {
    print("初始化读写器失败: \(error.localizedDescription)")
}

关键说明

  • 统一audioSettings字典,让Reader和Writer使用相同的格式参数,确保数据流格式兼容
  • 必须检查reader.canAdd(readerOutput),避免Reader无法处理指定格式的情况
  • 补充完整的读写回调逻辑,确保音频数据被正确写入文件
  • 使用do-catch替代强制解包try!,避免崩溃并捕获错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 21:35:01