iOS音频录制

作者: Mob_Developer | 来源:发表于2017-03-09 14:45 被阅读2746次

    音频会话(Audio Session)

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

    • 音频会话分类(Audio Session Category)
      AV Foundation把音频行为分成了七类。各个分类有着不同的作用,因此各个分类用在不同的功能场景。
    音频分类_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音频录制

        本文链接:https://www.haomeiwen.com/subject/apaigttx.html