录音
这里实现开始录音,暂停,继续以及停止录音。
创建文件目录
iOS沙盒内胡要有三个目录:Documents目录,tmp目录以及Library目录,其中Documents目录用来存放用户的应用程序数据,需要定期备份的数据要放在这里,和plist文件存储一样,我们要找到存放文件的路径,然后在该路径下放一个我们的文件,因此要自定义一个带后缀的文件名,将获得的路径和文件名拼在一起记得到我们的文件的绝对路径:
// 文件名#define fileName_caf @"demoRecord.caf"// 录音文件绝对路径@property (nonatomic, copy) NSString *filepathCaf;// 获取沙盒Document文件路径NSString *sandBoxPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];// 拼接录音文件绝对路径_filepathCaf = [sandBoxPath stringByAppendingPathComponent:fileName_caf];创建音频会话
// 创建音频会话AVAudioSession *audioSession=[AVAudioSession sharedInstance];// 设置录音类别(这里选用录音后可回放录音类型)[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];[audioSession setActive:YES error:nil];录音设置
// 录音设置-(NSDictionary *)getAudioSetting{// LinearPCM 是iOS的一种无损编码格式,但是体积较为庞大// 录音设置信息字典NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];// 录音格式[recordSettings setValue :@(kAudioFormatLinearPCM) forKey: AVFormatIDKey];// 采样率[recordSettings setValue :@11025.0 forKey: AVSampleRateKey];// 通道数(双通道)[recordSettings setValue :@2 forKey: AVNumberOfChannelsKey];// 每个采样点位数(有8、16、24、32)[recordSettings setValue :@16 forKey: AVLinearPCMBitDepthKey];// 采用浮点采样[recordSettings setValue:@YES forKey:AVLinearPCMIsFloatKey];// 音频质量[recordSettings setValue:@(AVAudioQualityMedium) forKey:AVEncoderAudioQualityKey];// 其他可选的设置// ... ...return recordSettings;}创建录音机对象
// 懒加载录音机对象get方法- (AVAudioRecorder *)audioRecorder {if (!_audioRecorder) {// 保存录音文件的路径urlNSURL *url = [NSURL URLWithString:_filepathCaf];// 创建录音格式设置settingNSDictionary *setting = [self getAudioSetting];// errorNSError *error=nil;_audioRecorder = [[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];_audioRecorder.delegate = self;_audioRecorder.meteringEnabled = YES;// 监控声波if (error) {NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription);return nil;}}return _audioRecorder;}录音控制方法
// 开始录音或者继续录音- (IBAction)startOrResumeRecord {// 注意调用audiorecorder的get方法if (![self.audioRecorder isRecording]) {// 如果该路径下的音频文件录制过则删除[self deleteRecord];// 开始录音,会取得用户使用麦克风的同意[_audioRecorder record];}}// 录音暂停- (IBAction)pauseRecord {if (_audioRecorder) {[_audioRecorder pause];}}// 结束录音- (IBAction)stopRecord {[_audioRecorder stop];}录音播放
// audioPlayer懒加载getter方法- (AVAudioPlayer *)audioPlayer {_audioRecorder = NULL; // 每次都创建新的播放器,删除旧的// 资源路径NSURL *url = [NSURL fileURLWithPath:_filepathCaf];// 初始化播放器,注意这里的Url参数只能为本地文件路径,不支持HTTP UrlNSError *error = nil;_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];//设置播放器属性_audioPlayer.numberOfLoops = 0;// 不循环_audioPlayer.delegate = self;_audioPlayer.volume = 0.5; // 音量[_audioPlayer prepareToPlay];// 加载音频文件到缓存【这个函数在调用play函数时会自动调用】if(error){NSLog(@"初始化播放器过程发生错误,错误信息:%@",error.localizedDescription);return nil;}return _audioPlayer;}// 播放录制好的音频- (IBAction)playRecordedAudio {// 没有文件不播放if (![[NSFileManager defaultManager] fileExistsAtPath:self.filepathCaf]) return;// 播放最新的录音[self.audioPlayer play];}完整源码和Demo下载
//// ViewController.m// IOSRecorderDemo//// Created by Xinhou Jiang on 29/12/16.// Copyright © 2016年 Xinhou Jiang. All rights reserved.//#import "ViewController.h"#import <AVFoundation/AVFoundation.h>// 文件名#define fileName_caf @"demoRecord.caf"@interface ViewController ()// 录音文件绝对路径@property (nonatomic, copy) NSString *filepathCaf;// 录音机对象@property (nonatomic, strong) AVAudioRecorder *audioRecorder;// 播放器对象,和上一章音频播放的方法相同,只不过这里简单播放即可@property (nonatomic, strong) AVAudioPlayer *audioPlayer;// 用一个processview显示声波波动情况@property (nonatomic, weak) IBOutlet UIProgressView *processView;// 用一个label显示录制时间@property (nonatomic, weak) IBOutlet UILabel *recordTime;// UI刷新监听器@property (nonatomic, strong) NSTimer *timer;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// 初始化工作[self initData];}// 初始化- (void)initData {// 获取沙盒Document文件路径NSString *sandBoxPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];// 拼接录音文件绝对路径_filepathCaf = [sandBoxPath stringByAppendingPathComponent:fileName_caf];// 1.创建音频会话AVAudioSession *audioSession=[AVAudioSession sharedInstance];// 设置录音类别(这里选用录音后可回放录音类型)[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];[audioSession setActive:YES error:nil];// 2.开启定时器[self timer];}#pragma mark -录音设置工具函数// 懒加载录音机对象get方法- (AVAudioRecorder *)audioRecorder {if (!_audioRecorder) {// 保存录音文件的路径urlNSURL *url = [NSURL URLWithString:_filepathCaf];// 创建录音格式设置settingNSDictionary *setting = [self getAudioSetting];// errorNSError *error=nil;_audioRecorder = [[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];_audioRecorder.delegate = self;_audioRecorder.meteringEnabled = YES;// 监控声波if (error) {NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription);return nil;}}return _audioRecorder;}// audioPlayer懒加载getter方法- (AVAudioPlayer *)audioPlayer {_audioRecorder = NULL; // 每次都创建新的播放器,删除旧的// 资源路径NSURL *url = [NSURL fileURLWithPath:_filepathCaf];// 初始化播放器,注意这里的Url参数只能为本地文件路径,不支持HTTP UrlNSError *error = nil;_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];//设置播放器属性_audioPlayer.numberOfLoops = 0;// 不循环_audioPlayer.delegate = self;_audioPlayer.volume = 0.5; // 音量[_audioPlayer prepareToPlay];// 加载音频文件到缓存【这个函数在调用play函数时会自动调用】if(error){NSLog(@"初始化播放器过程发生错误,错误信息:%@",error.localizedDescription);return nil;}return _audioPlayer;}// 计时器get方法- (NSTimer *)timer {if (!_timer) {_timer = [NSTimer scheduledTimerWithTimeInterval:0.1f repeats:YES block:^(NSTimer * _Nonnull timer) {if(_audioRecorder) {// 1.更新录音时间,单位秒int curInterval = [_audioRecorder currentTime];_recordTime.text = [NSString stringWithFormat:@"%02d:%02d",curInterval/60,curInterval%60];// 2.声波显示//更新声波值[self.audioRecorder updateMeters];//第一个通道的音频,音频强度范围:[-160~0],这里调整到0~160float power = [self.audioRecorder averagePowerForChannel:0] + 160;[_processView setProgress:power/160.0];}}];}return _timer;}// 录音设置-(NSDictionary *)getAudioSetting{// LinearPCM 是iOS的一种无损编码格式,但是体积较为庞大// 录音设置信息字典NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];// 录音格式[recordSettings setValue :@(kAudioFormatLinearPCM) forKey: AVFormatIDKey];// 采样率[recordSettings setValue :@11025.0 forKey: AVSampleRateKey];// 通道数(双通道)[recordSettings setValue :@2 forKey: AVNumberOfChannelsKey];// 每个采样点位数(有8、16、24、32)[recordSettings setValue :@16 forKey: AVLinearPCMBitDepthKey];// 采用浮点采样[recordSettings setValue:@YES forKey:AVLinearPCMIsFloatKey];// 音频质量[recordSettings setValue:@(AVAudioQualityMedium) forKey:AVEncoderAudioQualityKey];// 其他可选的设置// ... ...return recordSettings;}// 删除filepathCaf路径下的音频文件-(void)deleteRecord{NSFileManager* fileManager=[NSFileManager defaultManager];if ([[NSFileManager defaultManager] fileExistsAtPath:self.filepathCaf]) {// 文件已经存在if ([fileManager removeItemAtPath:self.filepathCaf error:nil]) {NSLog(@"删除成功");}else {NSLog(@"删除失败");}}else {return; // 文件不存在无需删除}}#pragma mark -录音流程控制函数// 开始录音或者继续录音- (IBAction)startOrResumeRecord {// 注意调用audiorecorder的get方法if (![self.audioRecorder isRecording]) {// 如果该路径下的音频文件录制过则删除[self deleteRecord];// 开始录音,会取得用户使用麦克风的同意[_audioRecorder record];}}// 录音暂停- (IBAction)pauseRecord {if (_audioRecorder) {[_audioRecorder pause];}}// 结束录音- (IBAction)stopRecord {[_audioRecorder stop];}#pragma mark -录音播放// 播放录制好的音频- (IBAction)playRecordedAudio {// 没有文件不播放if (![[NSFileManager defaultManager] fileExistsAtPath:self.filepathCaf]) return;// 播放最新的录音[self.audioPlayer play];}@endDemo下载:demo