iOS录音及播放全解
//
// ViewController.m
// 录音与播放
//
// Created by 张璟冰 on 2020/3/29.
// Copyright © 2020 张璟冰. All rights reserved.
//
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()<AVAudioRecorderDelegate>{
UILabel *timeLabel;
float time;//保存我们录音录了多久
}
@property(nonatomic,strong)AVAudioRecorder *audioRecorder;//录音器
@property (nonatomic,strong) NSString *mp3Path;
@property (nonatomic,strong) NSString *cafPath;
@property (nonatomic, strong) NSTimer *timer;//定时器
@property (nonatomic, strong) AVAudioPlayer *player; //播放器
@end
@implementation ViewController
#pragma mark 第三步 录音器的懒加载
- (AVAudioRecorder *)audioRecorder
{
if (!_audioRecorder)
{
//7.0第一次运行会提示,是否允许使用麦克风
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *sessionError;
//AVAudioSessionCategoryPlayAndRecord用于录音和播放
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
if(session == nil)
NSLog(@"Error creating session: %@", [sessionError description]);
else
[session setActive:YES error:nil];
//创建录音文件保存路径
NSURL *url = [self getSavePath];
//创建录音格式设置
NSDictionary *setting = [self getAudioSetting];
//创建录音机
NSError *error=nil;
_audioRecorder = [[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];
_audioRecorder.delegate=self;
_audioRecorder.meteringEnabled=YES;//如果要监控声波则必须设置为YES
[_audioRecorder prepareToRecord];
if (error)
{
NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription);
return nil;
}
}
return _audioRecorder;
}
/**
* 取得录音文件保存路径
*
* @return 录音文件路径
*/
-(NSURL *)getSavePath
{
//iPhone会为每一个应用程序生成一个私有目录,这个目录位于/user/.../Application下
//并会随机生成一个数字字母串作为目录名
//通常使用Documents目录进行数据持久化的保存
// 在Documents目录下创建一个名为AudioData的文件夹、
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"AudioData"];
NSLog(@"%@",path);
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isDir = FALSE;
BOOL isDirExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
if(!(isDirExist && isDir))
{
BOOL bCreateDir = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
if(!bCreateDir){
NSLog(@"创建文件夹失败!");
}
NSLog(@"创建文件夹成功,文件路径%@",path);
}
NSString *fileName = @"record";
NSString *cafFileName = [NSString stringWithFormat:@"%@.caf", fileName];
NSString *mp3FileName = [NSString stringWithFormat:@"%@.mp3", fileName];
//拼接路径
NSString *cafPath = [path stringByAppendingPathComponent:cafFileName];
NSString *mp3Path = [path stringByAppendingPathComponent:mp3FileName];
self.mp3Path = mp3Path;
self.cafPath = cafPath;
NSLog(@"file path:%@",cafPath);
NSURL *url=[NSURL fileURLWithPath:cafPath];
return url;
}
/**
* 取得录音文件设置
*
* @return 录音设置
*/
- (NSDictionary *)getAudioSetting
{
NSMutableDictionary *dicM = [NSMutableDictionary dictionary];
[dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
// [dicM setObject:@(ETRECORD_RATE) forKey:AVSampleRateKey];
[dicM setObject:@(2) forKey:AVNumberOfChannelsKey];
[dicM setObject:@(16) forKey:AVLinearPCMBitDepthKey];
[dicM setObject:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];
return dicM;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
btn.tag = 10000;
[btn setTitle:@"开始录音" forState:UIControlStateNormal];
[btn setTitle:@"停止录音" forState:UIControlStateSelected];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn.backgroundColor = [UIColor whiteColor];
[btn addTarget:self action:@selector(recordClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
UIButton *btn2 = [[UIButton alloc]initWithFrame:CGRectMake(120, 0, 100, 100)];
btn2.tag = 10001;
[btn2 setTitle:@"播放录音" forState:UIControlStateNormal];
[btn2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn2.backgroundColor = [UIColor whiteColor];
[btn2 addTarget:self action:@selector(play:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn2];
//时间
timeLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 200, 100, 30)];
timeLabel.text = @"录音时长";
timeLabel.font = [UIFont systemFontOfSize:16];
timeLabel.textColor = [UIColor blackColor];
[self.view addSubview:timeLabel];
}
#pragma mark 播放录音
-(void)play:(UIButton *)sender
{
if ([self.player isPlaying])
return;
self.player = [[AVAudioPlayer alloc]initWithData:[NSData dataWithContentsOfFile:self.cafPath] error:nil];
[self.player play];
}
#pragma mark 第四步 开始/结束录音点击、播放点击
-(void)recordClick:(UIButton *)sender
{
sender.selected = !sender.selected;
if (sender.selected)
{
//开始录音
[self startRecord];
}
else
{
//结束录音
[self finishRecorded];
}
}
//结束录音
- (void)finishRecorded
{
//使用系统自带录音机
if ([self.audioRecorder isRecording])
{
NSLog(@"完成");
[self destoryTimer];
[self.audioRecorder stop];//停止工作
}
if (time < 1)
{
NSLog(@"录音时间过短!");//清空录音内容
return;
}
//进行录音格式的转码成mp3格式、提交网络上传
//Lame
time = 0;
timeLabel.text = @"点击录音";
}
//开始录音
- (void)startRecord
{
// 重置录音机
if (self.audioRecorder)
{
self.audioRecorder = nil;
time = 0;
[self destoryTimer];
}
if (![self.audioRecorder isRecording])
{
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *sessionError;
//AVAudioSessionCategoryPlayAndRecord用于录音和播放
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
if(session == nil)
NSLog(@"Error creating session: %@", [sessionError description]);
else
[session setActive:YES error:nil];
//创建定时器方法,实时计算录音了几秒钟
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(record)
userInfo:nil
repeats:YES];
timeLabel.text = @"00:00";
[self.audioRecorder record];//开始工作
NSLog(@"录音开始");
}
else
{
NSLog(@"is recording now ....");
}
}
// 定时器方法--录音时间计算
- (void)record
{
time = time+1;
timeLabel.text = [self timeFormatted:(float)time];
//假如一次性只能录180s,一般写倒计时提示
if (time == 180)
{
NSLog(@"%@",@"最多仅能录取180s");
//结束录音
UIButton *btn = [self.view viewWithTag:10000];
btn.selected = !btn.selected;
// [self finishRecorded];//调用录音结束
[self.timer invalidate];
self.timer = nil;
// _recordGIFImg.hidden = YES;//关闭GIF图,这个图是一个光播图标)))
// [_recordGIFImg stopAnimating];
}
}
- (NSString *)timeFormatted:(NSInteger)totalSeconds
{
NSInteger seconds = totalSeconds % 60;
NSInteger minutes = (totalSeconds / 60) % 60;
NSInteger hours = totalSeconds / 3600;
if (hours <= 0)
{
return [NSString stringWithFormat:@"%02ld:%02ld",(long)minutes, (long)seconds];
}
return [NSString stringWithFormat:@"%02ld:%02ld:%02ld",(long)hours, (long)minutes, (long)seconds];
}
//销毁定时器
- (void)destoryTimer
{
if (self.timer)
{
[self.timer invalidate];//使其无效
self.timer = nil;//置空
NSLog(@"----- timer destory");
}
}
@end