項目中有面部認證、聲紋認證,服務器端要求上傳wav格式的音頻,所以寫了這樣一個小demo。
剛剛開始寫博客還不知道怎么上傳代碼,就復制了,嘻嘻
DotimeManage.h
@class DotimeManage;
@protocol DotimeManageDelegate <NSObject>
- (void)TimerActionValueChange:(int)time; //時間改變
@end
#import <Foundation/Foundation.h>
@interface DotimeManage : NSObject
{
? ? NSTimer *BBtimer;
}
@property (nonatomic)int timeValue;
@property (nonatomic,assign)id<DotimeManageDelegate> delegate;
+ (DotimeManage *)DefaultManage;
//開始計時
- (void)startTime;
//停止計時
- (void)stopTimer;
@end
DotimeManage.m
#import "DotimeManage.h"
@implementation DotimeManage
static DotimeManage *timeManage = nil;
+ (DotimeManage *)DefaultManage{
? ? static dispatch_once_t onceToken;
? ? dispatch_once(&onceToken, ^{
? ? ? ? timeManage = [[DotimeManage alloc] init];
? ? });
? ? return timeManage;
}
- (id)init {
? ? self = [super init];
? ? if (self) {
? ? }
? ? return self;
}
//開始計時
- (void)startTime {
? ? //停止上次計時器
? ? [self stopTimer];
?? ?
? ? if (BBtimer == nil) {
? ? ? ? self.timeValue = 0;
? ? ? ? BBtimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(TimerAction) userInfo:nil repeats:YES];
? ? ? ? NSRunLoop *main=[NSRunLoop currentRunLoop];
? ? ? ? [main addTimer:BBtimer forMode:NSRunLoopCommonModes];
? ? }
}
//停止計時
- (void)stopTimer {
? ? if (BBtimer != nil) {
? ? ? ? [BBtimer invalidate];
? ? ? ? BBtimer = nil;
? ? }
}
//倒計時
- (void)TimerAction {
? ? self.timeValue ++;
? ? if ([self.delegate respondsToSelector:@selector(TimerActionValueChange:)]) {
? ? ? ? [self.delegate TimerActionValueChange:self.timeValue];
? ? }
}
@end
Recorder.h
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#import <UIKit/UIKit.h>
#define DefaultSubPath @"Voice" //默認 二級目錄 可以修改自己想要的 例如 "文件夾1/文件夾2/文件夾3"
#define SampleRateKey 44100.0 //采樣率8000.0
#define LinearPCMBitDepth 16 //采樣位數 默認 16
#define NumberOfChannels 1? //通道的數目
@protocol RecorderDelegate <NSObject>
/**
?* 錄音進行中
?* currentTime 錄音時長
?**/
-(void)recorderCurrentTime:(NSTimeInterval)currentTime;
/**
?* 錄音完成
?* filePath 錄音文件保存路徑
?* fileName 錄音文件名
?* duration 錄音時長
?**/
-(void)recorderStop:(NSString *)filePath voiceName:(NSString *)fileName duration:(NSTimeInterval)duration;
/**
?* 開始錄音
?**/
-(void)recorderStart;
@end
@interface Recorder : NSObject<AVAudioRecorderDelegate>
@property (assign, nonatomic) id<RecorderDelegate> recorderDelegate;
@property(strong, nonatomic) NSString *filename,*filePath;
/**
?* 錄音控件 單例對象
?**/
+(Recorder *)shareRecorder;
/**
?* 開始錄音
?* //默認的錄音存儲的文件夾在 "Document/Voice/文件名(文件名示例: 2015-01-06_12:41).wav"
?* 錄音的文件名 "2015-01-06_12:41"
?**/
-(void)startRecord;
/**
?* 停止錄音
?**/
-(void)stopRecord;
/**
?* 獲得峰值
?**/
-(float)getPeakPower;
/**
?* 是否可以錄音
?**/
- (BOOL)canRecord;
@end
Recorder.m
#import "Recorder.h"
#ifdef DEBUG
#define VSLog(log, ...) NSLog(log, ## __VA_ARGS__)
#else
#define VSLog(log, ...)
#endif
#define IOS7 ? ( [[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending )
@interface Recorder ()
{
? ? NSMutableArray *cacheDelegates;
? ? NSMutableArray *cacheURLs;
? ? NSTimer ? ? *countDownTimer_;//定時器,每秒調用一次
}
@property(strong, nonatomic) AVAudioRecorder *audioRecorder;
@property(strong, nonatomic) NSMutableDictionary *cacheDic;
@end
@implementation Recorder
+(Recorder *)shareRecorder
{
? ? static Recorder *sharedRecorderInstance = nil;
? ? static dispatch_once_t predicate;
? ? dispatch_once(&predicate, ^{
? ? ? ? sharedRecorderInstance = [[self alloc] init];
? ? });
? ? return sharedRecorderInstance;
}
-(BOOL)canRecord
{
? ? __block BOOL bCanRecord = YES;
? ? if (IOS7)
? ? {
? ? ? ? AVAudioSession *audioSession = [AVAudioSession sharedInstance];
? ? ? ? if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {
? ? ? ? ? ? [audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
? ? ? ? ? ? ? ? if (granted) {
? ? ? ? ? ? ? ? ? ? bCanRecord = YES;
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? bCanRecord = NO;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }];
? ? ? ? }
? ? }
?? ?
? ? return bCanRecord;
}
-(id)init
{
? ? self = [super init];
? ? if (self) {
? ? ? ? self.cacheDic = [NSMutableDictionary dictionaryWithCapacity:1];
? ? ? ? cacheDelegates = [[NSMutableArray alloc] init];
? ? ? ? cacheURLs = [[NSMutableArray alloc] init];
? ? ? ? [self resetTimerCount];
? ? }
? ? return self;
}
-(void)stopTimerCountRun
{
? ? if (countDownTimer_) {
? ? ? ? [countDownTimer_ invalidate];
? ? ? ? countDownTimer_ = nil;
? ? }
}
-(void)resetTimerCount
{
? ? [self stopTimerCountRun];
? ? countDownTimer_ = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeCountDown) userInfo:nil repeats:YES];
? ? [[NSRunLoop currentRunLoop] addTimer:countDownTimer_ forMode:NSRunLoopCommonModes];
}
- (void)timeCountDown
{
? ? if (self.audioRecorder.isRecording) {
? ? ? ? //當前時間
? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderCurrentTime:)]) {
? ? ? ? ? ? [self.recorderDelegate recorderCurrentTime:self.audioRecorder.currentTime];
? ? ? ? }
? ? }
}
#pragma mark - 廣播停止錄音
//停止錄音
-(void)stopAVAudioRecord
{
?? ?
}
-(void)startRecordWithFilePath:(NSString *)filePath
{
?? ?
? ? AVAudioSession *session = [AVAudioSession sharedInstance];
?? ?
? ? [session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
? ? [session setActive:YES error:nil];
?? ?
? ? NSDictionary *recordSetting = [NSDictionary dictionaryWithObjectsAndKeys:
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [NSNumber numberWithFloat: SampleRateKey],AVSampleRateKey, //采樣率
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [NSNumber numberWithInt:LinearPCMBitDepth],AVLinearPCMBitDepthKey,//采樣位數 默認 16
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [NSNumber numberWithInt: NumberOfChannels], AVNumberOfChannelsKey,//通道的數目,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nil];
?? ?
?? ?
? ? NSURL *url = [NSURL fileURLWithPath:filePath];
? ? self.filePath = filePath;
?? ?
? ? NSError *error = nil;
? ? if (self.audioRecorder) {
? ? ? ? if (self.audioRecorder.isRecording) {
? ? ? ? ? ? [self.audioRecorder stop];
? ? ? ? }
? ? ? ? self.audioRecorder = nil;
? ? }
?? ?
? ? AVAudioRecorder *tmpRecord = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&error];
? ? self.audioRecorder = tmpRecord;
? ? self.audioRecorder.meteringEnabled = YES;
? ? self.audioRecorder.delegate = self;
? ? if ([self.audioRecorder prepareToRecord] == YES){
? ? ? ? self.audioRecorder.meteringEnabled = YES;
? ? ? ? [self.audioRecorder record];
? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStart)]) {
? ? ? ? ? ? [self.recorderDelegate recorderStart];
? ? ? ? }
? ? ? ? [[UIApplication sharedApplication] setIdleTimerDisabled: YES];//保持屏幕長亮
? ? ? ? [[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; //建議在播放之前設置yes,播放結束設置NO,這個功能是開啟紅外感應
?? ? ? ?
? ? }else {
? ? ? ? int errorCode = CFSwapInt32HostToBig ([error code]);
? ? ? ? VSLog(@"Error: %@ [%4.4s])" , [error localizedDescription], (char*)&errorCode);
?? ? ? ?
? ? }
}
-(void)startRecord
{
? ? NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSDocumentDirectory, NSUserDomainMask, YES);
? ? NSString *docsDir = [dirPaths objectAtIndex:0];
? ? //錄音文件名采用時間標記 例如"2015-01-06_12:41"
//? ? self.filename = [self createFilename];
? ? self.filename = @"RecordingFile";
? ? NSString *soundFilePath = [docsDir
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/%@.wav",DefaultSubPath,self.filename]];
?? ?
? ? [self createFilePath];
? ? [self startRecordWithFilePath:soundFilePath];
}
//創建錄音文件名字
- (NSString *)createFilename {
? ? NSDate *date_ = [NSDate date];
? ? NSDateFormatter *dateformater = [[NSDateFormatter alloc] init];
? ? [dateformater setDateFormat:@"yyyy-MM-dd_HH-mm-ss"];
? ? NSString *timeFileName = [dateformater stringFromDate:date_];
? ? return timeFileName;
}
//創建存儲路徑
-(void)createFilePath
{
? ? NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSDocumentDirectory, NSUserDomainMask, YES);
? ? NSString *docsDir = [dirPaths objectAtIndex:0];
? ? NSString *savedImagePath = [docsDir
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? stringByAppendingPathComponent:DefaultSubPath];
? ? BOOL isDir = NO;
? ? NSFileManager *fileManager = [NSFileManager defaultManager];
? ? BOOL existed = [fileManager fileExistsAtPath:savedImagePath isDirectory:&isDir];
? ? if ( !(isDir == YES && existed == YES) )
? ? {
? ? ? ? [fileManager createDirectoryAtPath:savedImagePath withIntermediateDirectories:YES attributes:nil error:nil];
? ? }
}
-(void)stopRecord
{
? ? if (self.audioRecorder) {
? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {
? ? ? ? ? ? [self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];
? ? ? ? }
? ? ? ? self.recorderDelegate = nil;
? ? ? ? [self.audioRecorder stop];
?? ? ? ?
? ? ? ? AVAudioSession *session = [AVAudioSession sharedInstance];
? ? ? ? [session setActive:NO error:nil];
? ? ? ? [session setCategory:AVAudioSessionCategoryAmbient error:nil];
? ? }
}
-(float)getPeakPower
{
? ? [self.audioRecorder updateMeters];
? ? float linear = pow (10, [self.audioRecorder peakPowerForChannel:0] / 20);
? ? float linear1 = pow (10, [self.audioRecorder averagePowerForChannel:0] / 20);
? ? float Pitch = 0;
? ? if (linear1>0.03) {
?? ? ? ?
? ? ? ? Pitch = linear1+.20;//pow (10, [audioRecorder averagePowerForChannel:0] / 20);//[audioRecorder peakPowerForChannel:0];
? ? }
? ? else {
?? ? ? ?
? ? ? ? Pitch = 0.0;
? ? }
? ? float peakPowerForChannel = (linear + 160)/160;
? ? return peakPowerForChannel;
}
//-(void)dealloc
//{
//? ? self.audioRecorder = nil;
//? ? [[NSNotificationCenter defaultCenter] removeObserver:self];
//? ? [super dealloc];
//}
//
#pragma mark -
#pragma mark AVAudioRecorderDelegate Methods
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
? ? [[UIApplication sharedApplication] setIdleTimerDisabled: NO];
? ? if (flag) {
? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {
? ? ? ? ? ? [self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];
? ? ? ? }
? ? ? ? self.recorderDelegate = nil;
? ? }else{
? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {
? ? ? ? ? ? [self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];
? ? ? ? }
? ? ? ? self.recorderDelegate = nil;
? ? }
? ? AVAudioSession *session = [AVAudioSession sharedInstance];
? ? [session setActive:NO error:nil];
? ? [session setCategory:AVAudioSessionCategoryAmbient error:nil];
}
-(void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error
{
? ? [[UIApplication sharedApplication] setIdleTimerDisabled: NO];
?? ?
? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {
? ? ? ? [self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];
? ? }
? ? self.recorderDelegate = nil;
? ? AVAudioSession *session = [AVAudioSession sharedInstance];
? ? [session setActive:NO error:nil];
? ? [session setCategory:AVAudioSessionCategoryAmbient error:nil];
}
@end
在需要錄制音頻的界面調用這兩個文件
錄制音頻的按鈕有兩個響應事件,代碼如下
[recordingBtn addTarget:self action:@selector(buttonSayBegin) forControlEvents:UIControlEventTouchDown];
? ? [recordingBtn addTarget:self action:@selector(buttonSayEnd) forControlEvents:UIControlEventTouchUpInside];
- (void)buttonSayBegin
{
? ? [self stopAudio];
?? ?
? ? [[Recorder shareRecorder]startRecord];
??
}
- (void)buttonSayEnd
{ ? ?
? ? [[Recorder shareRecorder]stopRecord];
?? ?
? ? [self stopAudio];
?? ?
? ? //? ? [StateLable setText:@"播放錄音文件中。。"];
? ? NSString * string = [Recorder shareRecorder].filePath;
? ? [self playAudio:string];
}
//播放
- (void)playAudio:(NSString *)path {
? ? NSURL *url = [NSURL URLWithString:path];
? ? NSError *err = nil;
? ? audioPalyer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
? ? audioPalyer.delegate = self;
? ? [audioPalyer prepareToPlay];
? ? [audioPalyer play];
}
//停止播放
- (void)stopAudio {
? ? if (audioPalyer) {
? ? ? ? [audioPalyer stop];
? ? ? ? audioPalyer = nil;
? ? }
}
- (void)playing
{
? ? if([audioPalyer isPlaying])
? ? {
? ? ? ? [audioPalyer pause];
? ? }
?? ?
? ? else
? ? {
? ? ? ? [audioPalyer play];
? ? }
}
#pragma mark -AVAudio 代理方法-
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
?
}