AVAudioRecorder 同AVAudioPlayer 類似,都是AVFoundation框架下的類
AVAudioRecorder 是一個錄音器,可以調用方法來錄制音頻,使用還是比較簡單的。
一、開啟錄音權限,並設置錄音category
需要在info.plist文件中添加Privacy - Microphone Usage Description
//請求錄音權限
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
//yes表示用戶同意
if (granted) {
NSError * error = nil;
//設置錄音category
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:&error];
if (error) {
NSLog(@"設置錄音類別失敗");
}
[[AVAudioSession sharedInstance] setActive:YES error:&error];
if (error) {
NSLog(@"激活類別失敗");
}
} else {
NSLog(@"用戶不允許錄音");
}
}];
備注:AVAudioSessionCategoryRecord 只是使用錄音通道,設置了之后只能錄音,不能播放音頻。
也可以使用AVAudioSessionCategoryPlayAndRecord 可以一邊播放一邊錄音,有語音喚醒的應用一般需要使用這個category
二、初始化錄音器
兩種初始化方法
- (nullable instancetype)initWithURL:(NSURL *)url settings:(NSDictionary<NSString *, id> *)settings error:(NSError **)outError;
- (nullable instancetype)initWithURL:(NSURL *)url format:(AVAudioFormat *)format error:(NSError **)outError;
url:指要存儲音頻的本地路徑地址
settings/format:錄制會話的設置
outError:錯誤描述
2.1 settings字典的所需key
音頻格式設置
-
AVFormatIDKey
格式標識符。取值為
AudioFormatID類型 -
AVSampleRateKey
用於定義錄音的采樣率。數值越小,錄音質量越差,對應的錄音文件越小。數值越大,錄音質量越好,對應的錄音文件越大。比如8000(AM廣播類型的錄制效果),16000,22050或者44100(CD質量的采樣率)
-
AVNumberOfChannelsKey
用於設置錄音時的通道數。設置默認值1為單聲道錄制,設置為2意味着使用立體聲錄制。除非使用外設進行錄制,否則應設置為1。
編碼設置
-
AVEncoderAudioQualityKey
編碼質量,值為
AVAudioQuality -
AVEncoderBitRateKey
編碼比特率,值為整數
-
AVEncoderBitRatePerChannelKey
標識每個通道的編碼比特率。
注意:
AVEncoderBitRateKey和AVEncoderBitRatePerChannelKey只需要設置一個
-
AVEncoderBitRateStrategyKey
編碼比特率的策略 取值為
AVAudioBitRateStrategy -
AVEncoderAudioQualityForVBRKey
動態比特率,只和AVAudioBitRateStrategy_Variable有關 值為
AVAudioQuality -
AVEncoderBitDepthHintKey
編碼位數(位深度)。值為8~32。這個數值越大,解析度就越高,錄制和回放的聲音就越真實
線性PCM音頻格式設置
-
AVLinearPCMBitDepthKey
一個NSNumber整數,指示線性PCM音頻格式的位深度,值為8、16、24或32之一。
-
AVLinearPCMIsBigEndianKey
一個布爾值,指示音頻格式是大端(YES)還是小端(NO)。
-
AVLinearPCMIsFloatKey
一個布爾值,指示音頻格式是浮點(YES)還是定點(NO)。
-
AVLinearPCMIsNonInterleaved
一個布爾值,指示音頻格式是非交錯(YES)還是交錯(NO)。
采樣率轉換設置
-
AVSampleRateConverterAudioQualityKey
音頻采用率質量(錄音采樣質量)值為
AVAudioQuality -
AVSampleRateConverterAlgorithmKey
采樣率轉化算法, 值為 AVSampleRateConverterAlgorithm字符串
2.2 key對應的參數值
AudioFormatID音頻格式,枚舉類型
CF_ENUM(AudioFormatID)
{
kAudioFormatLinearPCM = 'lpcm',
kAudioFormatAC3 = 'ac-3',
kAudioFormat60958AC3 = 'cac3',
kAudioFormatAppleIMA4 = 'ima4',
kAudioFormatMPEG4AAC = 'aac ',
kAudioFormatMPEG4CELP = 'celp',
kAudioFormatMPEG4HVXC = 'hvxc',
kAudioFormatMPEG4TwinVQ = 'twvq',
kAudioFormatMACE3 = 'MAC3',
kAudioFormatMACE6 = 'MAC6',
kAudioFormatULaw = 'ulaw',
kAudioFormatALaw = 'alaw',
kAudioFormatQDesign = 'QDMC',
kAudioFormatQDesign2 = 'QDM2',
kAudioFormatQUALCOMM = 'Qclp',
kAudioFormatMPEGLayer1 = '.mp1',
kAudioFormatMPEGLayer2 = '.mp2',
kAudioFormatMPEGLayer3 = '.mp3',
kAudioFormatTimeCode = 'time',
kAudioFormatMIDIStream = 'midi',
kAudioFormatParameterValueStream = 'apvs',
kAudioFormatAppleLossless = 'alac',
kAudioFormatMPEG4AAC_HE = 'aach',
kAudioFormatMPEG4AAC_LD = 'aacl',
kAudioFormatMPEG4AAC_ELD = 'aace',
kAudioFormatMPEG4AAC_ELD_SBR = 'aacf',
kAudioFormatMPEG4AAC_ELD_V2 = 'aacg',
kAudioFormatMPEG4AAC_HE_V2 = 'aacp',
kAudioFormatMPEG4AAC_Spatial = 'aacs',
kAudioFormatMPEGD_USAC = 'usac',
kAudioFormatAMR = 'samr',
kAudioFormatAMR_WB = 'sawb',
kAudioFormatAudible = 'AUDB',
kAudioFormatiLBC = 'ilbc',
kAudioFormatDVIIntelIMA = 0x6D730011,
kAudioFormatMicrosoftGSM = 0x6D730031,
kAudioFormatAES3 = 'aes3',
kAudioFormatEnhancedAC3 = 'ec-3',
kAudioFormatFLAC = 'flac',
kAudioFormatOpus = 'opus'
};
AVAudioQuality 一個枚舉屬性,指定采用率轉化質量
typedef NS_ENUM(NSInteger, AVAudioQuality) {
AVAudioQualityMin = 0,
AVAudioQualityLow = 0x20,
AVAudioQualityMedium = 0x40,
AVAudioQualityHigh = 0x60,
AVAudioQualityMax = 0x7F
};
AVSampleRateConverterAlgorithm 轉換算法(字符串類型)
// 使用正常的編碼器比特率策略
extern NSString *const AVSampleRateConverterAlgorithm_Normal;
// 使用主控編碼器比特率策略
extern NSString *const AVSampleRateConverterAlgorithm_Mastering;
// 使用最小相位編碼器比特率策略
extern NSString *const AVSampleRateConverterAlgorithm_MinimumPhase;
AVAudioBitRateStrategy 比特率的策略
// 常數策略
extern NSString *const AVAudioBitRateStrategy_Constant;
// 長期平均值策略
extern NSString *const AVAudioBitRateStrategy_LongTermAverage;
// 受約束的變量值策略
extern NSString *const AVAudioBitRateStrategy_VariableConstrained;
// 變量值策略
extern NSString *const AVAudioBitRateStrategy_Variable;
2.3 示例
上邊的值不需要全部設置,只使用需要的就可以,例如:
NSDictionary *settings = @{
AVSampleRateKey:[NSNumber numberWithFloat: 44100.0], // 采樣率
AVFormatIDKey:[NSNumber numberWithInt: kAudioFormatMPEG4AAC], // 音頻格式
AVNumberOfChannelsKey:[NSNumber numberWithInt: 1], // 聲道數
AVEncoderAudioQualityKey:[NSNumber numberWithInt:AVAudioQualityMin], // 錄音質量
AVSampleRateConverterAudioQualityKey:[NSNumber numberWithInt: AVAudioQualityMin] // 錄音采樣質量
};
NSError *error;
_audioRecorder = [[AVAudioRecorder alloc] initWithURL:_recordURL settings:settings error:&error];
if(error) {
NSLog(@"Ups, could not create recorder %@", error);
}
三、錄音
3.1常用方法如下:
// 創建一個文件,並准備開始錄制。調用record方法時,如果音頻還沒有准備好,程序會隱式先執行該方法。
- (BOOL)prepareToRecord;
// 開始或恢復錄制。調用該方法時,如果音頻還沒有准備好,程序會隱式執行prepareToRecord方法。
- (BOOL)record;
// 在指定時間點開始或恢復錄制。時間是一個絕對的時間,基於並大於設備的時間
- (BOOL)recordAtTime:(NSTimeInterval)time;
// 錄制一個指定持續時間的音頻,錄到指定時長后會自動停止
- (BOOL)recordForDuration:(NSTimeInterval) duration;
// 在指定時間點開始或恢復錄制,並指定錄制的持續時間。
- (BOOL)recordAtTime:(NSTimeInterval)time forDuration:(NSTimeInterval) duration;
// 暫停。
- (void)pause;
// 停止
- (void)stop;
// 必須先調用停止之后才能調用,調用后會刪掉錄制的音頻文件
- (BOOL)deleteRecording;
3.2 其他方法
獲取音量(分貝)
// 是否開啟分貝檢測,默認是關閉的
@property(getter=isMeteringEnabled) BOOL meteringEnabled;
// 調用更新分貝值,在調用后面兩個方法前,需要先調用這個方法
- (void)updateMeters;
// 返回給定信道的峰值功率(最大分貝)親測,取值范圍為 -160~0,但官方文檔說值有可能超過0
- (float)peakPowerForChannel:(NSUInteger)channelNumber;
// 返回給定信道的平均功率(平均分貝)
- (float)averagePowerForChannel:(NSUInteger)channelNumber;
從這里找到分貝轉化的代碼如下,未測試結果是否准確
[recorder updateMeters];
//發送updateMeters消息來刷新平均和峰值功率。此計數是以對數刻度計量的,-160表示完全安靜,0表示最大輸入值
float averagePower = [recorder averagePowerForChannel:0];
float peakPower = [recorder peakPowerForChannel:0];
//轉換最高分貝值,范圍是0到1。0最小,1最大。
const double ALPHA = 0.05;
double peakPowerForChannel = pow(10, (0.05 * peakPower));
lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;
3.3 代理
/*在錄制完成或停止時調用。如果recorder由於中斷而停止,則不調用此方法.*/
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag;
/* 如果在編碼時發生錯誤,將調用這個方法告訴代理*/
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError * __nullable)error;
// audio的interrupt打斷代理不建議使用,建議使用avaudiosession的打斷監聽來處理。
