//
|
// PBRecordingView.m
|
// IphoneBIMe
|
//
|
// Created by zjf on 2019/1/3.
|
// Copyright © 2019 ProBIM. All rights reserved.
|
//
|
|
#import "PBRecordingView.h"
|
#import <AVFoundation/AVFoundation.h>
|
#import "ConvertAudioFile.h"
|
#define ETRECORD_RATE 11025.0
|
|
@interface PBRecordingView()
|
//时间记录
|
@property (nonatomic, strong) UILabel *timeL;
|
//录音机
|
@property (nonatomic, strong) AVAudioRecorder *recorder;
|
//每秒60次
|
@property (nonatomic, strong) CADisplayLink *displayLink;
|
//录音计数
|
@property (nonatomic, assign) NSInteger recordingTimer;
|
@property (nonatomic, assign) NSInteger totalTime;
|
//录音路径
|
@property (nonatomic, copy) NSString *recordingCafPath;
|
//记录右侧按钮状态
|
@property (nonatomic, assign) BOOL isComplete;
|
@end
|
@implementation PBRecordingView
|
- (instancetype)initWithFrame:(CGRect)frame {
|
if (self = [super initWithFrame:frame]) {
|
[self setupUI];
|
}
|
return self;
|
}
|
- (void)setupUI {
|
self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3];
|
UIView *toolsView = [[UIView alloc] init];
|
toolsView.backgroundColor = [UIColor whiteColor];
|
toolsView.layer.cornerRadius = 10.0f;
|
[toolsView.layer setMasksToBounds:YES];
|
[self addSubview:toolsView];
|
[toolsView mas_makeConstraints:^(MASConstraintMaker *make) {
|
make.center.equalTo(self);
|
make.size.mas_equalTo(CGSizeMake(317, 166));
|
}];
|
|
UILabel *promptL = [UILabel z_labelWithText:@"提示:仅可上传一条语音,最多60秒" Color:TitleColor isBold:NO Font:14];
|
[self addSubview:promptL];
|
[promptL mas_makeConstraints:^(MASConstraintMaker *make) {
|
make.top.equalTo(toolsView).offset(20);
|
make.centerX.equalTo(toolsView);
|
make.height.equalTo(@20);
|
}];
|
|
UILabel *countdownL = [UILabel z_labelWithText:@"倒计时" Color:TitleColor isBold:NO Font:16];
|
[self addSubview:countdownL];
|
[countdownL mas_makeConstraints:^(MASConstraintMaker *make) {
|
make.left.equalTo(toolsView).offset(98);
|
make.top.equalTo(toolsView).offset(72);
|
make.size.mas_equalTo(CGSizeMake(57, 22));
|
}];
|
self.timeL = [UILabel z_labelWithText:@"60 S" Color:TitleColor isBold:YES Font:20];
|
[self addSubview:self.timeL];
|
[self.timeL mas_makeConstraints:^(MASConstraintMaker *make) {
|
make.centerY.equalTo(countdownL);
|
make.left.equalTo(countdownL.mas_right).offset(20);
|
make.height.equalTo(@28);
|
}];
|
UIView *linView = [[UIView alloc] init];
|
linView.backgroundColor = PBColor(208, 211, 218);
|
[self addSubview:linView];
|
[linView mas_makeConstraints:^(MASConstraintMaker *make) {
|
make.top.equalTo(toolsView).offset(115);
|
make.left.right.equalTo(toolsView);
|
make.height.equalTo(@1);
|
}];
|
UIView *lin2View = [[UIView alloc] init];
|
lin2View.backgroundColor = PBColor(208, 211, 218);
|
[self addSubview:lin2View];
|
[lin2View mas_makeConstraints:^(MASConstraintMaker *make) {
|
make.top.equalTo(linView.mas_bottom);
|
make.bottom.equalTo(toolsView);
|
make.centerX.equalTo(toolsView);
|
make.width.equalTo(@1);
|
}];
|
|
UIButton *cancelBtn = [UIButton z_textButton:@"取消" fontSize:20 normalColor:IndicatedColor];
|
[cancelBtn addTarget:self action:@selector(cancelInterAction) forControlEvents:UIControlEventTouchUpInside];
|
[self addSubview:cancelBtn];
|
[cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
make.top.equalTo(linView.mas_bottom);
|
make.left.bottom.equalTo(toolsView);
|
make.right.equalTo(lin2View.mas_left);
|
}];
|
|
UIButton *endBtn = [UIButton z_textButton:@"开始" fontSize:20 normalColor:IndicatedColor];
|
[endBtn addTarget:self action:@selector(endAction:) forControlEvents:UIControlEventTouchUpInside];
|
[self addSubview:endBtn];
|
[endBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
make.top.equalTo(linView.mas_bottom);
|
make.right.bottom.equalTo(toolsView);
|
make.left.equalTo(lin2View.mas_right);
|
}];
|
}
|
//定时器
|
- (void)updateMeters{
|
self.recordingTimer ++;
|
NSInteger seconds = self.recordingTimer / 60;
|
NSInteger countdown = self.totalTime - seconds;
|
if (countdown == 0) {
|
[self.recorder stop];
|
[self.displayLink invalidate];
|
[self cleanCafFile];
|
if (self.endRecordingBlock) {
|
NSString *mp3Path = [_recordingCafPath stringByReplacingOccurrencesOfString:@"caf" withString:@"mp3"];
|
self.endRecordingBlock([mp3Path lastPathComponent]);
|
}
|
[self removeFromSuperview];
|
}
|
self.timeL.text = [NSString stringWithFormat:@"%zd S",countdown];
|
}
|
- (void)cleanCafFile {
|
NSFileManager *fileManager=[NSFileManager defaultManager];
|
BOOL isDir = FALSE;
|
BOOL isDirExist = [fileManager fileExistsAtPath:_recordingCafPath isDirectory:&isDir];
|
if (isDirExist) {
|
[fileManager removeItemAtPath:_recordingCafPath error:nil];
|
}
|
}
|
- (void)cleanMp3File {
|
NSString *recordingMp3Path = [_recordingCafPath stringByReplacingOccurrencesOfString:@"caf" withString:@"mp3"];
|
NSFileManager *fileManager=[NSFileManager defaultManager];
|
BOOL isDir = FALSE;
|
BOOL isDirExist = [fileManager fileExistsAtPath:recordingMp3Path isDirectory:&isDir];
|
if (isDirExist) {
|
[fileManager removeItemAtPath:recordingMp3Path error:nil];
|
}
|
}
|
//取消录音
|
- (void)cancelInterAction {
|
if (self.isComplete) {
|
[self.recorder stop];
|
[self.displayLink invalidate];
|
[self cleanCafFile];
|
[self cleanMp3File];
|
}
|
[self removeFromSuperview];
|
}
|
|
// 开始/完成录音
|
- (void)endAction:(UIButton *)button {
|
if (self.isComplete) {
|
[self.recorder stop];
|
[[ConvertAudioFile sharedInstance] sendEndRecord];
|
[self.displayLink invalidate];
|
[self cleanCafFile];
|
if (self.endRecordingBlock) {
|
NSString *mp3Path = [_recordingCafPath stringByReplacingOccurrencesOfString:@"caf" withString:@"mp3"];
|
self.endRecordingBlock([mp3Path lastPathComponent]);
|
}
|
[self removeFromSuperview];
|
}else {
|
[button setTitle:@"完成" forState:UIControlStateNormal];
|
self.totalTime = 60;
|
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
|
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
|
[self.recorder record];
|
//转换MP3格式
|
[[ConvertAudioFile sharedInstance] conventToMp3WithCafFilePath:_recordingCafPath mp3FilePath:[_recordingCafPath stringByReplacingOccurrencesOfString:@"caf" withString:@"mp3"] sampleRate:ETRECORD_RATE];
|
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateMeters)];
|
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
|
self.isComplete = YES;
|
}
|
}
|
#pragma mark - 懒加载
|
- (AVAudioRecorder *)recorder {
|
if (_recorder == nil) {
|
NSDateFormatter * formatter = [[NSDateFormatter alloc ] init];
|
[formatter setDateFormat:@"YYYYMMddHHmmssSSS"];
|
NSString *date = [formatter stringFromDate:[NSDate date]];
|
NSString *recordingName = [NSString stringWithFormat:@"%@.caf",date];
|
|
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];
|
}
|
//设置录音输出路径
|
_recordingCafPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:recordingName];
|
NSLog(@"=======%@", _recordingCafPath);
|
|
// 2.录音参数设置
|
NSMutableDictionary *settingDictM = [NSMutableDictionary dictionary];
|
[settingDictM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
|
[settingDictM setObject:@(ETRECORD_RATE) forKey:AVSampleRateKey];
|
[settingDictM setObject:@(2) forKey:AVNumberOfChannelsKey];
|
[settingDictM setObject:@(16) forKey:AVLinearPCMBitDepthKey];
|
[settingDictM setObject:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];
|
|
//创建录音机
|
NSError *error=nil;
|
_recorder = [[AVAudioRecorder alloc]initWithURL:[NSURL fileURLWithPath:_recordingCafPath] settings:settingDictM error:&error];
|
// _recorder.delegate = self;
|
_recorder.meteringEnabled = YES;//如果要监控声波则必须设置为YES
|
[_recorder prepareToRecord];
|
if (error) {
|
NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription);
|
return nil;
|
}
|
}
|
return _recorder;
|
}
|
|
|
/*
|
// Only override drawRect: if you perform custom drawing.
|
// An empty implementation adversely affects performance during animation.
|
- (void)drawRect:(CGRect)rect {
|
// Drawing code
|
}
|
*/
|
|
@end
|