arrays - 无效的输出文件类型

标签 arrays swift avfoundation wav avaudiorecorder

我试图从下面的函数输出一个 wav 文件,但是,在运行时,我收到错误“无效的输出文件类型”。我对为什么 AVFileType.wav 不起作用感到困惑,我测试了 AVFileType.m4a 并且由于某种原因它起作用了。干杯!

func createSound(soundFiles: [String], outputFile: String) {
    var startTime: CMTime = kCMTimeZero
    let composition: AVMutableComposition = AVMutableComposition()
    let compositionAudioTrack: AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)!

    for fileName in soundFiles {

        let sound: String = fileName
        let url: URL = URL(fileURLWithPath: sound)
        let avAsset: AVURLAsset = AVURLAsset(url: url)
        let timeRange: CMTimeRange = CMTimeRangeMake(kCMTimeZero, avAsset.duration)
        let audioTrack: AVAssetTrack = avAsset.tracks(withMediaType: AVMediaType.audio)[0]

        try! compositionAudioTrack.insertTimeRange(timeRange, of: audioTrack, at: startTime)
        startTime = CMTimeAdd(startTime, timeRange.duration)
    }

    let exportPath: String = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].path+"/"+outputFile+".wav"

    let export: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A)!

    export.outputURL = URL(fileURLWithPath: exportPath)
    export.outputFileType = AVFileType.wav

    export.exportAsynchronously {
        if export.status == AVAssetExportSessionStatus.completed {
            NSLog("All done");
            print(export.outputURL)
        }
    }

}

最佳答案

预设 AVAssetExportPresetAppleM4A 用于创建 m4a 文件,而不是 wav 文件。对于 wav,尝试 passthrough 预设:AVAssetExportPresetPassthrough,并删除之前运行遗留下来的文件:

let export: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough)!

export.outputURL = URL(fileURLWithPath: exportPath)
export.outputFileType = .wav

try? FileManager.default.removeItem(at: export.outputURL!)    // otherwise export can fail :(

export.exportAsynchronously {
    // etc
}

注意:使用 AVAssetExportPresetPassthrough,您的输入音频文件可能也需要是 wavs,甚至可能具有相同的格式。如果这对您不利,请尝试使用 AVAssetWriterAVAudioFileExtAudioFile API 之一。

附注如果您想知道哪些 AVAssetExportSession 预设、AVAsset/AVAssetCompositionAVFileType 组合受支持,您可以使用 determineCompatibility 功能:

AVAssetExportSession.determineCompatibility(ofExportPreset: AVAssetExportPresetPassthrough, with: composition, outputFileType: .wav) { ok in
    print("COMPUTER SAYS \(ok)")
}

虽然它基本上是一个试运行导出,减去 file-url-already-exists 检查和偶尔有用的 Error 变成了一个无用的 bool 值,所以我想它不会增加太多值(value)完全没有。

关于arrays - 无效的输出文件类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50216074/

相关文章:

ios - 从后台打开应用程序时不调用 ViewDidAppear

ios - AudioSessionGetProperty已过时,如何知道设备已静音

objective-c - AVMutableAudioMix - 无法淡出

javascript - 修改字符串数组,使其用作定位中的 ID

php - 从数组中获取 3 个最低值,PHP

Python bytearray() 索引分配

swift - 使用 swift4 在 xcode 中对单个项目使用不同的 GoogleService-Info.plist

swift - 为某个关联类型实现 PAT

javascript - 为什么 [[GetPrototypeOf]] 是 Javascript 代理的不变量?

ios - 在录制视频时将动态文本渲染到 CVPixelBufferRef 上