1. 导入录音功能依赖的框架
2. 在相应界面引入头文件
然后遵守协议AVAudioRecorderDelegate,AVAudioPlayerDelegate
3. 定义一些需要用得到属性
//录音存储路径
@property (nonatomic, strong)NSURL *tmpFile;
//录音
@property (nonatomic, strong)AVAudioRecorder *recorder;
//播放
@property (nonatomic, strong)AVAudioPlayer *player;
//录音状态(是否录音)
@property (nonatomic, assign)BOOL isRecoding;
4. 录音功能的实现
(1)首先判断后台是否正在播放音乐,如果正在播放则停止播放
session = [AVAudioSession sharedInstance];
NSError *sessionError;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
//判断后台有没有播放
if (session == nil) {
NSLog(@"Error creating sessing:%@", [sessionError description]);
} else {
[session setActive:YES error:nil];
}
(2)实现录音功能
//判断当录音状态为不录音的时候
if (!self.isRecoding)
//设置录音音质
NSMutableDictionary * recordSetting = [NSMutableDictionary dictionary];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];//
[recordSetting setValue:[NSNumber numberWithFloat:8000.0] forKey:AVSampleRateKey];//采样率
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];//声音通道,这里必须为双通道
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityLow] forKey:AVEncoderAudioQualityKey];//音频质量
//创建临时文件来存放录音文件
NSDate * senddate=[NSDate date];
NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init];
[dateformatter setDateFormat:@"yyyyMMddhhmmss"];
String=[dateformatter stringFromDate:senddate];
NSDateFormatter *dateformatter1=[[NSDateFormatter alloc] init];
[dateformatter1 setDateFormat:@"YYYY-MM-dd hh:mm:ss"];
string11=[dateformatter1 stringFromDate:senddate];
//创建临时文件来保存录音文件 (为了播放)
// //保存录音文件到沙盒
self.tmpFile=[NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.caf",String]]];
yuanpath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.caf",String]];
这里创建了一个沙盒路径,并用当前录音时间命名(防止重复)
创建一个计时器来为录音计时,同时时间置0
sec=0;
timer=[NSTimer scheduledTimerWithTimeInterval:1
target:self selector:@selector(timer) userInfo:nil repeats:YES];
接下来设置录音,按钮的状态,以及对获取到的录音进行相关操作
//录音状态变为录音
self.isRecoding = YES;
//将录音按钮变为停止
[recordButton setImage:[UIImage imageNamed:@"recording_button.png"] forState:UIControlStateNormal];
recordla.text=NSLocalizedString(@"tingzhi",@"");
//播放按钮不能被点击
[playButton setEnabled:NO];
playButton.titleLabel.alpha = 0.5;
//开始录音,将所获取到得录音存到文件里,录音放进相应url里
self.recorder = [[AVAudioRecorder alloc] initWithURL:_tmpFile settings:recordSetting error:nil];
//准备记录录音
[_recorder prepareToRecord];
//启动或者恢复记录的录音文件
[_recorder record];
_player = nil;
5. 录音完成
(1)对录音的状态,按钮的设置,录音时间等进行设置
//录音状态 点击录音按钮 停止录音
self.isRecoding = NO;
[recordButton setImage:[UIImage imageNamed:@"record_button.png"] forState:UIControlStateNormal];
recordla.text=NSLocalizedString(@"luyin",@"");
//录音停止的时候,播放按钮可以点击
[playButton setEnabled:YES];
[setButton setEnabled:YES];
[playButton.titleLabel setAlpha:1];
//停止录音
[_recorder stop];
[[NSUserDefaults standardUserDefaults] setObject:[NSString stringWithFormat:@"%d",sec] forKey:@"time"];
[[NSUserDefaults standardUserDefaults] setObject:[NSString stringWithFormat:@"%d",min] forKey:@"min"];
NSString * timestr=[NSString stringWithFormat:@"%@:%02d:%02d",NSLocalizedString(@"luyinshichang",@""),min,sec];
[[NSUserDefaults standardUserDefaults] setObject:timestr forKey:@"soundtime"];
//计时器停止
[timer invalidate];
_recorder = nil;
(2)大多数情况下需要对录音文件的格式进行转换,这里是将录音文件转换成mp3格式,用到第三方libmp3lame
//设置mp3文件的存储路径 nsstring格式的
mp3FilePath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",String]];
@try {
int read, write;
FILE *pcm = fopen ([yuanpath cStringUsingEncoding:1],"rb"); //source 被 转换的音频文件位置
if (pcm == NULL )
{
NSLog ( @"mp3格式转换失败 所给路径没有音频文件" );
}
else{
//source 被转换的音频文件位置
fseek(pcm, 4*1024, SEEK_CUR); //skip file header
FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1],"wb"); //output 输出生成的Mp3文件位置
const int PCM_SIZE = 8192 ;
const int MP3_SIZE = 8192 ;
short int pcm_buffer[PCM_SIZE* 2 ];
unsigned char mp3_buffer[MP3_SIZE];
//mp3格式语音的压缩参数
lame_t lame = lame_init ();
lame_set_num_channels (lame, 2); // 设置 1 为单通道,默认为 2 双通道
lame_set_in_samplerate (lame, 8000.0 ); //11025.0
//lame_set_VBR(lame, vbr_default);
lame_set_brate (lame, 8);
lame_set_mode (lame, 3);
lame_set_mode(lame, 6);
lame_set_brate(lame, 25);
lame_set_quality(lame, 5);
lame_set_quality (lame, 2 ); /* 2=high 5 = medium 7=low 音 质 */
lame_init_params (lame);
do {
read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
if (read == 0)
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
else
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, write, 1, mp3);
} while (read != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);
}
}
@catch (NSException *exception) {
NSLog(@"%@",[exception description]);
}
@finally {
// yuanpath = mp3FilePath;
// NSLog(@"MP3生成成功: %@",yuanpath);
}
});
(3)检测录音是否录制成功
//根据路径播放录音
// self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:_tmpFile error:&playError];
self.tmpFile=[NSURL URLWithString:mp3FilePath];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL: self.tmpFile error:&playError];
//当播放录音为空, 打印错误信息
if (self.player == nil) {
UIAlertView *alertView=[[ UIAlertView alloc ] initWithTitle :NSLocalizedString(@"luyinshibai",@"") message :nil delegate : nil cancelButtonTitle : NSLocalizedString(@"queren",@"") otherButtonTitles : nil ];
[alertView show ];
}
self.player.delegate = self;
6. 播放以及播放暂停,播放完成
(1)播放按钮的实现
//判断是否正在播放,如果正在播放
if ([self.player isPlaying]) {
//正在播放 录音按钮不能被点击
[recordButton setEnabled:YES];
//暂停播放
[_player pause];
[timer invalidate];
//按钮显示为播放
[playButton setImage:[UIImage imageNamed:@"play_button.png"] forState:UIControlStateNormal];
playla.text=NSLocalizedString(@"bofang",@"");
} else {
//开始播放
[recordButton setEnabled:NO];
[_player play];
sec=[[[NSUserDefaults standardUserDefaults] valueForKey:@"time"]intValue];
min=[[[NSUserDefaults standardUserDefaults] valueForKey:@"min"]intValue];
if (!(sec==0)) {
timer=[NSTimer scheduledTimerWithTimeInterval:1
target:self selector:@selector(timer1) userInfo:nil repeats:YES];
}
else{
sec=0;
}
[playButton setImage:[UIImage imageNamed:@"suspend_button.png"] forState:UIControlStateNormal];
playla.text=NSLocalizedString(@"tingzhi",@"");
}
这里又定义了一个计时器,来为播放录音计时
(2)下面两个计时器的实现方法
//录音计时
-(void)timer
{
sec++;
if (sec==60) {
min=min+1;
}
if (min==1) {
[self chaoTimeStop];
}
sec=sec%60;
time.text=[NSString stringWithFormat:@"%02d:%02d",min,sec];
}
/播放计时
-(void)timer1
{
if (sec==0 && min==0) {
sec=0;
}
else{
if (min==0) {
sec--;
sec=sec%60;
time.text=[NSString stringWithFormat:@"%02d:%02d",min,sec];
}
if (min>0) {
sec--;
min--;
sec=sec%60;
time.text=[NSString stringWithFormat:@"%02d:%02d",min,sec];
if (sec==0 && min>0) {
min=min-1;
sec=60;
}
}
}
}
(3)当播放结束时自动调用的方法
//当播放结束后调用这个方法
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
//按钮标题变为播放
[playButton setImage:[UIImage imageNamed:@"play_button.png"] forState:UIControlStateNormal];
playla.text=NSLocalizedString(@"bofang",@"");
[timer invalidate];
int j=[[[NSUserDefaults standardUserDefaults] valueForKey:@"time"] intValue];
int i=[[[NSUserDefaults standardUserDefaults] valueForKey:@"min"] intValue];
if (j>0 && j<10) {
time.text=[NSString stringWithFormat:@"0%d:0%d",i,j];
}
if (j>=10) {
time.text=[NSString stringWithFormat:@"0%d:%d",i,j];
}
[recordButton setEnabled:YES];
}
7. 录音发送到服务器(请关注我的上一篇简书,与图片的发送一致,用力戳)