IOS 利用麦克风声音来实现吹裙子的动画效果

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u011154007/article/details/53020400

前言:闲来无事帮别人写的,利用麦克风声音来实现吹裙子的动画效果,因为录下来的东西不需要播放,所以在停止录音的同时删除文件。

大致步骤:

1、首先需要在plist文件中添加Privacy - Microphone Usage Description这个key值;

2、导入AVFoundation框架;

3、初始化录音实例:

3.1、设置录音文件存放路径;

3.2、录音配置;

3.3、开启监控声波设置;

4、开始录音;

5、添加计时器;

6、停止录音;

7、销毁计时器;

8、删除文件;

demo实现代码:

#import "BlowSkirtVC.h"
#import <AVFoundation/AVFoundation.h>

//图片个数
static const NSInteger KImageCount = 20;
static const CGFloat KDurationLevel = 0.05;
//录音文件存放路径
#define KRecorderFilePath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"play.aac"]

@interface BlowSkirtVC ()

//录音实例
@property (nonatomic,strong) AVAudioRecorder *recorder;
//定时器
@property (nonatomic,strong) NSTimer *levelTimer;
//图片实例
@property (nonatomic,strong) UIImageView *imageV;
//图片数组
@property (nonatomic,strong) NSMutableArray *imageArray;

@property (nonatomic,assign)  double lowPassResults;

@end

@implementation BlowSkirtVC

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //1.添加图片
    [self addImageView];
    
    //2.添加按钮
    [self addRecorderBtn];
}

#pragma mark 添加图片视图
- (void)addImageView
{
    [self.view addSubview:self.imageV];
}

#pragma mark 添加按钮
- (void)addRecorderBtn
{
    CGFloat recorderBtnX = CGRectGetMinX(self.imageV.frame);
    CGFloat recorderBtnY = CGRectGetMaxY(self.imageV.frame) + 20;
    CGFloat recorderBtnW = self.imageV.frame.size.width;
    CGFloat recorderBtnH = 44;
    UIButton *recorderBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    recorderBtn.backgroundColor = [UIColor redColor];
    recorderBtn.frame = CGRectMake(recorderBtnX, recorderBtnY, recorderBtnW, recorderBtnH);
    [recorderBtn setTitle:@"按住 说话" forState:UIControlStateNormal];
    [recorderBtn setTitle:@"松开 结束" forState:UIControlStateHighlighted];
    [recorderBtn addTarget:self action:@selector(startRecord) forControlEvents:UIControlEventTouchDown];
    [recorderBtn addTarget:self action:@selector(stopRecord) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:recorderBtn];
}

#pragma mark 开启录音
- (void)startRecord
{
    //0.判断是否正在录音,如果有则停止
    if ([self.recorder isRecording]) {
        [self.recorder stop];
    }
    
    //1.设置AVAudioSession分类
    AVAudioSession *audioSession=[AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
    
    //2.准备录音
    [self.recorder prepareToRecord];
    
    //3.开始录音
    [self.recorder record];
    
    //4.添加计时器
    [self.levelTimer fire];
}

#pragma mark 结束录音
- (void)stopRecord
{
    //1.停止录音,并设为nil
    [_recorder stop];
    _recorder = nil;
    
    //2.停止计时器,并设为nil
    [_levelTimer invalidate];
    _levelTimer = nil;
    
    //3.恢复图片最初状态
    NSInteger currentLevel = _lowPassResults/KDurationLevel;
    if (currentLevel > 0) {
        //3.1添加数据源
        NSMutableArray *animationArray = [NSMutableArray array];
        for (int i = 0; i < currentLevel; i ++) {
            UIImage *image = _imageArray[currentLevel - i];
            [animationArray addObject:image];
        }
        
        //3.2设置动画执行后需要现实的图片
        _imageV.image = _imageArray.firstObject;
        _imageV.animationImages = animationArray;
        
        //3.3重复次数
        _imageV.animationRepeatCount = 1;
        
        //3.4执行一次需要的时间
        _imageV.animationDuration = 2;
        
        //3.5开始动画
        [_imageV startAnimating];
        
    }
    
    //4.删除录音文件,以免数据量太大
    [self deleteOldRecordFile];
    
    //5.设置lowPassResults为0
    _lowPassResults = 0;
}

- (UIImageView *)imageV
{
    if (!_imageV) {
        CGFloat imageVW = 200;
        CGFloat imageVH = imageVW;
        _imageV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, imageVW, imageVH)];
        _imageV.center = self.view.center;
        _imageV.image = self.imageArray.firstObject;
    }
    return _imageV;
}

- (NSMutableArray *)imageArray
{
    if (!_imageArray) {
        _imageArray = [NSMutableArray array];
        for (int i = 0; i < KImageCount; i ++) {
            NSString *imageName = [NSString stringWithFormat:@"Blowskirt%d_@2x.jpg",i + 1];
            UIImage *image = [UIImage imageNamed:imageName];
            [_imageArray addObject:image];
        }
    }
    return _imageArray;
}

- (AVAudioRecorder *)recorder
{
    if (!_recorder) {
        //1.录音文件存储路径
        NSURL *url = [NSURL URLWithString:KRecorderFilePath];
        //2.录音设置
        NSDictionary *setting = [self getAudioSetting];
        //3.实例化对象
        NSError *error = nil;
        _recorder = [[AVAudioRecorder alloc] initWithURL:url settings:setting error:&error];
        //3.1如果要监控声波则必须设置为YES
        _recorder.meteringEnabled = YES;
        if (error) {
            NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription);
            return nil;
        }
    }
    return _recorder;
}

#pragma mark 录音配置
-(NSDictionary *)getAudioSetting
{
    //录音设置
    NSMutableDictionary *recordSettings = [NSMutableDictionary dictionary];
    //录音格式
    [recordSettings setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
    //采样率
    [recordSettings setValue:[NSNumber numberWithFloat:11025.0] forKey:AVSampleRateKey];//44100.0
    //通道数
    [recordSettings setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    //线性采样位数
    [recordSettings setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    //音频质量,采样质量
    [recordSettings setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];
    
    return recordSettings;
}

- (NSTimer *)levelTimer
{
    if (!_levelTimer) {
        _levelTimer = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:@selector(levelTimerCallback:) userInfo:nil repeats:YES];
    }
    return _levelTimer;
}

#pragma mark 计时器执行的方法
- (void)levelTimerCallback:(NSTimer *)timer
{
    //1.刷新电平值,-120表示完全安静,0表示最大输入值
    [_recorder updateMeters];
    
    //2.获取峰值电平并转化为0-1
    const double ALPHA = 0.05;
    double peakPowerForChannel = pow(10, (0.05 * [self.recorder peakPowerForChannel:0]));
    _lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * _lowPassResults;
    
    NSLog(@"Average input: %f Peak input: %f Low pass results: %f", [self.recorder averagePowerForChannel:0], [self.recorder peakPowerForChannel:0], _lowPassResults);
    
    //3.根据值转换为对应的等级的图片,此处以0.05为划分
    NSInteger currentLevel = _lowPassResults/KDurationLevel;
    //3.1防止数组越界
    if (currentLevel >= KImageCount - 1) {
        currentLevel = KImageCount - 1;
    }
    _imageV.image = _imageArray[currentLevel];
    
}

#pragma mark 删除录音文件
- (void)deleteOldRecordFile
{
    [self deleteOldRecordFileAtPath:KRecorderFilePath];
}

#pragma mark 删除录音文件(根据相应的路径)
- (void)deleteOldRecordFileAtPath:(NSString *)pathStr
{
    NSFileManager* fileManager=[NSFileManager defaultManager];
    
    BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:pathStr];
    if (!blHave) {
        NSLog(@"不存在");
        return ;
    }else {
        NSLog(@"存在");
        BOOL blDele= [fileManager removeItemAtPath:pathStr error:nil];
        if (blDele) {
            NSLog(@"删除成功");
        }else {
            NSLog(@"删除失败");
        }
    }
}

@end

demo下载链接:http://download.csdn.net/detail/u011154007/9674248
展开阅读全文

没有更多推荐了,返回首页