使用AVAudioRecorder錄制音頻


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

    標識每個通道的編碼比特率。

注意:AVEncoderBitRateKeyAVEncoderBitRatePerChannelKey只需要設置一個

  • 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的打斷監聽來處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM