Osheep

时光不回头,当下最重要。

iOS--录音相关功能的实现

1. 导入录音功能依赖的框架

《iOS--录音相关功能的实现》

.framework框架

2. 在相应界面引入头文件

《iOS--录音相关功能的实现》

头文件

然后遵守协议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

《iOS--录音相关功能的实现》

//设置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. 录音发送到服务器(请关注我的上一篇简书,与图片的发送一致,用力戳

点赞