// // YOUPAILZRecordAudioView.m // VQU // // Created by CY on 2021/4/26. // Copyright © 2021 leo. All rights reserved. // #import "YOUPAILZRecordAudioView.h" #import "NSURL+TransferFileFormat.h" #import "YOUPAILZGameModel.h" @interface YOUPAILZRecordAudioView() @property (nonatomic, weak)UILabel *youpaiptimeL; @property (nonatomic, weak)UIButton *youpaipleftBtn; @property (nonatomic, weak)UIButton *youpaipcenterBtn; @property (nonatomic, weak)UIButton *youpaiprightBtn; /// 录制 @property (nonatomic, strong)AVAudioRecorder *youpaiprecorder; @property (nonatomic, strong)NSURL *youpaiprecordAudioUrl; /// 播放 @property (nonatomic, strong)AVAudioPlayer *youpaipaudioPlayer; @property (nonatomic, weak)UILabel *youpaipdescL; @property (nonatomic,strong)NSTimer *youpaiptimer; @property (nonatomic,assign)NSInteger youpaipaudioTime; @property (nonatomic,assign)NSInteger youpaipplayTime; @property (nonatomic,strong)YOUPAILZGameModel *youpaipgameModel; @end @implementation YOUPAILZRecordAudioView - (instancetype)initWithFrame:(CGRect)frame model:(YOUPAILZGameModel *)model{ if (self = [super initWithFrame:frame]) { self.youpaipgameModel = model; [self youpaifsetupUI]; self.youpaipstate = LZCaptrueAudioStateNone; } return self; } - (void)youpaifsetupUI{ UIButton *centerBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [centerBtn addTarget:self action:@selector(youpaifcenterBtnClick) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:centerBtn]; self.youpaipcenterBtn = centerBtn; [centerBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self); make.size.mas_offset(CGSizeMake(65.0f, 65.0f)); }]; UILabel *timeL = [[UILabel alloc] init]; timeL.font = LCFont15; timeL.textColor = HexColorFromRGB(0x999999); timeL.text = @"00:00"; [self addSubview:timeL]; self.youpaiptimeL = timeL; [timeL mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(centerBtn.mas_centerX); make.bottom.equalTo(centerBtn.mas_top).offset(-15.0f); }]; UILabel *descL = [[UILabel alloc] init]; descL.font = LCFont15; descL.textColor = HexColorFromRGB(0x999999); descL.text = @"点击录音"; [self addSubview:descL]; self.youpaipdescL = descL; [descL mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(centerBtn.mas_centerX); make.top.equalTo(centerBtn.mas_bottom).offset(15.0f); }]; UIButton *leftBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [leftBtn addTarget:self action:@selector(youpaifleftBtnClick) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:leftBtn]; self.youpaipleftBtn = leftBtn; [leftBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(centerBtn.mas_centerY); make.size.mas_offset(CGSizeMake(50.0f, 50.0f)); make.right.equalTo(centerBtn.mas_left).offset(-44.0f); }]; UIButton *rightBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [rightBtn addTarget:self action:@selector(youpaifrightBtnClick) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:rightBtn]; self.youpaiprightBtn = rightBtn; [rightBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(centerBtn.mas_centerY); make.size.mas_offset(CGSizeMake(50.0f, 50.0f)); make.left.equalTo(centerBtn.mas_right).offset(44.0f); }]; } - (void)youpaifleftBtnClick{ [self youpaifstopTimer]; self.youpaipstate = LZCaptrueAudioStateNone; self.youpaiprecordAudioUrl = nil; self.youpaiprecorder = nil; // 停止播放 [self.youpaipaudioPlayer stop]; self.youpaipaudioPlayer = nil; } - (void)youpaifcenterBtnClick{ if(self.youpaipstate == LZCaptrueAudioStateNone){ self.youpaipstate = LZCaptrueAudioStateStart; //创建录音通道 [self setAudioSession]; // 开始录音 [self.youpaiprecorder record]; // 检查权限 [self youpaifsetupAuthority]; self.youpaipaudioTime = 0; [self youpaifstartTimer]; }else if(self.youpaipstate == LZCaptrueAudioStateFinish){ self.youpaipstate = LZCaptrueAudioStatePlay; // UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback; // AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory); UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride); AVAudioSession * session = [AVAudioSession sharedInstance]; [session setActive:YES error:nil]; [session setCategory:AVAudioSessionCategoryPlayback error:nil]; NSError *error; self.youpaipaudioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:self.youpaiprecordAudioUrl error:&error]; if (error) { NSLog(@"%@",error); } self.youpaipaudioPlayer.delegate = self; // 播放 [self.youpaipaudioPlayer play]; self.youpaipplayTime = self.youpaipaudioTime; [self youpaifstartTimer]; }else if (self.youpaipstate == LZCaptrueAudioStatePlay){ self.youpaipstate = LZCaptrueAudioStateFinish; // 停止播放 [self.youpaipaudioPlayer stop]; self.youpaipaudioPlayer = nil; [self youpaifstopTimer]; }else if (self.youpaipstate == LZCaptrueAudioStateStart){ self.youpaipstate = LZCaptrueAudioStateFinish; // 停止录制 [self.youpaiprecorder stop]; self.youpaiprecorder = nil; [self youpaifstopTimer]; } } - (void)youpaifrightBtnClick{ self.youpaipstate = LZCaptrueAudioStateSubmit; [self youpaifstopTimer]; // 停止播放 [self.youpaipaudioPlayer stop]; self.youpaipaudioPlayer = nil; self.youpaipgameModel.youpaipaudioUrl = [self.youpaiprecordAudioUrl transformCAFToMP3]; self.youpaipgameModel.youpaipaudioDuration = self.youpaipaudioTime; self.youpaiprecorder = nil; self.youpaiprecordAudioUrl = nil; } - (void)setYoupaipstate:(LZCaptrueAudioState)state{ _youpaipstate = state; NSString *time = @""; NSString *desc = @""; self.youpaipleftBtn.hidden = YES; self.youpaiprightBtn.hidden = YES; UIImage *centerImg = nil; UIImage *leftImg = nil; UIImage *rightImg = nil; switch (state) { case LZCaptrueAudioStateNone:{ time = @"00:00"; desc = @"点击录音"; centerImg = [UIImage imageNamed:@"vqu_images_H_game_audio_none1"]; } break; case LZCaptrueAudioStateStart:{ time = @"00:00"; desc = @"点击结束录音"; centerImg = [UIImage imageNamed:@"vqu_images_game_audio_start"]; } break; case LZCaptrueAudioStateFinish:{ time = [self youpaiftimeFormatted:self.youpaipaudioTime]; desc = @"点击试听"; centerImg = [UIImage imageNamed:@"vqu_images_game_audio_finish"]; leftImg = [UIImage imageNamed:@"vqu_images_game_audio_re_record"]; rightImg = [UIImage imageNamed:@"vqu_images_game_audio_submit"]; self.youpaipleftBtn.hidden = NO; self.youpaiprightBtn.hidden = NO; } break; case LZCaptrueAudioStatePlay:{ time = [self youpaiftimeFormatted:self.youpaipaudioTime]; desc = @"播放中"; centerImg = [UIImage imageNamed:@"vqu_images_H_game_audio_play1"]; leftImg = [UIImage imageNamed:@"vqu_images_game_audio_re_record"]; rightImg = [UIImage imageNamed:@"vqu_images_game_audio_submit"]; self.youpaipleftBtn.hidden = NO; self.youpaiprightBtn.hidden = NO; } break; case LZCaptrueAudioStateSubmit:{ time = [self youpaiftimeFormatted:self.youpaipaudioTime]; desc = @"已录制"; centerImg = [UIImage imageNamed:@"vqu_images_game_audio_success"]; } break; default: break; } self.youpaiptimeL.text = time; self.youpaipdescL.text = desc; [self.youpaipleftBtn setBackgroundImage:leftImg forState:UIControlStateNormal]; [self.youpaiprightBtn setBackgroundImage:rightImg forState:UIControlStateNormal]; [self.youpaipcenterBtn setBackgroundImage:centerImg forState:UIControlStateNormal]; } #pragma mark - AVAudioPlayerDelegate - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ self.youpaipstate = LZCaptrueAudioStateFinish; // 停止播放 [self.youpaipaudioPlayer stop]; self.youpaipaudioPlayer = nil; [self youpaifstopTimer]; } - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{ self.youpaipstate = LZCaptrueAudioStateFinish; // 停止播放 [self.youpaipaudioPlayer stop]; self.youpaipaudioPlayer = nil; [self youpaifstopTimer]; } - (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{ self.youpaipstate = LZCaptrueAudioStateFinish; // 停止播放 [self.youpaipaudioPlayer stop]; self.youpaipaudioPlayer = nil; [self youpaifstopTimer]; } #pragma mark - AVAudioRecorderDelegate - (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError * _Nullable)error{ self.youpaipstate = LZCaptrueAudioStateFinish; // 停止录制 [self.youpaiprecorder stop]; self.youpaiprecorder = nil; [self youpaifstopTimer]; } - (void)audioRecorderBeginInterruption:(AVAudioRecorder *)recorder{ self.youpaipstate = LZCaptrueAudioStateFinish; // 停止录制 [self.youpaiprecorder stop]; self.youpaiprecorder = nil; [self youpaifstopTimer]; } // 开始计时 - (void)youpaifstartTimer{ self.youpaiptimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(youpaiftimerAction) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:self.youpaiptimer forMode:NSRunLoopCommonModes]; } // 结束计时 - (void)youpaifstopTimer{ [self.youpaiptimer invalidate]; self.youpaiptimer = nil; self.youpaiptimeL.text = [self youpaiftimeFormatted:self.youpaipaudioTime]; } - (void)youpaiftimerAction{ if (self.youpaipstate == LZCaptrueAudioStateStart) { self.youpaipaudioTime ++; self.youpaiptimeL.text = [self youpaiftimeFormatted:self.youpaipaudioTime]; if (self.youpaipaudioTime >= kAudioMaxDuration) { self.youpaipstate = LZCaptrueAudioStateFinish; // 停止录制 [self.youpaiprecorder stop]; self.youpaiprecorder = nil; [self youpaifstopTimer]; } }else if (self.youpaipstate == LZCaptrueAudioStatePlay){ self.youpaipplayTime --; self.youpaiptimeL.text = [self youpaiftimeFormatted:self.youpaipplayTime]; } } - (NSString *)youpaiftimeFormatted:(NSInteger)totalSeconds{ NSInteger seconds = totalSeconds % 60; NSInteger minutes = (totalSeconds / 60); return [NSString stringWithFormat:@"%02ld:%02ld", minutes, seconds]; } /// 视频本地url路径 - (NSURL *)youpaiprecordAudioUrl{ if (!_youpaiprecordAudioUrl) { NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) lastObject]; NSString *fileName = @"audioVerify.caf"; _youpaiprecordAudioUrl = [NSURL fileURLWithPath:[path stringByAppendingPathComponent:fileName]]; if ([[NSFileManager defaultManager] fileExistsAtPath:_youpaiprecordAudioUrl.resourceSpecifier]){ [[NSFileManager defaultManager] removeItemAtPath:_youpaiprecordAudioUrl.resourceSpecifier error:nil]; } } return _youpaiprecordAudioUrl; } - (AVAudioRecorder *)youpaiprecorder{ if (_youpaiprecorder == nil) { //创建录音机 NSError *error=nil; _youpaiprecorder = [[AVAudioRecorder alloc] initWithURL:self.youpaiprecordAudioUrl settings:[self getAudioSetting] error:&error]; _youpaiprecorder.delegate = self; if (error) { NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription); return nil; } } return _youpaiprecorder; } /** * 取得录音文件设置 * * @return 录音设置 */ -(NSDictionary *)getAudioSetting{ NSDictionary *recordSetting = @{ AVFormatIDKey : @(kAudioFormatLinearPCM), AVSampleRateKey : @(44100), AVNumberOfChannelsKey : @(2), AVLinearPCMBitDepthKey : @(16), AVLinearPCMIsNonInterleaved : @NO, AVLinearPCMIsFloatKey : @NO, AVLinearPCMIsBigEndianKey : @NO, }; return recordSetting; } /// 权限 - (void)youpaifsetupAuthority{ [UCAuthorityManager microPhoneAuthority:^{ } denied:^{ [self youpaifshowAlertVCWithTitle:@"请在iphone的“设置-隐私-麦克风”选项中,允许APP访问您的麦克风。"]; }]; } - (void)youpaifshowAlertVCWithTitle:(NSString *)title{ UIAlertController *systemAlert = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"现在去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){ if ([[UIDevice currentDevice].systemVersion floatValue] < 10.0) { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; } else { // 去系统设置页面 if (@available(iOS 10.0, *)) { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil]; } else { // Fallback on earlier versions } } }]; UIAlertAction *action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]; [systemAlert addAction:cancelAction]; [systemAlert addAction:action]; dispatch_async(dispatch_get_main_queue(), ^{ [[LCTools getCurrentVC] presentViewController: systemAlert animated: YES completion: nil]; }); } - (void)setAudioSession{ AVAudioSession *session = [AVAudioSession sharedInstance]; NSError *sessionError; [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError]; if(session == nil){ NSLog(@"Error creating session: %@", [sessionError description]); } else{ [session setActive:YES error:nil]; } } - (void)dealloc{ [self youpaifstopTimer]; self.youpaiprecordAudioUrl = nil; self.youpaiprecorder = nil; // 停止播放 [self.youpaipaudioPlayer stop]; self.youpaipaudioPlayer = nil; } @end