在AVFoundation架構中還要一個AVAudioRecorder類專門處理錄音操作,它同樣支援多種音頻格式。與AVAudioPlayer類似,你完全可以將它看成是一個錄音機控制類,下面是常用的屬性和方法:
屬性 |
說明 |
@property(readonly, getter=isRecording) BOOL recording; |
是否正在錄音,唯讀 |
@property(readonly) NSURL *url |
錄音檔案地址,唯讀 |
@property(readonly) NSDictionary *settings |
錄音檔案設定,唯讀 |
@property(readonly) NSTimeInterval currentTime |
錄音時間長度,唯讀,注意僅僅在錄音狀態可用 |
@property(readonly) NSTimeInterval deviceCurrentTime |
輸入設定的時間長度,唯讀,注意此屬性一直可訪問 |
@property(getter=isMeteringEnabled) BOOL meteringEnabled; |
是否啟用錄音測量,如果啟用錄音測量可以獲得錄音分貝等資料資訊 |
@property(nonatomic, copy) NSArray *channelAssignments |
當前錄音的通道 |
對象方法 |
說明 |
- (instancetype)initWithURL:(NSURL *)url settings:(NSDictionary *)settings error:(NSError **)outError |
錄音機對象初始化方法,注意其中的url必須是本地檔案url,settings是錄音格式、編碼等設定 |
- (BOOL)prepareToRecord |
準備錄音,主要用於建立緩衝區,如果不手動調用,在調用record錄音時也會自動調用 |
- (BOOL)record |
開始錄音 |
- (BOOL)recordAtTime:(NSTimeInterval)time |
在指定的時間開始錄音,一般用於錄音暫停再恢複錄音 |
- (BOOL)recordForDuration:(NSTimeInterval) duration |
按指定的時間長度開始錄音 |
- (BOOL)recordAtTime:(NSTimeInterval)time forDuration:(NSTimeInterval) duration |
在指定的時間開始錄音,並指定錄音時間長度 |
- (void)pause; |
暫停錄音 |
- (void)stop; |
停止錄音 |
- (BOOL)deleteRecording; |
刪除錄音,注意要刪除錄音此時錄音機必須處於停止狀態 |
- (void)updateMeters; |
更新測量資料,注意只有meteringEnabled為YES此方法才可用 |
- (float)peakPowerForChannel:(NSUInteger)channelNumber; |
指定通道的測量峰值,注意只有調用完updateMeters才有值 |
- (float)averagePowerForChannel:(NSUInteger)channelNumber |
指定通道的測量平均值,注意只有調用完updateMeters才有值 |
代理方法 |
說明 |
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag |
完成錄音 |
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error |
錄音編碼發生錯誤 |
AVAudioRecorder很多屬性和方法跟AVAudioPlayer都是類似的,但是它的建立有所不同,在建立錄音機時除了指定路徑外還必須指定錄音設定資訊,因為錄音機必須知道錄音檔案的格式、採樣率、通道數、每個採樣點的位元等資訊,但是也並不是所有的資訊都必須設定,通常只需要幾個常用設定。關於錄音設定詳見協助文檔中的“AV Foundation Audio Settings Constants”。
下面就使用AVAudioRecorder建立一個錄音機,實現了錄音、暫停、停止、播放等功能,實現效果大致如下:
在這個樣本中將實行一個完整的錄音控制,包括錄音、暫停、恢複、停止,同時還會即時展示使用者錄音的聲音波動,當使用者點擊完停止按鈕還會自動播放錄音檔案。程式的構建主要分為以下幾步: 設定音頻會話類型為AVAudioSessionCategoryPlayAndRecord,因為程式中牽扯到錄音和播放操作。 建立錄音機AVAudioRecorder,指定錄音儲存的路徑並且設定錄音屬性,注意對於一般的錄音檔案要求的採樣率、位元並不高,需要適當設定以保證錄音檔案的大小和效果。 設定錄音機代理以便在錄音完成後播放錄音,開啟錄音測量保證能夠即時獲得錄音時的聲音強度。(注意聲音強度範圍-160到0,0代表最大輸入) 建立音頻播放器AVAudioPlayer,用於在錄音完成之後播放錄音。 建立一個定時器以便即時重新整理錄音測量值並更新錄音強度到UIProgressView中顯示。 添加錄音、暫停、恢複、停止操作,需要注意錄音的恢複操作其實是有音頻會話管理的,恢複時只要再次調用record方法即可,無需手動管理恢復等。
下面是主要代碼:
//// ViewController.m// AVAudioRecorder//// Created by Kenshin Cui on 14/03/30.// Copyright (c) 2014年 cmjstudio. All rights reserved.//#import "ViewController.h"#import <AVFoundation/AVFoundation.h>#define kRecordAudioFile @"myRecord.caf"@interface ViewController ()<AVAudioRecorderDelegate>@property (nonatomic,strong) AVAudioRecorder *audioRecorder;//音頻錄音機@property (nonatomic,strong) AVAudioPlayer *audioPlayer;//音頻播放器,用於播放錄音檔案@property (nonatomic,strong) NSTimer *timer;//錄音聲波監控(注意這裡暫時不對播放進行監控)@property (weak, nonatomic) IBOutlet UIButton *record;//開始錄音@property (weak, nonatomic) IBOutlet UIButton *pause;//暫停錄音@property (weak, nonatomic) IBOutlet UIButton *resume;//恢複錄音@property (weak, nonatomic) IBOutlet UIButton *stop;//停止錄音@property (weak, nonatomic) IBOutlet UIProgressView *audioPower;//音頻波動@end@implementation ViewController#pragma mark - 控制器視圖方法- (void)viewDidLoad { [super viewDidLoad]; [self setAudioSession];}#pragma mark - 私人方法/** * 設定音頻會話 */-(void)setAudioSession{ AVAudioSession *audioSession=[AVAudioSession sharedInstance]; //設定為播放和錄音狀態,以便可以在錄製完之後播放錄音 [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; [audioSession setActive:YES error:nil];}/** * 取得錄音檔案儲存路徑 * * @return 錄音檔案路徑 */-(NSURL *)getSavePath{ NSString *urlStr=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; urlStr=[urlStr stringByAppendingPathComponent:kRecordAudioFile]; NSLog(@"file path:%@",urlStr); NSURL *url=[NSURL fileURLWithPath:urlStr]; return url;}/** * 取得錄音檔案設定 * * @return 錄音設定 */-(NSDictionary *)getAudioSetting{ NSMutableDictionary *dicM=[NSMutableDictionary dictionary]; //設定錄音格式 [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey]; //設定錄音採樣率,8000是電話採樣率,對於一般錄音已經夠了 [dicM setObject:@(8000) forKey:AVSampleRateKey]; //設定通道,這裡採用單聲道 [dicM setObject:@(1) forKey:AVNumberOfChannelsKey]; //每個採樣點位元,分為8、16、24、32 [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey]; //是否使用浮點數採樣 [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey]; //....其他設定等 return dicM;}/** * 獲得錄音機對象 * * @return 錄音機對象 */-(AVAudioRecorder *)audioRecorder{ if (!_audioRecorder) { //建立錄音檔案儲存路徑 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 if (error) { NSLog(@"建立錄音機對象時發生錯誤,錯誤資訊:%@",error.localizedDescription); return nil; } } return _audioRecorder;}/** * 建立播放器 * * @return 播放器 */-(AVAudioPlayer *)audioPlayer{ if (!_audioPlayer) { NSURL *url=[self getSavePath]; NSError *error=nil; _audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error]; _audioPlayer.numberOfLoops=0; [_audioPlayer prepareToPlay]; if (error) { NSLog(@"建立播放器過程中發生錯誤,錯誤資訊:%@",error.localizedDescription); return nil; } } return _audioPlayer;}/** * 錄音聲波監控定製器 * * @return 定時器 */-(NSTimer *)timer{ if (!_timer) { _timer=[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(audioPowerChange) userInfo:nil repeats:YES]; } return _timer;}/** * 錄音聲波狀態設定 */-(void)audioPowerChange{ [self.audioRecorder updateMeters];//更新測量值 float power= [self.audioRecorder averagePowerForChannel:0];//取得第一個通道的音頻,注意音頻強度範圍時-160到0 CGFloat progress=(1.0/160.0)*(power+160.0); [self.audioPower setProgress:progress];}#pragma mark - UI事件/** * 點擊錄音按鈕 * * @param sender 錄音按鈕 */- (IBAction)recordClick:(UIButton *)sender { if (![self.audioRecorder isRecording]) { [self.audioRecorder record];//首次使用應用時如果調用record方法會詢問使用者是否允許使用麥克風 self.timer.fireDate=[NSDate distantPast]; }}/** * 點擊暫訂按鈕 * * @param sender 暫停按鈕 */- (IBAction)pauseClick:(UIButton *)sender { if ([self.audioRecorder isRecording]) { [self.audioRecorder pause]; self.timer.fireDate=[NSDate distantFuture]; }}/** * 點擊恢複按鈕 * 恢複錄音只需要再次調用record,AVAudioSession會協助你記錄上次錄音位置並追加錄音 * * @param sender 恢複按鈕 */- (IBAction)resumeClick:(UIButton *)sender { [self recordClick:sender];}/** * 點擊停止按鈕 * * @param sender 停止按鈕 */- (IBAction)stopClick:(UIButton *)sender { [self.audioRecorder stop]; self.timer.fireDate=[NSDate distantFuture]; self.audioPower.progress=0.0;}#pragma mark - 錄音機代理方法/** * 錄音完成,錄音完成後播放錄音 * * @param recorder 錄音機對象 * @param flag 是否成功 */-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{ if (![self.audioPlayer isPlaying]) { [self.audioPlayer play]; } NSLog(@"錄音完成!");}@end
運行效果:
本文轉自:http://www.cnblogs.com/kenshincui/p/4186022.html