iOS-AVFoundation-AudioRecorder-RecorderAndPlay-語音錄制和播放
支持錄制,暫停,繼續錄制,停止錄制,顯示錄制效果語音界面,點擊播放試聽錄制的語音(這里少一個播放的效果,由于前面介紹過播放,就沒有完善)。
錄制語音.gif
前言:
學習音視頻有一段時間了,先把語音的錄制和播放整合整理筆記,分享給大家。如有不足之處,歡迎指正。
前面一片已經給大家分享過播放了,那么這里重點介紹錄制,其余的UI交互和數據存儲,不在多說,demo里面有完整的思路。相信你也一看就懂。廢話少說,老規矩,上代碼:
JWDRecorderController 類 -音頻錄制
JWDRecorderController.h
#import <Foundation/Foundation.h>
#import "JWDRecorderModel.h"
錄制結束的塊回調
typedef void(^JWDRecordingStopCompletionHandler) (BOOL);
保存數據的塊回調
typedef void(^JWDRecordingSaveCompletionHandler)(BOOL,id);
@interface JWDRecorderController : NSObject
@property(nonatomic, strong)JWDRecordingStopCompletionHandler stopHandler;//!< <#value#>
對外接口
// 錄制
- (BOOL)record;
// 暫停
- (void)pause;
// 停止
- (void)stop;
// 停止
- (void)stopWithCompletionHandler:(JWDRecordingStopCompletionHandler)stopHandler;
// 保存
- (void)saveRecordingWithName:(NSString *)name
completionHandler:(JWDRecordingSaveCompletionHandler)saveHandler;
// 播放
- (void)playRecodeWithMoedl:(JWDRecorderModel *)model;
// 獲取分貝
- (double)getLevelRecoder;//作為顯示 正在錄音效果的顯示
@end
JWDRecorderController.h沒有什么可說的,重點看.m實現
JWDRecorderController.m
init
- (instancetype)init {
self = [super init];
if (self){
// 存儲臨時緩存
NSString *tempDir = NSTemporaryDirectory();
NSString *filePath = [tempDir stringByAppendingPathComponent:@"temp.caf"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
// 設置錄制音頻參數
NSDictionary *settings = @{
AVFormatIDKey :@(kAudioFormatAppleIMA4),//音頻格式
AVSampleRateKey:@44100.0f,// 采樣率
AVEncoderBitDepthHintKey:@16,// 位深
AVEncoderAudioQualityKey:@(AVAudioQualityMedium),// 錄音質量
};
NSError *error;
self.recorder = [[AVAudioRecorder alloc] initWithURL:fileUrl settings:settings error:&error];
if(self.recorder){
self.recorder.delegate = self;
self.recorder.meteringEnabled = YES;
[self.recorder prepareToRecord];
}else {
NSLog(@"[AVAudioRecorder alloc] error:%@",[error localizedDescription]);
}
}
return self;
}
init方法的創建錄制器,獲取 零時url 用于常見 錄制器,進行相應參數的設置和代理的設置,其中
self.recorder.meteringEnabled = YES;
表示可以獲取采集的語音分貝大小。
[self.recorder prepareToRecord];
準備錄制。
錄制,暫停,結束
- (BOOL)record {
return [self.recorder record];
}
- (void)pause {
[self.recorder pause];
}
- (void)stop{
[self.recorder stop];
}
錄音結束,保存錄音
// 停止
- (void)stopWithCompletionHandler:(JWDRecordingStopCompletionHandler)stopHandler {
self.stopHandler = stopHandler;
[self stop];
}
// 保存
- (void)saveRecordingWithName:(NSString *)name
completionHandler:(JWDRecordingSaveCompletionHandler)saveHandler {
NSString *topath = [self docunmentsDirectoryWithName:name];
NSURL *toUrl = [NSURL fileURLWithPath:topath];
NSURL *atUrl = self.recorder.url;
NSError *error;
BOOL isSuccess = [[NSFileManager defaultManager] copyItemAtURL:atUrl toURL:toUrl error:&error];
if (isSuccess) {
saveHandler(YES,[JWDRecorderModel memoWithTitle:name url:toUrl]);
} else {
saveHandler(NO,error);
}
}
- (NSString *)docunmentsDirectoryWithName:(NSString *)name {
NSTimeInterval timeSatmp = [NSDate timeIntervalSinceReferenceDate];
NSString *filename = [NSString stringWithFormat:@"%@-%f.caf",name,timeSatmp];
NSString *docsdir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
return [docsdir stringByAppendingPathComponent:filename];
}
如果錄音結束也可以在下面代理方法里面進行需要的操做,只是時機有前后之分罷了。
// 錄制結束
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag {
NSLog(@"audioRecorderDidFinishRecording");
}
獲取分貝
獲取的分貝有平均分貝和最高分貝,可以視情況而定,自己需要什么就搞什么,但是有一個轉換。因為獲取的分貝數值為10的對數,所以需要轉換成 0~1之間的數,便于外界使用。
- (double)getLevelRecoder {
[self.recorder updateMeters];
float peak = [self.recorder peakPowerForChannel:0];
float average = [self.recorder averagePowerForChannel:0];
NSLog(@"最高 分貝 %f, 平均 %f",peak,average);
double peaklowPassResults = pow(10, (0.05 * peak));
double averagelowPassResults = pow(10, (0.05 * average));
NSLog(@"peaklowPassResults%lf,averagelowPassResults%lf",peaklowPassResults,averagelowPassResults);
return peaklowPassResults;
}
點擊開始播放
- (void)playRecodeWithMoedl:(JWDRecorderModel *)model {
[self.player stop];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:model.url error:nil];
if (self.player) {
[self.player play];
}
}
小結
好了,重點的錄制類就這些東西。有幾個需要注意的,就是訪問權限和播放器時一樣需要申請用戶開啟訪問權限,這個剛開始會忽略掉。
有的app需要跳轉去設置里面打開,而這個跳轉蘋果只有一次操作機會的實現,后面介紹,在工作項目中遇到的這個坑,以及授權的一些坑。
最后上demo地址,歡迎交流
demo地址