1. AVAudioRecorder应用
AVAudioRecorder
的主要属性
// 是否在录制中
@property(readonly, getter=isRecording) BOOL recording;
// 录音本地文件地址
@property(readonly) NSURL *url;
// 录音文件配置
@property(readonly) NSDictionary<NSString *, id> *settings;// 录音文件当前时间,只有在录音时有效
@property(readonly) NSTimeInterval currentTime;
// 设备当前时间
@property(readonly) NSTimeInterval deviceCurrentTime;// AVAudioRecorder回调
@property(weak, nullable) id<AVAudioRecorderDelegate> delegate;// 是否启用音频测量, 默认是NO
@property(getter=isMeteringEnabled) BOOL meteringEnabled;
AVAudioRecorder
的主要方法
// 初始化方法
- (nullable instancetype)initWithURL:(NSURL *)url settings:(NSDictionary<NSString *, id> *)settings error:(NSError **)outError;
// 准备开始录音
- (BOOL)prepareToRecord;
// 立即开始录音
- (BOOL)record;
// 在一段时间之后开始录音,time与deviceCurrentTime相比较
- (BOOL)recordAtTime:(NSTimeInterval)time;
// 开始录音,并只录制一段时间
- (BOOL)recordForDuration:(NSTimeInterval) duration;
// 在一段时间之后开始录音,并只录制一段时间
- (BOOL)recordAtTime:(NSTimeInterval)time forDuration:(NSTimeInterval) duration;// 暂停录音
- (void)pause;
// 停止录音,关闭录音文件
- (void)stop;
// 删除录音文件,需在stop方法后
- (BOOL)deleteRecording;// 更新音频测量值,meteringEnabled为YES时才可以获得音频分贝等信息
- (void)updateMeters;
// 获得指定声道的分贝峰值,在此之前调用updateMeters方法
- (float)peakPowerForChannel:(NSUInteger)channelNumber;
// 获得指定声道的分贝平均值,在此之前调用updateMeters方法
- (float)averagePowerForChannel:(NSUInteger)channelNumber;
AVAudioRecorder
录制后将音频保存到本地文件中
- (void)startRecord:(NSString *)filePath {NSDictionary *setting = @{AVFormatIDKey: @(kAudioFormatMPEG4AAC), // 音频格式AVSampleRateKey : @(44100), // 采样率AVNumberOfChannelsKey : @(1) // 声道数};NSError *error;self.audioRecorder = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath:filePath] settings:setting error:&error];if (!error) {self.audioRecorder.delegate = self;self.audioRecorder.meteringEnabled = YES;[self.audioRecorder prepareToRecord];[self.audioRecorder record];}
}- (void)stopRecord {[self.audioRecorder pause];[self.audioRecorder stop];
}
2. AVAudioRecorderDelegate代理
AVAudioRecorderDelegate
主要有两个方法
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag {// 录音结束}- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError * __nullable)error {// 录音错误}
3. 获取音频功率
获取音频功率,meteringEnabled
需要设置为YES
- (void)updateMeter { // 获取计量之前调用[self.audioRecorder updateMeters];CGFloat averagePower = [self.audioRecorder averagePowerForChannel:0];CGFloat peakPower = [self.audioRecorder peakPowerForChannel:0];// 网上给出的转换公式,转换后结果是 0 到 120 的幅度范围内CGFloat power = pow(10.0, peakPower / 20.0) * 120;
}
4. 合并录音文件
录音结束后,有时需要合并录音文件
- (void)mergeAudio:(NSArray *)filePathArray outputFile:(NSString *)outputFilePath {// 创建音频轨道,并获取多个音频素材的轨道AVMutableComposition *composition = [AVMutableComposition composition];// 音频插入的开始时间,用于记录每次添加音频文件的开始时间__block CMTime beginTime = kCMTimeZero;[filePathArray enumerateObjectsUsingBlock:^(NSString *filePath, NSUInteger idx, BOOL * _Nonnull stop) {// 获取音频素材AVURLAsset *audioAsset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:filePath]];// 音频轨道AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];// 获取音频素材轨道AVAssetTrack *audioAssetTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] firstObject];// 音频合并- 插入音轨文件[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) ofTrack:audioAssetTrack atTime:beginTime error:nil];// 记录尾部时间beginTime = CMTimeAdd(beginTime, audioAsset.duration);}];AVAssetExportSession *session = [[AVAssetExportSession alloc]initWithAsset:composition presetName:AVAssetExportPresetAppleM4A];// 音频文件输出session.outputURL = [NSURL fileURLWithPath:outputFilePath];session.outputFileType = AVFileTypeAppleM4A; // 与上述的`present`相对应[session exportAsynchronouslyWithCompletionHandler:^{if (session.status == AVAssetExportSessionStatusCompleted) {} else {}}];
}