简体   繁体   English

如何使用Swift在iOS中将音频格式从mp3转换为wav?

[英]How do I convert audio format from mp3 to wav in iOS using Swift?

I am using cmusphinx in iOS using Swift, and cmusphinx uses audio files in wav format, while the files I need to use are in mp3 format. 我在使用Swift的iOS中使用cmusphinx,而cmusphinx使用wav格式的音频文件,而我需要使用的文件为mp3格式。

How do I convert audio files of mp3 format to wav format in iOS using Swift? 如何在iOS中使用Swift将mp3格式的音频文件转换为wav格式?

So far I have the following code using AVAssetExportSession from the Apple AVFoundation framework, but I keep getting an error saying I used an invalid output file type, no matter what I set the outputFileType property of the AVAssetExportSession object. 到目前为止,我已经从Apple AVFoundation框架使用AVAssetExportSession使用了以下代码,但是无论设置了AVAssetExportSession对象的outputFileType属性如何,我总是收到一条错误消息,指出我使用了无效的输出文件类型。

I am open to using other frameworks other than from Apple. 我愿意使用Apple以外的其他框架。

The error occurs where I mark it with a comment that says "error here", where the AVAssetExportSession.outputFileType instance property is set. 该错误发生在我用注释标记为“此处错误”的地方,其中设置了AVAssetExportSession.outputFileType实例属性。

override func viewDidLoad() {
    super.viewDidLoad()

    let assetURL: URL = Bundle.main.url(forResource: "audio16000", withExtension: "mp3")!

    let asset = AVAsset(url: assetURL)

    let presets: [String] = AVAssetExportSession.allExportPresets()

    for preset in presets {
        print(preset)
    }

    let localDocumentsURL: URL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

    let outputURL: URL = localDocumentsURL.appendingPathComponent("audio16000").appendingPathExtension("wav")

    if FileManager.default.fileExists(atPath: outputURL.path) {

        do {

            try FileManager.default.removeItem(at: outputURL)

        } catch {

            print(error)

        }

    }

    let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHEVC1920x1080)

    exporter?.outputURL = outputURL
    exporter?.outputFileType = AVFileType.wav // error here

    exporter?.exportAsynchronously {

        print("exporter status =", exporter?.status as Any)

        switch exporter!.status {
        case .unknown:
            print("status unknown")
        case .waiting:
            print("status waiting")
        case .exporting:
            print("status exporting")
        case .completed:
            print("status completed")
        case .failed:
            print("status failed")
        case .cancelled:
            print("status cancelled")
        @unknown default:
            print("@unknown default:")
        }

    }

}

Here's what the debug window says: 这是调试窗口的内容:

2019-09-17 11:42:14.766703-0500 TrialAVAssetExportSession[5620:2016827] [Accessibility] ****************** Loading GAX Client Bundle ****************
AVAssetExportPreset1920x1080
AVAssetExportPresetLowQuality
AVAssetExportPresetAppleM4A
AVAssetExportPresetHEVCHighestQuality
AVAssetExportPreset640x480
AVAssetExportPreset3840x2160
AVAssetExportPresetHEVC3840x2160
AVAssetExportPresetHighestQuality
AVAssetExportPresetMediumQuality
AVAssetExportPreset1280x720
AVAssetExportPreset960x540
AVAssetExportPresetHEVC1920x1080
2019-09-17 11:42:25.574394-0500 TrialAVAssetExportSession[5620:2016827] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVAssetExportSession setOutputFileType:] Invalid output file type'
*** First throw call stack:
(0x233d4a98c 0x232f239f8 0x239d527f4 0x1004d2f58 0x1004d40f0 0x2601fe224 0x2601fe628 0x2607dce64 0x2607dd40c 0x253f82620 0x2607edce8 0x2607a0908 0x2607a5fe0 0x2600692a4 0x26007183c 0x260068f28 0x260069818 0x260067b64 0x26006782c 0x26006c36c 0x26006d150 0x26006c224 0x260070f24 0x2607a45e8 0x2603a0e04 0x2366c69fc 0x2366d040c 0x2366cfc14 0x100584c78 0x100588840 0x236701040 0x236700cdc 0x236701294 0x233cdc728 0x233cdc6a8 0x233cdbf90 0x233cd6ecc 0x233cd67c0 0x235ed779c 0x2607a7c38 0x1004d5594 0x23379a8e0)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

I've tried all the presets I received from the AVAssetExportSession.exportPresets(compatibleWith:) method. 我已经尝试了从AVAssetExportSession.exportPresets(compatibleWith :)方法收到的所有预设。 I receive the same exact array of strings when I use the AVAssetExportSession.allExportPresets(). 当我使用AVAssetExportSession.allExportPresets()时,会收到相同的字符串数组。

WAV and contain PCM, look at Core Audio, specifically: WAV并包含PCM,请查看Core Audio,特别是:

  1. Audio File Services (to read the MP3 format and write AIFF or WAV) 音频文件服务(读取MP3格式并写入AIFF或WAV)
  2. Audio File Conversion Services (to convert the MP3 data to PCM, and/or to encode from PCM to some other codec if you were to write a file).Note that a given converter cannot convert between two encoded formats. 音频文件转换服务(将MP3数据转换为PCM,和/或将PCM编码为其他编解码器,如果要编写文件的话)。请注意,给定的转换器无法在两种编码格式之间进行转换。 you can do MP3-to-PCM or PCM-to-AAC, but to do MP3-to-AAC, you'd need two converters. 您可以执行MP3-to-PCM或PCM-to-AAC,但是要执行MP3-to-AAC,则需要两个转换器。
  3. Extended Audio File Services, which combine both of the above. 扩展的音频文件服务,结合了以上两者。

Also, be sure to understand the difference between codecs and file formats, and what codec/format combinations are legal. 另外,请务必了解编解码器和文件格式之间的区别,以及哪些编解码器/格式组合是合法的。 I was surprised the first time I found out that PCM must be little-endian in a WAV, big-endian in an AIFF. 第一次发现PCM在WAV中必须是小端,在AIFF中是大端,这让我感到惊讶。

Look at the nice example here taken from AudioKit 这里取自AudioKit的漂亮示例

AudioKit库包括从MP3到WAV的转换器,您可以在此处检查其所有可用的输入/输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM