iOS 录音的常用设置 Objective-C

作者: Zhang_yD | 来源:发表于2017-05-27 14:30 被阅读784次

    本章涉及关于录音的以下几个要点
    · 构建录音环境
    · 录音

    录音介绍

    在iOS中录音的方法有很多
    这里采用了AVFoundation框架中的AVAudioRecorder

    构建录音环境

    构建录音环境其实就是对录音进行初始化。
    录音初始化包括:
    · 判断设备录音权限
    · 创建AVAudioRecorder对象
    · 指定文件路径
    · 设置录音参数、属性、代理。
    权限判断

    - (BOOL)checkPermission {
        AVAudioSessionRecordPermission permission = [[AVAudioSession sharedInstance] recordPermission];
        return permission == AVAudioSessionRecordPermissionGranted;
    }
    

    AVAudioSessionRecordPermission枚举有三个参数 分别是未验证、未通过和通过。
    未验证的时候需要提示用户点击确认允许软件访问麦克风。

    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
        if (granted) {
            // 通过验证
        } else {
            // 未通过验证
        }
    }];
    

    在info.plist添加下面的代码,否则在iOS9.0以后的设备中无法录音。

    // SourceCode
    <key>NSMicrophoneUsageDescription</key>
    <string>随意填写(例:访问麦克风权限)</string>
    // PropertyList
    Key:Privacy - Microphone Usage Description
    Value:随意填写(例:访问麦克风权限)
    

    配置录音:

    - (BOOL)configRecorder {
        // ...其他设置
        NSURL *fileUrl = [NSURL fileURLWithPath:[self filePathWithName:[self newRecorderName]]];
        NSError *error = nil;
        NSDictionary *setting = [self recordSetting];
        _recorder = [[AVAudioRecorder alloc] initWithURL:fileUrl settings:setting error:&error];
        if (error) // 录音文件创建失败处理
        _recorder.delegate = self
        _recorder.meteringEnabled = YES;
        // ...其他设置
    }
    
    // 录音参数设置
    - (NSDictionary *)recordSetting {
        NSMutableDictionary *recSetting = [[NSMutableDictionary alloc] init];
        // General Audio Format Settings
        recSetting[AVFormatIDKey] = @(kAudioFormatLinearPCM);
        recSetting[AVSampleRateKey] = @44100;
        recSetting[AVNumberOfChannelsKey] = @2;
        // Linear PCM Format Settings
        recSetting[AVLinearPCMBitDepthKey] = @24;
        recSetting[AVLinearPCMIsBigEndianKey] = @YES;
        recSetting[AVLinearPCMIsFloatKey] = @YES;
        // Encoder Settings
        recSetting[AVEncoderAudioQualityKey] = @(AVAudioQualityMedium);
        recSetting[AVEncoderBitRateKey] = @128000;
        return [recSetting copy];
    }
    
    // 录音文件的名称使用时间戳+caf后缀
    - (NSString *)newRecorderName {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyyMMddhhmmss";
        return [[formatter stringFromDate:[NSDate date]] stringByAppendingPathExtension:@"caf"];
    }
    // Document目录
    - (NSString *)filePathWithName:(NSString *)fileName {
        NSString *urlStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        return [urlStr stringByAppendingPathComponent:fileName];
    }
    
    • 使用prepareRecord方法来确保录音文件和参数被正确配置,如果有问题会返回NO。通常出现NO的原因是参数部分出现问题,可能少了某个必要的参数。

    录音准备工作结束后就可以开始录音过程了
    使用record方法开始录音,pause方法暂停录音,stop结束录音。
    在暂停后继续录音直接调用recordaudioSession会帮助记录暂停前的数据。

    如果要获取录音时候的一些参数,需要设置meteringEnabled参数为YES。
    启动一个计时器NSTimer,并在每次轮询的时候更新录音参数。

    - (void)handleRecorderData {
        [_recorder updateMeters];
        float peak0 = ([_recorder peakPowerForChannel:0] + 160.0) * (1.0 / 160.0);
        float peak1 = ([_recorder peakPowerForChannel:1] + 160.0) * (1.0 / 160.0);
        float ave0 = ([_recorder averagePowerForChannel:0] + 160.0) * (1.0 / 160.0);
        float ave1 = ([_recorder averagePowerForChannel:1] + 160.0) * (1.0 / 160.0);
    }
    

    peakPowerForChannel:方法返回峰值
    averagePowerForChannel:返回平均值
    两个值的范围都是-160~0.

    录音结束后的处理

    AVAudioRecorderDelegate代理方法可以进行录音完成后的处理

    - (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag {
        if (flag) {
            // 录音正常结束
        } else {
            // 未正常结束
            if ([_recorder deleteRecording]) {
                // 录音文件删除成功
            } else {
                // 录音文件删除失败
            }
        }
    }
    

    在调用这个代理的时候,录音已经结束了,所以无法从currentTime中获取到当前录音的时长。
    想要获得总时长,可以用AVAudioPlayer加载,我的做法是在轮询时候进行取值,并作为成员变量记录。
    换句话说,就是利用在播放期间访问recorder.currentTime并及时更新和记录。

    录音结束后一些常用的信息:
    录音文件地址:recorder.url.path
    (笔者之前犯了一个常识性的错误,就是使用recorder.url.absoluteString获取路径,并用NSFileManager通过这个路径获得文件属性以求得文件大小,结果一直提示no such file,后来对比路径的时候发现absoluteString是带有url协议头的,所以提示大家一定要用url.path。)
    录音文件大小[[NSFileManager defaultManager] attributesOfItemAtPath:recorder.url.path error:nil][NSFileSize];
    有兴趣的同学可以打印一下attributesOfItemAtPath:error:方法返回的字典。

    至此整个录音过程结束。


    附录1 录音参数设置
    官方文档:AV Foundation Audio Settings Constants

    AVNumberOfChannelsKey:声道数 1、2
    AVSampleRateKey:采样率 单位是Hz 常见值 44100 48000 96000 192000
    AVLinearPCMBitDepthKey:比特率  8 16 32
    AVEncoderAudioQualityKey 声音质量 需要的参数是一个枚举:
        AVAudioQualityMin    最小的质量
        AVAudioQualityLow    比较低的质量
        AVAudioQualityMedium 中间的质量
        AVAudioQualityHigh   高的质量
        AVAudioQualityMax    最好的质量
    AVEncoderBitRateKey:音频的编码比特率 BPS传输速率 一般为128000bps
    

    附录2 借鉴文章来源
    iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
    关于iPhone音频的那些事
    iOS之录音

    相关文章

      网友评论

        本文标题:iOS 录音的常用设置 Objective-C

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