亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS使用音頻處理框架The Amazing Audio Engine實現音頻錄制播放

2020-07-26 02:20:14
字體:
來源:轉載
供稿:網友

iOS 第三方音頻框架The Amazing Audio Engine使用,實現音頻錄制、播放,可設置配樂。

首先看一下效果圖:

下面貼上核心控制器代碼:

#import "ViewController.h"#import <AVFoundation/AVFoundation.h>#import "HWProgressHUD.h"#import "UIImage+HW.h"#import "AERecorder.h"#import "HWRecordingDrawView.h" #define KMainW [UIScreen mainScreen].bounds.size.width#define KMainH [UIScreen mainScreen].bounds.size.height @interface ViewController () @property (nonatomic, strong) AERecorder *recorder;@property (nonatomic, strong) AEAudioController *audioController;@property (nonatomic, strong) AEAudioFilePlayer *player;@property (nonatomic, strong) AEAudioFilePlayer *backgroundPlayer;@property (nonatomic, strong) NSTimer *timer;@property (nonatomic, strong) NSMutableArray *soundSource;@property (nonatomic, weak) HWRecordingDrawView *recordingDrawView;@property (nonatomic, weak) UILabel *recLabel;@property (nonatomic, weak) UILabel *recordTimeLabel;@property (nonatomic, weak) UILabel *playTimeLabel;@property (nonatomic, weak) UIButton *auditionBtn;@property (nonatomic, weak) UIButton *recordBtn;@property (nonatomic, weak) UISlider *slider;@property (nonatomic, copy) NSString *path; @end @implementation ViewController - (AEAudioController *)audioController{ if (!_audioController) { _audioController = [[AEAudioController alloc] initWithAudioDescription:[AEAudioController nonInterleavedFloatStereoAudioDescription] inputEnabled:YES]; _audioController.preferredBufferDuration = 0.005; _audioController.useMeasurementMode = YES; }  return _audioController;} - (NSMutableArray *)soundSource{ if (!_soundSource) { _soundSource = [NSMutableArray array]; }  return _soundSource;} - (void)viewDidLoad { [super viewDidLoad];  [self creatControl];} - (void)creatControl{ CGFloat marginX = 30.0f;  //音頻視圖 HWRecordingDrawView *recordingDrawView = [[HWRecordingDrawView alloc] initWithFrame:CGRectMake(marginX, 80, KMainW - marginX * 2, 100)]; [self.view addSubview:recordingDrawView]; _recordingDrawView = recordingDrawView;  //REC UILabel *recLabel = [[UILabel alloc] initWithFrame:CGRectMake(marginX, CGRectGetMaxY(recordingDrawView.frame) + 20, 80, 40)]; recLabel.text = @"REC"; recLabel.textColor = [UIColor redColor]; [self.view addSubview:recLabel]; _recLabel = recLabel;  //錄制時間 UILabel *recordTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(recLabel.frame) + 20, CGRectGetMinY(recLabel.frame), 150, 40)]; recordTimeLabel.text = @"錄制時長:00:00"; [self.view addSubview:recordTimeLabel]; _recordTimeLabel = recordTimeLabel;  //播放時間 UILabel *playTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMinX(recordTimeLabel.frame), CGRectGetMaxY(recordTimeLabel.frame), 150, 40)]; playTimeLabel.text = @"播放時長:00:00"; playTimeLabel.hidden = YES; [self.view addSubview:playTimeLabel]; _playTimeLabel = playTimeLabel;  //配樂按鈕 NSArray *titleArray = @[@"無配樂", @"夏天", @"陽光海灣"]; CGFloat btnW = 80.0f; CGFloat padding = (KMainW - marginX * 2 - btnW * titleArray.count) / (titleArray.count - 1); for (int i = 0; i < titleArray.count; i++) { CGFloat btnX = marginX + (btnW + padding) * i; UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(btnX, CGRectGetMaxY(playTimeLabel.frame) + 20, btnW, btnW)]; [btn setTitle:titleArray[i] forState:UIControlStateNormal]; btn.layer.cornerRadius = btnW * 0.5; btn.layer.masksToBounds = YES; [btn setBackgroundImage:[UIImage imageWithColor:[UIColor grayColor]] forState:UIControlStateNormal]; [btn setBackgroundImage:[UIImage imageWithColor:[UIColor orangeColor]] forState:UIControlStateSelected]; if (i == 0) btn.selected = YES; btn.tag = 100 + i; [btn addTarget:self action:@selector(changeBackgroundMusic:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn]; }  //配樂音量 UILabel *backgroundLabel = [[UILabel alloc] initWithFrame:CGRectMake(marginX + 10, CGRectGetMaxY(playTimeLabel.frame) + 120, 80, 40)]; backgroundLabel.text = @"配樂音量"; [self.view addSubview:backgroundLabel];  //配樂音量 UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(CGRectGetMaxX(backgroundLabel.frame) + 10, CGRectGetMinY(backgroundLabel.frame), 210, 40)]; slider.value = 0.4f; [slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged]; [self.view addSubview:slider]; _slider = slider;  //試聽按鈕 UIButton *auditionBtn = [[UIButton alloc] initWithFrame:CGRectMake(marginX, KMainH - 150, 120, 80)]; auditionBtn.hidden = YES; auditionBtn.backgroundColor = [UIColor blackColor]; [auditionBtn setTitle:@"試聽" forState:UIControlStateNormal]; [auditionBtn setTitle:@"停止" forState:UIControlStateSelected]; [auditionBtn addTarget:self action:@selector(auditionBtnOnClick:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:auditionBtn]; _auditionBtn = auditionBtn;  //錄音按鈕 UIButton *recordBtn = [[UIButton alloc] initWithFrame:CGRectMake(KMainW - marginX - 120, KMainH - 150, 120, 80)]; recordBtn.backgroundColor = [UIColor blackColor]; [recordBtn setTitle:@"開始" forState:UIControlStateNormal]; [recordBtn setTitle:@"暫停" forState:UIControlStateSelected]; [recordBtn addTarget:self action:@selector(recordBtnOnClick:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:recordBtn]; _recordBtn = recordBtn;} //配樂按鈕點擊事件- (void)changeBackgroundMusic:(UIButton *)btn{ //更新選中狀態 for (int i = 0; i < 3; i++) { UIButton *button = (UIButton *)[self.view viewWithTag:100 + i]; button.selected = NO; } btn.selected = YES;  //移除之前配樂 if (_backgroundPlayer) { [_audioController removeChannels:@[_backgroundPlayer]]; _backgroundPlayer = nil; }  NSURL *url; if (btn.tag == 100) { return; }else if (btn.tag == 101) { url = [[NSBundle mainBundle]URLForResource:@"夏天.mp3" withExtension:nil]; }else if (btn.tag == 102) { url = [[NSBundle mainBundle]URLForResource:@"陽光海灣.mp3" withExtension:nil]; } [self.audioController start:NULL];  NSError *AVerror = NULL; _backgroundPlayer = [AEAudioFilePlayer audioFilePlayerWithURL:url error:&AVerror]; _backgroundPlayer.volume = _slider.value; _backgroundPlayer.loop = YES; if (!_backgroundPlayer) { [[[UIAlertView alloc] initWithTitle:@"Error"     message:[NSString stringWithFormat:@"Couldn't start playback: %@", [AVerror localizedDescription]]     delegate:nil    cancelButtonTitle:nil    otherButtonTitles:@"OK", nil] show]; return; }  //放完移除 _backgroundPlayer.removeUponFinish = YES; __weak ViewController *weakSelf = self; _backgroundPlayer.completionBlock = ^{ weakSelf.backgroundPlayer = nil; }; [_audioController addChannels:@[_backgroundPlayer]];} //配樂音量slider滑動事件- (void)sliderValueChanged:(UISlider *)slider{ if (_backgroundPlayer) _backgroundPlayer.volume = slider.value;} //錄音按鈕點擊事件- (void)recordBtnOnClick:(UIButton *)btn{ [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) { if (granted) {  //用戶同意獲取麥克風  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.1f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{  btn.selected = !btn.selected;    if (btn.selected) {   [self startRecord];  }else {   [self finishRecord];  }  });   }else {  //用戶不同意獲取麥克風  [HWProgressHUD showMessage:@"需要訪問您的麥克風,請在“設置-隱私-麥克風”中允許訪問。" duration:3.f]; } }];} //開始錄音- (void)startRecord{ _auditionBtn.hidden = YES; [self.audioController start:NULL]; _recorder = [[AERecorder alloc] initWithAudioController:_audioController]; _path = [self getPath];  NSError *error = NULL; if ( ![_recorder beginRecordingToFileAtPath:_path fileType:kAudioFileM4AType error:&error] ) { [[[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Couldn't start recording: %@", [error localizedDescription]] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show]; _recorder = nil; return; }  [self.soundSource removeAllObjects]; [self removeTimer]; [self addRecordTimer];  [_audioController addOutputReceiver:_recorder]; [_audioController addInputReceiver:_recorder];} //結束錄音- (void)finishRecord{ _auditionBtn.hidden = NO; _recLabel.hidden = NO; [self removeTimer];  [_recorder finishRecording]; [_audioController removeOutputReceiver:_recorder]; [_audioController removeInputReceiver:_recorder]; _recorder = nil;} //添加錄音定時器- (void)addRecordTimer{ self.timer = [NSTimer scheduledTimerWithTimeInterval:.2f target:self selector:@selector(recordTimerAction) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];} //錄音定時器事件- (void)recordTimerAction{ //獲取音頻 [CATransaction begin]; [CATransaction setDisableActions:YES]; Float32 inputAvg, inputPeak, outputAvg, outputPeak; [_audioController inputAveragePowerLevel:&inputAvg peakHoldLevel:&inputPeak]; [_audioController outputAveragePowerLevel:&outputAvg peakHoldLevel:&outputPeak]; [self.soundSource insertObject:[NSNumber numberWithFloat:(inputPeak + 18) * 2.8] atIndex:0]; [CATransaction commit]; _recordingDrawView.pointArray = _soundSource;  //REC閃動 _recLabel.hidden = (int)[self.recorder currentTime] % 2 == 1 ? YES : NO;  //錄音時間 NSString *str = [self strWithTime:[self.recorder currentTime] interval:0.5f]; if ([str intValue] < 0) str = @"錄制時長:00:00"; [self.recordTimeLabel setText:[NSString stringWithFormat:@"錄制時長:%@", str]];} //移除定時器- (void)removeTimer{ [self.timer invalidate]; self.timer = nil;} //試聽按鈕點擊事件- (void)auditionBtnOnClick:(UIButton *)btn{ btn.selected = !btn.selected;  if (btn.selected) { [self playRecord]; }else { [self stopPlayRecord]; }} //播放錄音- (void)playRecord{ //更新界面 _recordBtn.hidden = YES; [_playTimeLabel setText:@"播放時長:00:00"]; _playTimeLabel.hidden = NO;  //取消背景音樂 [self changeBackgroundMusic:(UIButton *)[self.view viewWithTag:100]];  if (![[NSFileManager defaultManager] fileExistsAtPath:_path]) return;  NSError *error = nil; _player = [AEAudioFilePlayer audioFilePlayerWithURL:[NSURL fileURLWithPath:_path] error:&error]; if (!_player) { [[[UIAlertView alloc] initWithTitle:@"Error"     message:[NSString stringWithFormat:@"Couldn't start playback: %@", [error localizedDescription]]     delegate:nil    cancelButtonTitle:nil    otherButtonTitles:@"OK", nil] show]; return; }  [self addPlayTimer]; _player.removeUponFinish = YES;  __weak ViewController *weakSelf = self; _player.completionBlock = ^{ weakSelf.player = nil; weakSelf.auditionBtn.selected = NO; [weakSelf stopPlayRecord]; }; [self.audioController start:NULL]; [self.audioController addChannels:@[_player]];} //停止播放錄音- (void)stopPlayRecord{ _recordBtn.hidden = NO; _playTimeLabel.hidden = YES; [self removeTimer]; if (_player) [_audioController removeChannels:@[_player]];} //添加播放定時器- (void)addPlayTimer{ self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(playTimerAction) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];} //播放定時器事件- (void)playTimerAction{ //播放時間 NSString *str = [self strWithTime:[_player currentTime] interval:1.f]; if ([str intValue] < 0) str = @"播放時長:00:00"; [_playTimeLabel setText:[NSString stringWithFormat:@"播放時長:%@", str]];} //錄制音頻沙盒路徑- (NSString *)getPath{ NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"YYYYMMddhhmmss"]; NSString *recordName = [NSString stringWithFormat:@"%@.wav", [formatter stringFromDate:[NSDate date]]]; NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:recordName];  return path;} //時長長度轉時間字符串- (NSString *)strWithTime:(double)time interval:(CGFloat)interval{ int minute = (time * interval) / 60; int second = (int)(time * interval) % 60;  return [NSString stringWithFormat:@"%02d:%02d", minute, second];} @end

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久国产精品| 91热福利电影| 日韩中文字在线| 日韩欧美高清视频| 精品福利在线观看| 欧美人与性动交| 亚洲成人a级网| 欧美黑人xxxx| 国产精品视频26uuu| 日韩av一区在线| 欧美视频一二三| 久久精品亚洲热| 日韩精品在线观看一区| 精品国产精品三级精品av网址| 亚洲aⅴ男人的天堂在线观看| 欧美小视频在线观看| 疯狂做受xxxx高潮欧美日本| 久久久久久这里只有精品| 国产91ⅴ在线精品免费观看| 亚洲欧美制服综合另类| 成人国产精品色哟哟| 国产精品免费在线免费| 日韩hd视频在线观看| 欧美成人精品在线视频| 91香蕉亚洲精品| 亚洲热线99精品视频| xxav国产精品美女主播| 97在线视频免费播放| 欧美视频不卡中文| 国产日韩欧美视频在线| 日韩国产高清视频在线| 精品偷拍各种wc美女嘘嘘| 国产精品一区二区久久精品| 国产99久久精品一区二区| 亚洲最大在线视频| 亚洲综合第一页| 欧美成人一区在线| 久久免费观看视频| 亚洲国产毛片完整版| 精品视频在线播放免| 欧美电影《睫毛膏》| 国产欧美精品va在线观看| 日韩av色在线| 亚洲男女自偷自拍图片另类| 日韩中文字幕欧美| 国产日韩精品在线| 国产精品日韩欧美| 亚洲天堂男人的天堂| 国自在线精品视频| 国产精品美女www爽爽爽视频| 亚洲影院污污.| 中文字幕v亚洲ⅴv天堂| 日韩精品久久久久| 成人精品在线视频| 91精品国产免费久久久久久| 国产一区二区三区在线免费观看| 成人有码在线播放| 国产亚洲精品久久久优势| www国产亚洲精品久久网站| 日韩中文在线视频| 96精品久久久久中文字幕| 国产精品久久久久国产a级| 久久九九全国免费精品观看| 日本aⅴ大伊香蕉精品视频| 亚洲国产精品va| 国语自产精品视频在线看一大j8| 欧美日韩另类在线| 韩国国内大量揄拍精品视频| 国产视频欧美视频| 国产精品久久久久久久久久免费| 国产欧美一区二区白浆黑人| 亚洲性生活视频| 日韩av中文字幕在线免费观看| 欧美极品在线播放| 国产精品一区二区久久精品| 日韩av在线免费播放| 91极品视频在线| 福利二区91精品bt7086| 欧美日韩亚洲视频一区| 久久久久久免费精品| 亚洲欧美在线一区| 91在线视频九色| 97视频在线观看视频免费视频| 9.1国产丝袜在线观看| 国产在线观看91精品一区| 日韩风俗一区 二区| 日韩久久免费电影| 91精品久久久久久久| 中文字幕日韩av综合精品| 亚洲人成电影网站色| 孩xxxx性bbbb欧美| 伊人伊人伊人久久| 亚洲天堂网在线观看| 亚洲另类欧美自拍| 亚洲日本中文字幕免费在线不卡| 亚洲a区在线视频| 色婷婷综合成人av| 97热在线精品视频在线观看| 欧美午夜激情小视频| 欧美激情综合亚洲一二区| 久久久久久久久久av| 91社区国产高清| 亚洲老头老太hd| 91精品久久久久久综合乱菊| 26uuu国产精品视频| 亚洲一区二区三区四区视频| 国产欧美中文字幕| 国产精品爽爽ⅴa在线观看| 日韩精品在线免费观看| 久久精品视频中文字幕| 国产精品女人久久久久久| 国产精品精品国产| 久久久91精品国产一区不卡| 国产成人精品久久久| 在线成人免费网站| zzijzzij亚洲日本成熟少妇| 91探花福利精品国产自产在线| 色爱精品视频一区| 亚洲a中文字幕| 国产精品国产三级国产专播精品人| 国产精品最新在线观看| 亚洲视频在线观看视频| 欧洲精品毛片网站| 中文欧美在线视频| 欧美日韩国产精品| 欧美巨乳在线观看| 国产精品久久久久aaaa九色| 色伦专区97中文字幕| 欧美性理论片在线观看片免费| 最好看的2019年中文视频| 日本成人在线视频网址| 国产日本欧美在线观看| 欧美性69xxxx肥| 国产z一区二区三区| 日本精品视频在线播放| 亚洲高清色综合| 国产一区二区在线免费视频| 亚洲性生活视频| 国产精品直播网红| 久久99国产精品久久久久久久久| 久久久中精品2020中文| 激情久久av一区av二区av三区| 午夜精品福利电影| 91精品国产高清久久久久久| 欧美亚洲伦理www| 成人免费看黄网站| 国产精品久久久久99| 97成人精品视频在线观看| 久久综合免费视频影院| 国产又爽又黄的激情精品视频| 亚洲自拍偷拍色图| 亚洲老司机av| 精品久久久久久久久久ntr影视| 中文字幕欧美精品日韩中文字幕| 91精品久久久久久久久| 日韩成人av在线播放| 国产中文字幕日韩| 狠狠躁夜夜躁人人爽天天天天97| 欧美成人免费在线视频| 92看片淫黄大片欧美看国产片| 久久精品美女视频网站| 国产99视频精品免视看7| 国产色综合天天综合网| 国语自产精品视频在线看一大j8|