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. 錄音發送到服務器(請關注我的上一篇簡書,與圖片的發送一致,用力戳)