使用 AVAudioRecorder 录制语音

Posted

技术标签:

【中文标题】使用 AVAudioRecorder 录制语音【英文标题】:Using AVAudioRecorder to record voice 【发布时间】:2015-06-24 20:56:38 【问题描述】:

我正在尝试制作一个简单的录音机。我正在使用 Xcode-beta 7,我的代码基于这三个来源。

AVFoundation Audio Recording With Swift AVAudioRecorder Reference 查看初始化器的输入。 Recording audio in Swift 获取我应该使用的设置

我正在使用以下代码:

var recordSettings = [
        AVFormatIDKey: kAudioFormatAppleIMA4,
        AVLinearPCMIsBigEndianKey: 0,
        AVLinearPCMIsFloatKey: 0,
        AVNumberOfChannelsKey: 2,
        AVSampleRateKey: 32000
    ]

    var session = AVAudiosession.sharedInstance()

    do
        try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
        recorder = AVAudioRecorder(URL: filePath, settings: recordSettings, error: nil)
    catch
        print("Error")
    

但它说“找不到接受类型为 '(URL:NSURL?, settings:[String:AudioFormatID], error:nil)' 的参数列表的类型 'AVAudioRecorder' 的初始化程序”

我的输入不正是文档要求的吗?

【问题讨论】:

我现在也遇到了同样的问题!当我创建 recordSettings 字典时,我收到错误“AudioFormatID 不符合协议'AnyObject'”。你也有这个问题吗? 因为您传递的是 Int 而不是对象。尝试创建一个 NSNumber,而不是像我在答案中显示的那样: NSNumber(integer: kAudioFormatAppleIMA4) 【参考方案1】:

AVAudioRecorder 不再需要错误参数:

init(URL url: NSURL, settings settings: [String : AnyObject]) throws

另外,我需要解开文件路径,如上一个答案中所建议的:

func recordSound()
    let dirPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String

    let recordingName = "my_audio.wav"
    let pathArray = [dirPath, recordingName]
    let filePath = NSURL.fileURLWithPathComponents(pathArray)
    let recordSettings = [AVEncoderAudioQualityKey: AVAudioQuality.Min.rawValue,
            AVEncoderBitRateKey: 16,
            AVNumberOfChannelsKey: 2,
            AVSampleRateKey: 44100.0]
    print(filePath)

    let session = AVAudioSession.sharedInstance()
    do 
        try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
        audioRecorder = try AVAudioRecorder(URL: filePath!, settings: recordSettings as! [String : AnyObject])
     catch _ 
        print("Error")
    

    audioRecorder.delegate = self
    audioRecorder.meteringEnabled = true
    audioRecorder.prepareToRecord()
    audioRecorder.record()

【讨论】:

好的,这使我的构建成功,但我还没有测试出实际的录音。此外,我将此代码段从 viewDidLoad 移到了记录按钮的操作中。你知道为什么它在 viewDidLoad 中不起作用吗?我认为把它放在那里是有意义的,因为您希望在点击录制按钮之前加载所有内容。 将它移到viewDidLoad中是有意义的,但将最后两行留给记录按钮。 audioRecorder.delegate = self 是做什么的?因为如果我包含它,我似乎无法编译它。但是,当我在没有它的情况下运行它时,我得到一个 Thread1: EXC_BAD_ACCESS(code=1, address0x0) 录音机需要一个委托,因为它必须知道录音完成后要做什么。所以,你还需要在RecordSoundsViewController中实现协议:AVAudioRecorderDelegate,像这样:class RecordSoundsViewController: UIViewController, AVAudioRecorderDelegate 并且也实现了来自 AVAudioRecorderDelegate func audioRecorderDidFinishRecording(recorder: AVAudioRecorder, successfully flag: Bool)的方法【参考方案2】:

您的 filePath 被包装为一个选项。您应该检查是否不是 nil 并像这样打开它:

recorder = AVAudioRecorder(URL: filePath!, settings: recordSettings, error: nil)

你还需要传递一个 NSError 指针:

var error: NSError?
recorder = AVAudioRecorder(URL: filePath!, settings: recordSettings, error: &error)

之后,如果您的设置字典有错误,请尝试将所有 Tnt 转换为 NSNumber,因为 NSNumber 是 Object,而不是 Int。示例:

NSNumber(integer: kAudioFormatAppleIMA4)

【讨论】:

根据您的 NSNumber 建议,它仍然会给出类似的错误:“AudioFormatID”不可转换为“Int”。编辑:只需给它'unsignedInt'而不是'integer',它似乎工作。 AudioFormatID 是一个 UInt32。

以上是关于使用 AVAudioRecorder 录制语音的主要内容,如果未能解决你的问题,请参考以下文章

录制语音的正确 AVAudioRecorder 设置?

从 Alexa 语音服务获取 500 错误

AVAudioRecorder - 最后裁剪/修剪录音

xamarin iOS:录制时如何显示语音的音频幅度

第六十九篇OC_录制语音和播放语音功能的实现

iOS音频与视频的开发- 使用AVAudioRecorder进行录制音频