【AVFoundation】AVAudioRecorder录制音频

1,124 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

AVFoundation 是Apple iOS和OS X系统中用于处理基于时间的媒体数据的高级框架,通过开发所需的工具提供了强大的功能集,让开发者能够基于苹果平台创建当下最先进的媒体应用程序,其针对64位处理器设计,充分利用了多核硬件优势,会自动提供硬件加速操作,确保大部分设备能以最佳性能运行,是iOS开发接触音视频开发必学的框架之一

参与掘金日新计划,持续记录AVFoundation学习,Demo学习地址,这篇文章主要讲述利用AVAudioRecorder实现音频录制,其他类的相关用法可查看我的其他文章。

AVAudioRecorder

AVAudioRecorder构建于Audio Queue Services之上,是一个功能强大且代码简单易用的OC/Swift接口,我们可以在Mac/iOS设备上使用这个类录制音频(内部麦克风或外接设备均可)。

创建AVAudioRecorder

  • 需要写入本地文件的URL
  • 需要用于配置录音会话键值信息的NSDictionary
  • 创建可能失败
  • 创建成功建议调用prepareToRecord函数,与AVPlayer的prepareToPlay类似,这个函数执行底层的Audio Queue初始化的必要过程,该函数还在URL参数指定的位置创建一个文件,将录制启动时的延时降到最小
let filePath = NSTemporaryDirectory() + "momo.m4a"
let filerUrl = URL(fileURLWithPath: filePath)
let settings: [String: Any] = [AVFormatIDKey: kAudioFormatAppleIMA4,
                               AVSampleRateKey: 44100.0,
                               AVNumberOfChannelsKey: 1,
                               AVEncoderBitDepthHintKey: 16,]
recorder = try! **AVAudioRecorder**(**url**: filerUrl, **settings**: settings)

settings

音频格式
  • AVFormatIDKey定义了写入的格式。常用的有kAudioFormatLinearPCM、kAudioFormatAppleIMA4、kAudioFormatMPEG4AAC等,常用的有kAudioFormatLinearPCM会将未压缩的音频流写入到文件中,这种格式的保真度最高,不过相应文件也最大,kAudioFormatAppleIMA4、kAudioFormatMPEG4AAC等会显著缩小文件,还能保证相对较高的音频质量。
采样率
  • AVSampleRateKey用于定义采样率。采样率指对输入的模拟音频信号每一秒内的采样数,决定最终的音频文件大小以及音频质量,采样率越高质量越高文件也越大,反之亦然,对于使用什么样的采样率最好并没有一个明确的定义,应当尽量使用标准的采样率,例如8000、16000、22050、44100。
通道数
  • AVNumberOfChannelsKey用于定义音频采样的通道数,1是单声道录制,2是立体声录制,除非检测到用户使用了外接硬件录制,否则应当创建单声道录音。使用了立体声录制,可能会导致调用一些语音转文字SDK时出现重复内容。

录制、暂停等操作

  • 使用之前需注意配置了合理的音频会话
  • 需注意配置了plist文件,否则会崩溃
// 开始录制,注意返回值,并不一定成功过
recorder.record()
// 暂停录制,可以再次调用record继续录制
recorder.pause()
// 结束录制
recorder.stop()

AVAudioRecorderDelegate

// 录制成功
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
    stopHandler?(flag)
}

// 编码错误
func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder, error: Error?) {
     CQLog("编码错误")
}
    

获取录音时间

  • 录音时间返回的是一个双精度的TimeInterval,可以将其格式化使用,下面是一个保存成Int格式化使用的示例
  • currentTime不能使用KVO监听,如果需要随时间变化,可以创建定时器轮询
let time = recorder.currentTime
// 格式化录音时间
let hours: Int = Int(time/3600)
let minutes: Int = Int((time/60).truncatingRemainder(dividingBy: 60))
let seconds: Int = Int(time.truncatingRemainder(dividingBy: 60))
formattedCurrentTime = String(**format**: "%02i:%02i:%02i", hours, minutes, seconds)

获取录音音量大小

// 该方法一定要在读取之前调用
recorder.updateMeters()

// 平均,因为是单声道录制,所以询问第一个声道即可 ,范围0 - -160
averagePower = recorder.averagePower(forChannel: 0)

// 峰值,因为是单声道录制,所以询问第一个声道即可 ,范围0 - -160
peakPower = recorder.peakPower(forChannel: 0)