首页 > 解决方案 > 如何从录制的音频中为 Swift 中的 API 获取 m4a 文件?

问题描述

目标:我想录制 10 秒的音频,获取音频录制文件并在 post 请求中发送。

我做了什么:我可以使用以下代码录制 10 秒的音频:

var recordingSession: AVAudioSession!
var audioRecorder: AVAudioRecorder!

func setupAV() {
    recordingSession = AVAudioSession.sharedInstance()

    do {
        try recordingSession.setCategory(.playAndRecord, mode: .default)
        try recordingSession.setActive(true)
        recordingSession.requestRecordPermission() { [unowned self] allowed in
            DispatchQueue.main.async {
                if allowed {
                    self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.recordTapped)))
                } else {
                    // failed to record!
                }
            }
        }
    } catch {
        // failed to record!
    }
}

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

@objc func recordTapped() {
    let audioFilename = getDocumentsDirectory().appendingPathComponent("recording.m4a")

    let settings = [
        AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
        AVSampleRateKey: 12000,
        AVNumberOfChannelsKey: 1,
        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
    ]

    do {
        audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
        audioRecorder.delegate = self
        audioRecorder.record(forDuration: 10)
        print("RECORDING")
    } catch {
        print("audio failed to record")
    }

}

func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
    print("DONE")
}

我需要做的:我需要将此录音作为 m4a 文件并在发布请求中发送。我怎样才能做到这一点?如果您需要任何其他信息,请告诉我!谢谢!

标签: swiftpostavfoundation

解决方案


您需要使用 导出录音AVAssetExportSession。这是一个很好的方法,可以为你做到这一点:

func export(fileType: AVFileType = .m4a, completion: @escaping (() -> Void)) {
    let asset = AVAsset(url: recordingFileURL))
    guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else { return }
    exportSession.outputFileType = fileType
    exportSession.metadata = asset.metadata
    exportSession.shouldOptimizeForNetworkUse = true
    exportSession.outputURL = exportOutputURL
    exportSession.exportAsynchronously {
        print("Export finished.")
        completion()
    }
}

exportOutputURL您在文档目录中创建的任何 URL 都可以在哪里。例如,我们可以将其定义为计算属性:

var exportOutputURL: URL? {
    let pathURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    return pathURL?.appendingPathComponent("my_exported_recording")
}

您现在将在您的exportOutputURL.

根据您的 API 期望参数是什么,您可以像这样转换为数据:

do {
    let data = try Data(contentsOf: exportOutputURL)
} catch { ... }

和一个base64字符串:

let base64String = data.base64EncodedString()

推荐阅读