iOS--錄音相關功能的實現

1. 導入錄音功能依賴的框架


.framework框架

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容