前言
在AV Foundation
中使用AVAudioRecorder
类添加音频录制功能和使用AVAudioPlayer
一样简单, 都是在Audio Queue Server
上层构建的.同时支持macOS
和iOS
平台.可以从内置麦克风录制音频,也可以支持数字音频接口或USB外接麦克风录制.
主要内容如下:
如何创建AVAudioRecorder
1\. 音频格式
2\. 采样率
3\. 通道数
创建Demo
1\. 配置音频会话
2\. 实现录音功能
3\. 使用Audio Metering实现声波视觉显示
创建AVAudioRecorder
之前先了解一下它的方法和成员变量
@property (readonly, getter=isRecording) BOOL recording;//是否正在录音
@property (readonly) NSDictionary<NSString *, id> *settings;//录音配置:采样率、音频格式、通道数...
@property (readonly) NSURL *url;//录音文件存放URL
@property (readonly) NSTimeInterval currentTime;//录音时长
@property (getter=isMeteringEnabled) BOOL meteringEnabled;//是否监控声波
AVAudioRecorder
的实例方法:
- (BOOL)prepareToRecord;//为录音准备缓冲区
- (BOOL)record;//录音开始,暂停后调用会恢复录音
- (BOOL)recordAtTime:(NSTimeInterval)time;//在指定时间后开始录音
- (BOOL)recordForDuration:(NSTimeInterval) duration;//按指定时长录音
- (BOOL)recordAtTime:(NSTimeInterval)time
forDuration:(NSTimeInterval)duration;//上面2个的合体
- (void)pause; //暂停录音
- (void)stop; //停止录音
- (BOOL)deleteRecording;//删除录音,必须先停止录音再删除
AVAudioRecorder
的代理方法:
//录音完成后调用
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder
successfully:(BOOL)flag;
//录音编码发生错误时调用
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder
error:(NSError *)error;
如何创建AVAudioRecorder
创建AVAudioRecorder
对象所需要的参数如下:
- 音频流录制时写入到本地的路径URL
settings
录音配置:采样率、音频格式、通道数…等键值参数字典- 发生错误的
NSError
指针
如下代码:
/**
创建录音器
*/
- (void)createRecorder {
NSString *directory = NSTemporaryDirectory();
NSString *filePath = [directory stringByAppendingPathComponent:@"voice1.m4a"];
NSURL *url = [NSURL fileURLWithPath:filePath];
NSDictionary *setting = @{AVFormatIDKey : @(kAudioFormatMPEG4AAC),
AVSampleRateKey: @22050.0f,
AVNumberOfChannelsKey: @1};
NSError *error;
self.recorder = [[AVAudioRecorder alloc] initWithURL:url
settings:setting
error:&error];
if (self.recorder) {
[self.recorder prepareToRecord];
} else {
NSLog(@"Recorder Create Error: %@", [error localizedDescription]);
}
}
这里的建议调用[self.recorder prepareToRecord]
方法对录音实例进行预设就像上一章创建AVAudioPlayer
类似.都是为了执行底层Audio Queue
初始化的必要过程.这个prepareToRecord
方法还在给定的URL参数指定的位置创建一个文件,这样就减少了录制启动时的延时
音频格式
AVFormatIDKey
key指定录制格式,这里的除了kAudioFormatMPEG4AAC
格式还有下面这些:
CF_ENUM(AudioFormatID)
{
kAudioFormatLinearPCM = 'lpcm',
kAudioFormatAC3 = 'ac-3',
kAudioFormat60958AC3 = 'cac3',
kAudioFormatAppleIMA4 = 'ima4',
kAudioFormatMPEG4AAC = 'aac ',
kAudioFormatMPEG4CELP = 'celp',
kAudioFormatMPEG4HVXC = 'hvxc',
kAudioFormatMPEG4TwinVQ = 'twvq',
kAudioFormatMACE3 = 'MAC3',
kAudioFormatMACE6 = 'MAC6',
kAudioFormatULaw = 'ulaw',
kAudioFormatALaw = 'alaw',
kAudioFormatQDesign = 'QDMC',
kAudioFormatQDesign2 = 'QDM2',
kAudioFormatQUALCOMM = 'Qclp',
kAudioFormatMPEGLayer1 = '.mp1',
kAudioFormatMPEGLayer2 = '.mp2',
kAudioFormatMPEGLayer3 = '.mp3',
kAudioFormatTimeCode = 'time',
kAudioFormatMIDIStream = 'midi',
kAudioFormatParameterValueStream = 'apvs',
kAudioFormatAppleLossless = 'alac',
kAudioFormatMPEG4AAC_HE = 'aach',
kAudioFormatMPEG4AAC_LD = 'aacl',
kAudioFormatMPEG4AAC_ELD = 'aace',
kAudioFormatMPEG4AAC_ELD_SBR = 'aacf',
kAudioFormatMPEG4AAC_ELD_V2 = 'aacg',
kAudioFormatMPEG4AAC_HE_V2 = 'aacp',
kAudioFormatMPEG4AAC_Spatial = 'aacs',
kAudioFormatAMR = 'samr',
kAudioFormatAMR_WB = 'sawb',
kAudioFormatAudible = 'AUDB',
kAudioFormatiLBC = 'ilbc',
kAudioFormatDVIIntelIMA = 0x6D730011,
kAudioFormatMicrosoftGSM = 0x6D730031,
kAudioFormatAES3 = 'aes3',
kAudioFormatEnhancedAC3 = 'ec-3'
};
这里的kAudioFormatLinearPCM
会将为压缩的音频流写入到文件中,这就是原始数据,保真度最高,当然文件也最大, 选择ACCkAudioFormatMPEG4AAC
或者AppleIMA4kAudioFormatAppleLossless
等格式会显著缩小文件,还能保证音频质量.
注意:
指定的音频格式一定要和文件写入的URL文件类型保持一致。如果录制xxx.wav文件格式 是 Waveform Audio File Format(WAVE)的格式要求,即 低字节序、 LinePCM。 如果AVFormatIDKey
指定的值不是kAudioFormatLinearPCM
则会发生错误。NSError 会返回如下错误
The operation couldn’t be completed. (OSState error 1718449215.)
采样率
上边的代码里AVSampleRateKey
用于定义录音器的采样率. 采样率定义了对输入的模拟音频信号每一秒内的采样数. 如果使用低采样率 比如8kHz,会导致粗粒度、AM广播类型的录制效果, 不过文件会比较小; 使用44.1kHz的采样率(CD质量的采样率)会得到非常高质量的内容, 不过文件比较大. 至于使用什么样的采样率没有明确的定义. 不过开发者应该尽量使用标准的采样率,比如: 8000Hz、16 000Hz(16kHz)、22050Hz(22.05kHz)或 44100Hz(44.1kHz)、当然还有48000Hz和96000Hz ,(kHz代表千赫),超过48000或96000的采样对人耳已经没有意义.最终是我们的耳朵在进行判断.(上一章说了 人耳所能听到的声音,最低的频率是从20Hz起一直到最高频率20kHz,录音最好采用 x 2 倍的频率)
通道数
AVNumberOfChannelsKey
用于定义记录音频内容的通道数。指定默认值1 意味着使用单声道录制、设置2意味着使用立体声录制。除非使用外部硬件进行录制,否则同窗应该创建单声道录音。 这里的通道数是指 录制设备的输入数量 可以理解为 麦克风 内置 或者外接麦克风录制比如 插入Apple耳机 里面的麦克风。
以上是全面
AVAudioRecorder
的部分概念,AVAudioRecorder
支持无限时长录制,还可以设置从未来某一时间点开始录制或指定时长录制
网络流媒体处理
AVAudioPlayer
音频播放器只能播放本地文件,并且是一次性加载所有的音频数据,但我们有时候需要边下载边听怎么办?
AVAudioPlayer
是不支持这种网络流媒体形式的音频播放,要播放这种网络流媒体,我们需要使用AudioToolbox
框架的音频队列服务Audio Queue Services
。
音频队列服务分为3个部分:
- 3个缓冲器
- 1个缓冲队列
- 1个回调</