iOS音频录制

音频会话(Audio Session)

音频会话是应用程序和操作系统之间的中间人。应用程序不需要具体知道怎样和音频硬件交互的细节,只需要把所需的音频行为委托给音频会话管理即可。

  • 音频会话分类(Audio Session Category)
    AV Foundation把音频行为分成了七类。各个分类有着不同的作用,因此各个分类用在不同的功能场景。
iOS音频录制_第1张图片
音频分类_1.jpg

以上七个分类能够满足大部分的需求,但是开发者也可以通过使用选项(options)和模式(modes)自定义,增强和修改原有的分类功能。

配置音频会话

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *error = nil;
// 音频会话分类(catehory)和模式(mode)一起决定了应用要使用音频的方式,也可以说是定制音频的行为。通常在激活音频会话之前设置分类和模式。也可以在激活音频会话时设置分类和模式,但是这样会立即路由(route)。
 // 如果分类设置成功,但会也是,反则返回no
if([audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error]){
      // 配置成功
 }else{
      // 配置失败
  }

音频录制

AV Foundation提供了AVAudioRecorder类,用于从内置麦克风或者外置音频设备录制音频。

创建AVAudioRecorder需要提供以下数据信息:

  • 录制的音频要存放的位置,也就是本地URL。
  • 音频格式、采样率、声道等配置信息,这些信息使用字典保存。
  • NSError指针,用于捕捉初始化时可能出现的错误。

创建和准备AudioRecorder对象:

+(instancetype)audioRecordertoPrepare:(NSString *)audioName error:(NSError *)error{
    NSString *audioDirectory =  ;
    if(audioDirectory){
        NSString *audioPath = ;
        NSDictionary *audioSettings = @{AVFormatIDKey:@(kAudioFormatMPEG4AAC),
                                       AVSampleRateKey:@22050.0f,
                                       AVNumberOfChannelsKey:@1
                                       };
        AVAudioRecorder *audioRecorder = [[AVAudioRecorder alloc] initWithURL:audioURL settings:audioSettings error:&error];
        // prepareToRecord方法根据URL创建文件,并且执行底层Audio Queue初始化的必要过程,将录制启动时的延迟降到最低。
        if([audioRecorder prepareToRecord]){
            return audioRecorder;
        }
    }
    return nil;
}
  1. 音频格式
    kAudioFormatMPEG4AAC压缩格式能在显著减小文件的同时,保证音频的质量。同时Android也支持aac音频格式。
  2. 采样率
    采样率越高,文件越大,质量越好,反之,文件小,质量相对差一些,但是低于普通的音频,人耳并不能明显的分辨出好坏。最终选取哪一种采样率,由我们的耳朵来判断。建议使用标准的采样率,8000、16000、22050、44100。
  3. 通道数
    AVNumberOfChannelsKey用于指定记录音频的通道数。1为单声道,2为立体声。除非使用外部硬件进行录制,否则通常使用单声道录制。
  4. 其他配置
    在AV Foundation Audio Session Settings Constants中查看完整的键列表。

音频录制控制

  • 启动、恢复音频录制

[AVAudioRecorder record];
```

  • 暂停音频录制
    [AVAudioRecorder pause];
    
  • 结束录制
[AVAudioRecorder stop];
  • 删除录制的音频文件,删除之前必须先停止录制
    [self.audioRecorder deleteRecording];

录制和删除录制文件方法返回布尔值,如果操作成功,返回YES,操作失败返回NO,所以在实际的开发中,还应该考虑操作失败状态的处理,给用户以友好的提示。

同时AVAudioRecorder也提供了AVAdudioRecorderDelegate协议,用于接收音频录制完成、音频录制过程发生错误的事件。虽然也有定义音频录制过程被中断的方法,但是已经弃用。所以要监听诸如系统来电,闹钟响铃,Facetime……导致的音频录制终端事件,使用AVAudioSession通知代替。

AVAudioDelegate定义的接口:

@optional 

/* 录制完成或者调用stop时,回调用这个方法。但是如果是系统中断录音,则不会调用这个方法。 */
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag;

/* 在录制时出现错误时调用这个代理方法 */
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError * __nullable)error;

#if TARGET_OS_IPHONE

/* AVAudioRecorder INTERRUPTION NOTIFICATIONS 已废弃 - 使用 AVAudioSession 替代. */

/* audioRecorderBeginInterruption: is called when the audio session has been interrupted while the recorder was recording. The recorded file will be closed. */
- (void)audioRecorderBeginInterruption:(AVAudioRecorder *)recorder NS_DEPRECATED_IOS(2_2, 8_0);

/* audioRecorderEndInterruption:withOptions: is called when the audio session interruption has ended and this recorder had been interrupted while recording. */
/* Currently the only flag is AVAudioSessionInterruptionFlags_ShouldResume. */
- (void)audioRecorderEndInterruption:(AVAudioRecorder *)recorder withOptions:(NSUInteger)flags NS_DEPRECATED_IOS(6_0, 8_0);

- (void)audioRecorderEndInterruption:(AVAudioRecorder *)recorder withFlags:(NSUInteger)flags NS_DEPRECATED_IOS(4_0, 6_0);

/* audioRecorderEndInterruption: is called when the preferred method, audioRecorderEndInterruption:withFlags:, is not implemented. */
- (void)audioRecorderEndInterruption:(AVAudioRecorder *)recorder NS_DEPRECATED_IOS(2_2, 6_0);

AVAudioSession通知

/** 注册音频录制中断通知 */
 NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
                    [notificationCenter addObserver:self selector:@selector(handleNotification:) name:AVAudioSessionInterruptionNotification object:nil];

// 接收录制中断事件通知,并处理相关事件
-(void)handleNotification:(NSNotification *)notification{
    NSArray *allKeys = notification.userInfo.allKeys;
    // 判断事件类型
    if([allKeys containsObject:AVAudioSessionInterruptionTypeKey]){
        AVAudioSessionInterruptionType audioInterruptionType = [[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
        switch (audioInterruptionType) {
            case AVAudioSessionInterruptionTypeBegan:
                self.statusLabel.text = @"录音被打断…… 开始";
                break;
            case AVAudioSessionInterruptionTypeEnded:
                self.statusLabel.text = @"录音被打断…… 结束";
                break;
        }
    }
    // 判断中断的音频录制是否可恢复录制
    if([allKeys containsObject:AVAudioSessionInterruptionOptionKey]){
        AVAudioSessionInterruptionOptions shouldResume = [[notification.userInfo valueForKey:AVAudioSessionInterruptionOptionKey] integerValue];
        if(shouldResume){
            self.statusLabel.text = @"录音被打断…… 结束 可以恢复录音了";
        }
    }
}

你可能感兴趣的:(iOS音频录制)