序文
オーディオとビデオの開発では、録音中のオーディオの変動を監視し、それらをビューに表示する必要があります。
効果
コード
- ViewController.m
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController () <AVAudioRecorderDelegate>
@property(nonatomic, strong) UILabel *recordCountLabel;
@property(nonatomic, strong) UIImageView *backImage;
@property(nonatomic, strong) UIButton *recordBtn;
//录音
@property(nonatomic, strong) AVAudioRecorder *audioRecorder;
@property(nonatomic, assign) NSInteger recorderTime;
@property(nonatomic, strong) dispatch_source_t timerForVoiceChange;
@property(nonatomic, copy) void(^AudioSpeakPowerBlock)(float power);
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setViewControllerUI];
}
- (void)setViewControllerUI {
[self.view addSubview:self.recordCountLabel];
[self.view addSubview:self.backImage];
[self.view addSubview:self.recordBtn];
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
self.recordCountLabel.frame = CGRectMake(0, 100, self.view.frame.size.width, 20);
self.recordBtn.frame = CGRectMake(0, 0, 68, 68);
self.recordBtn.center = self.view.center;
self.backImage.frame = CGRectMake(0, 0, 68, 68);
self.backImage.center = self.view.center;
}
- (UILabel *)recordCountLabel {
if(_recordCountLabel == nil) {
_recordCountLabel = [[UILabel alloc]init];
_recordCountLabel.text = @"0s";
_recordCountLabel.textColor = [UIColor grayColor];
_recordCountLabel.textAlignment = NSTextAlignmentCenter;
_recordCountLabel.font = [UIFont systemFontOfSize:18 weight:0.4];
[_recordCountLabel sizeToFit];
}
return _recordCountLabel;
}
- (UIButton *)recordBtn {
if(_recordBtn == nil) {
_recordBtn = [[UIButton alloc]init];
_recordBtn.layer.cornerRadius = 34;
_recordBtn.layer.masksToBounds = YES;
_recordBtn.backgroundColor = [UIColor blackColor];
[_recordBtn addTarget:self action:@selector(recordBtnClick:) forControlEvents:UIControlEventTouchUpInside];
}
return _recordBtn;
}
- (UIImageView *)backImage {
//背景波动
if(_backImage == nil) {
_backImage = [[UIImageView alloc]init];
_backImage.image = [UIImage imageNamed:@"123"];
}
return _backImage;
}
- (AVAudioRecorder *)audioRecorder {
if (_audioRecorder == nil) {
NSString *wavRecordFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.wav", @"123"]];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
[audioSession setActive:YES error:nil];
NSDictionary *recordSetting = @{
AVSampleRateKey : @8000.0, // 采样率
AVFormatIDKey : @(kAudioFormatLinearPCM), // 音频格式
AVLinearPCMBitDepthKey : @16, // 采样位数 默认 16
AVNumberOfChannelsKey : @1 // 通道的数目
};
_audioRecorder = [[AVAudioRecorder alloc] initWithURL:[NSURL URLWithString:wavRecordFilePath] settings:recordSetting error:nil];
_audioRecorder.delegate = self;
_audioRecorder.meteringEnabled = YES;
}
return _audioRecorder;
}
/*
0.录音
0.0 大于1秒
1.录制完毕
1.1 播放
1.2 删除
0.1 小于一秒重新录制
*/
#pragma mark - 录音
- (void)recordBtnClick:(UIButton *)sender {
//开始录音
sender.selected = !sender.isSelected;
__weak typeof(self) weakSelf = self;
if(sender.isSelected) {
//正在录音
[self.audioRecorder prepareToRecord];
[self.audioRecorder record];
[self __createPickSpeakPowerTimer];
[self setAudioSpeakPowerBlock:^(float ff) {
weakSelf.recordCountLabel.text = [NSString stringWithFormat:@"%lds", (long)weakSelf.audioRecorder.currentTime];
float level = (ff + 37.5) * 0.5;//(ff + 37.5) * 3.2;
if( level < 0 ) {
level = 0;
}
//NSLog(@"level%f",level);
CGFloat rate = (1 + level * 0.1);
if(rate >= 1.45) {
rate = 1.45;
}
NSLog(@"rate %f",rate);
//方法1
[UIView animateWithDuration:0.1 animations:^{
weakSelf.backImage.transform = CGAffineTransformMakeScale(rate, rate);
}];
//方法2
}];
} else {
//结束录音
dispatch_source_cancel(_timerForVoiceChange);
if(self.audioRecorder.currentTime < 1.0f) {
//时间小于1秒
[self __setRebeginRecord];
weakSelf.recordCountLabel.text = @"Time Too Short";
} else {
NSInteger second = (self.audioRecorder.currentTime * 100 + 0.5) / 100;
_recorderTime = second;
[self __setRecordSucess];
self.recordCountLabel.text = [NSString stringWithFormat:@"%lds",(long)second];
}
self.backImage.transform = CGAffineTransformMakeScale(1.0,1.0);
[self.audioRecorder stop];
//恢复外部音乐
[[AVAudioSession sharedInstance] setActive:NO
withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
error:nil];
//方法2
UIView *findLabel = [self.view viewWithTag:10001];
[findLabel removeFromSuperview];
}
}
#pragma mark - private method
- (void)__setRecordSucess {
self.recordBtn.hidden = NO;
}
- (void)__setRebeginRecord {
//时长小于1秒重新录制
self.recordBtn.selected = NO;
self.recordCountLabel.text = @"0s";
}
- (void)__createPickSpeakPowerTimer {
//音频值测量
_timerForVoiceChange = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(_timerForVoiceChange,dispatch_walltime(NULL, 0), 1/10 * NSEC_PER_SEC, 0);
__weak typeof(self) weakSelf = self;
dispatch_source_set_event_handler(_timerForVoiceChange, ^{
[weakSelf.audioRecorder updateMeters];
//double power = pow(10, (0.05 * [weakSelf.audioRecorder peakPowerForChannel:0]));
//NSLog(@"%f", power);
float power = [weakSelf.audioRecorder averagePowerForChannel:0];
if (weakSelf.AudioSpeakPowerBlock) {
weakSelf.AudioSpeakPowerBlock(power);
}
});
dispatch_resume(_timerForVoiceChange);
}
@end
- 画像
- 123.png
- キーコード
- (void)__createPickSpeakPowerTimer {
//音频值测量
_timerForVoiceChange = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(_timerForVoiceChange,dispatch_walltime(NULL, 0), 1/10 * NSEC_PER_SEC, 0);
__weak typeof(self) weakSelf = self;
dispatch_source_set_event_handler(_timerForVoiceChange, ^{
[weakSelf.audioRecorder updateMeters];
//double power = pow(10, (0.05 * [weakSelf.audioRecorder peakPowerForChannel:0]));
//NSLog(@"%f", power);
float power = [weakSelf.audioRecorder averagePowerForChannel:0];
if (weakSelf.AudioSpeakPowerBlock) {
weakSelf.AudioSpeakPowerBlock(power);
}
});
dispatch_resume(_timerForVoiceChange);
}