废话不多说,直接看源代码:
还是说一句不算废话的废话,基于AVFoundation.framework 框架实现
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()<AVAudioPlayerDelegate,AVAudioRecorderDelegate>
//1.创建AVAduioPlayer和AVAudioRecorder属性
@property(strong,nonatomic) AVAudioRecorder *audioRecorder;//音频录音机
@property(strong,nonatomic) AVAudioPlayer *audioPlayer;//音频播放器,用于播放录音文件
//2.设置两个按钮
@property(nonatomic,retain) UIButton *recordButton;
@property(nonatomic,retain) UIButton *playButton;
@property(nonatomic,retain) NSDictionary *recordSetting;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//录音按钮
self.recordButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.recordButton.frame = CGRectMake(20, 100, self.view.frame.size.width - 60, 50);
self.recordButton.backgroundColor = [UIColor orangeColor];
[self.recordButton setTitle:@"录音" forState:UIControlStateNormal];
[self.recordButton addTarget:self action:@selector(recordButtonAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.recordButton];
//播放按钮
self.playButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.playButton.frame = CGRectMake(20, 200, self.view.frame.size.width - 60, 50);
self.playButton.backgroundColor = [UIColor orangeColor];
[self.playButton setTitle:@"播放录音" forState:UIControlStateNormal];
[self.playButton addTarget:self action:@selector(playButtonAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.playButton];
//yes 主界面不显示播放按钮 只显示录音按钮
self.playButton.hidden = NO;
//配置recorder 因为录音机必须知道录音文件的格式、采样率、通道数、每个采样点的位数等信息
/*AVEncoderAudioQualityKey音质,
AVEncoderBitRateKey 编码器 比特率
AVNumberOfChannelsKey 设置通道
AVSampleRateKey 设置录音采样率
*/
self.recordSetting = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityLow],AVEncoderAudioQualityKey,[NSNumber numberWithInt:16],AVEncoderBitRateKey,
[NSNumber numberWithInt:2],AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],AVSampleRateKey, nil];
//
// NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
// //设置录音格式
// [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
// //设置录音采样率,8000是电话采样率,对于一般录音已经够了
// [dicM setObject:@(8000) forKey:AVSampleRateKey];
// //设置通道,这里采用单声道
// [dicM setObject:@(1) forKey:AVNumberOfChannelsKey];
// //每个采样点位数,分为8、16、24、32
// [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey];
// //是否使用浮点数采样
// [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
//....其他设置等
}
//懒加载 获得录音机对象
-(AVAudioRecorder *)audioRecorder{
if (!_audioRecorder) {
文件录制的工程中,要使用document地址,下面是两个URL保存路径,但是第一个模拟器运行没问题,真机运行会出现不可录制的情况,转换URL就可以了,这是我们需要主义的一点。
//录音文件保存地址URL
//NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recorder.caf",[[NSBundle mainBundle] resourcePath]]];
NSString *urlStr=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
urlStr=[urlStr stringByAppendingPathComponent:@"/recorder.caf"];
NSLog(@"file path:%@",urlStr);
NSURL *url=[NSURL fileURLWithPath:urlStr];
NSError *errol = nil;
// NSLog(@"url的路径问题打印输出:%@",url);
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *setCategoryError = nil;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&setCategoryError];
if(setCategoryError){
NSLog(@"%@", [setCategoryError description]);
}
//初始化AVAudioRecorder *audioRecorder
self.audioRecorder = [[AVAudioRecorder alloc]initWithURL:url settings:self.recordSetting error:&errol];
if (errol != nil) {
NSLog(@"创建录音机对象时发生错误,错误信息:%@",errol);
NSLog(@"出错了");
}else{
//准备就绪,等待录音 该方法会返回Boolean,做个判断,有错误可以抛出异常信息
//prepareToRecord 创建文件,准备记录。会自动记录
if ([self.audioRecorder prepareToRecord]) {
NSLog(@"成功,准备就绪,等待录音");
}
}
}
return _audioRecorder;
}
//懒加载
//配置好record 开始实现录音按钮
- (void)recordButtonAction{
//判断是否正在录音;
if (self.audioRecorder.recording == 0) {//它是记录吗?
// self.playButton.hidden = YES;//点击录音按钮 播放按钮不显示
[self.audioRecorder record];//开始录音
NSLog(@"开始录音");
}else{
self.playButton.hidden = NO;
//点击录音按钮 播放按钮显示
[self.audioRecorder stop];//停止录音 stops recording. closes the file. 停止记录。关闭文件。
NSLog(@"结束录音");
}
}
//录音结束之后 播放按钮会出现,实现点击播放按钮点击事件
- (void)playButtonAction{
if (!self.audioPlayer.playing) {
self.recordButton.hidden = YES;//点击播放按钮 录音按钮不可用让它不显示 yes 不显示 no是显示
NSError *error;
//录音文件存储的路径
NSLog(@"%@",self.audioRecorder.url);
//初始化 AVAudioPlayer *audioPlayer;
self.audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:self.audioRecorder.url error:&error];
//设置代理
self.audioPlayer.delegate = self;
if (error != nil) {
NSLog(@"player错误:%@",error);
}else{
[self.audioPlayer play];//播放录音
}
}else{
self.recordButton.hidden = NO;//录音按钮显示
[self.audioPlayer pause];//暂停播放,
}
}
//当声音文件播放结束时,需要通知主程序,需要使用AVAudioPlayerDelegate,也可以实现AVAudioRecorderDelegate刈记录record的状态
#pragma mark AVAudioPlayerDelegate
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog(@"完成播放");
self.recordButton.hidden = NO;
}
-(void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
NSLog(@"Decode Error occurred");//解码错误发生
}
#pragma mark AVAudioRecorderDelegate
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
NSLog(@"完成record");//如果发生错误,而编码将报告委托
}
-(void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error{
NSLog(@"Encode Error occurred");//录音编码发生错误
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end