iOS录音实践

来源:互联网 发布:芜湖java招聘 编辑:程序博客网 时间:2024/05/16 11:44

在AVFoundation框架中AVAudioRecorder类专门处理录音操作,支持多种音频格式下面是常用的属性和方法:

属性说明@property(readonly, getter=isRecording) BOOL recording;是否正在录音,只读@property(readonly) NSURL *url录音文件地址,只读@property(readonly) NSDictionary *settings录音文件设置,只读@property(readonly) NSTimeInterval currentTime录音时长,只读,注意仅仅在录音状态可用@property(readonly) NSTimeInterval deviceCurrentTime输入设置的时间长度,只读,注意此属性一直可访问@property(getter=isMeteringEnabled) BOOL meteringEnabled;是否启用录音测量,如果启用录音测量可以获得录音分贝等数据信息@property(nonatomic, copy) NSArray *channelAssignments当前录音的通道对象方法说明- (instancetype)initWithURL:(NSURL *)url settings:(NSDictionary *)settings error:(NSError **)outError录音机对象初始化方法,注意其中的url必须是本地文件url,settings是录音格式、编码等设置- (BOOL)prepareToRecord准备录音,主要用于创建缓冲区,如果不手动调用,在调用record录音时也会自动调用- (BOOL)record开始录音- (BOOL)recordAtTime:(NSTimeInterval)time在指定的时间开始录音,一般用于录音暂停再恢复录音- (BOOL)recordForDuration:(NSTimeInterval) duration按指定的时长开始录音- (BOOL)recordAtTime:(NSTimeInterval)time forDuration:(NSTimeInterval) duration在指定的时间开始录音,并指定录音时长- (void)pause;暂停录音- (void)stop;停止录音- (BOOL)deleteRecording;删除录音,注意要删除录音此时录音机必须处于停止状态- (void)updateMeters;更新测量数据,注意只有meteringEnabled为YES此方法才可用- (float)peakPowerForChannel:(NSUInteger)channelNumber;指定通道的测量峰值,注意只有调用完updateMeters才有值- (float)averagePowerForChannel:(NSUInteger)channelNumber指定通道的测量平均值,注意只有调用完updateMeters才有值代理方法说明- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag完成录音- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error录音编码发生错误


AVAudioRecorder创建录音机时除了指定路径外还必须指定录音设置信息,因为录音机必须知道录音文件的格式、采样率、通道数、每个采样点的位数等信息,通常只需要几个常用设置。关于录音设置详见帮助文档中的“AV Foundation Audio Settings Constants”。

以下代码实现录音,暂停,继续,取消,停止,播放功能。

#import "ViewController.h"#import <AVFoundation/AVFoundation.h>#define kAudioFileName @"test.caf"@interface ViewController ()<AVAudioRecorderDelegate>@property (nonatomic,strong) AVAudioRecorder *audioRecorder; //音频录音机@property (nonatomic,strong) AVAudioPlayer *audioPlayer;     //音频播放器@property (nonatomic,strong) NSTimer *timer;            //录音监控@property (weak, nonatomic) IBOutlet UIProgressView *audioPower;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    [self setAudioSession];}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}/** *  设置音频会话 */-(void)setAudioSession{    AVAudioSession *audioSession=[AVAudioSession sharedInstance];    //设置为播放和录音状态,以便可以在录制完之后播放录音    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];    [audioSession setActive:YES error:nil];}/** *  录音文件设置 * *  @return 返回录音设置 */- (NSDictionary *)getAudioSetting{    NSMutableDictionary *dic = [NSMutableDictionary dictionary];    [dic setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];  //设置录音格式    [dic setObject:@(8000) forKey:AVSampleRateKey];                 //设置采样率    [dic setObject:@(1) forKey:AVNumberOfChannelsKey];              //设置通道,这里采用单声道    [dic setObject:@(8) forKey:AVLinearPCMBitDepthKey];             //每个采样点位数,分为8,16,24,32    [dic setObject:@(YES) forKey:AVLinearPCMIsFloatKey];            //是否使用浮点数采样    return dic;}/** *  录音存储路径 * *  @return 返回存储路径 */- (NSURL *)getSavePath{    NSString *url = [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask,YES) lastObject];    url = [url stringByAppendingPathComponent:kAudioFileName];    return [NSURL URLWithString:url];}- (NSTimer *)timer{    if (!_timer) {        _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(audioPowerChange) userInfo:nil repeats:YES];    }    return _timer;}- (AVAudioRecorder *)audioRecorder{    if (!_audioRecorder) {        NSError *error = nil;        _audioRecorder = [[AVAudioRecorder alloc] initWithURL:[self getSavePath] settings:[self getAudioSetting] error:&error];        _audioRecorder.delegate = self;        _audioRecorder.meteringEnabled = YES; //是否启用录音测量,如果启用录音测量可以获得录音分贝等数据信息        if (error) {            NSLog(@"创建录音机对象发生错误:%@",error.localizedDescription);            return nil;        }    }    return _audioRecorder;}- (AVAudioPlayer *)audioPlayer{    if (!_audioPlayer) {        NSError *error = nil;        _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[self getSavePath] error:&error];        if (error) {            NSLog(@"创建音频播放器对象发生错误:%@",error.localizedDescription);            return nil;        }    }    return _audioPlayer;}#pragma mark - #pragma mark - AVAudioRecorderDelegate//录音成功- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{    if (![self.audioPlayer isPlaying]) {        [self.audioPlayer play];    }}//录音失败- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error{    }#pragma mark - #pragma mark - Action- (void)audioPowerChange{    [self.audioRecorder updateMeters];  //更新测量值    float power = [self.audioRecorder averagePowerForChannel:1]; //取得第一个通道的音频,注意音频强度范围时-160到0    self.audioPower.progress = (1.0/160)*(power+160);}/** *  点击录音按钮 * *  @param sender 录音按钮 */- (IBAction)startRecord:(id)sender {        if (![self.audioRecorder isRecording]) {        [self.audioRecorder record];        self.timer.fireDate = [NSDate distantPast];    }}/** *  点击取消录音按钮 * *  @param sender 取消录音按钮 */- (IBAction)cancelRecord:(id)sender {    self.audioRecorder.delegate = nil;    if ([self.audioRecorder isRecording]) {       [self.audioRecorder stop];    }    self.audioRecorder = nil;}/** *  点击暂定按钮 * *  @param sender 暂停按钮 */- (IBAction)pause:(id)sender {    if ([self.audioRecorder isRecording]) {        [self.audioRecorder pause];        self.timer.fireDate = [NSDate distantFuture];    }}/** *  点击恢复按钮 *  恢复录音只需要再次调用record,AVAudioSession会帮助你记录上次录音位置并追加录音 * *  @param sender 恢复按钮 */- (IBAction)goon:(id)sender {    [self startRecord:nil];}/** *  点击停止按钮 * *  @param sender 停止按钮 */- (IBAction)stop:(id)sender {    if ([self.audioRecorder isRecording]) {        [self.audioRecorder stop];        self.timer = [NSDate distantFuture];    }}/** *  点击播放按钮 * *  @param sender 播放按钮 */- (IBAction)play:(id)sender {        if (![self.audioPlayer isPlaying]) {        [self.audioPlayer play];    }}


0 0