iOS開発-録音中のオーディオ変動の監視

iOS開発-録音されたオーディオの変動の監視は、サウンドサイズの変動に従います

序文

オーディオとビデオの開発では、録音中のオーディオの変動を監視し、それらをビューに表示する必要があります。

効果

ここに画像の説明を挿入

コード

  • 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);
}

おすすめ

転載: blog.csdn.net/weixin_41732253/article/details/110121282