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

来源:互联网 发布:淘宝优惠券使用规则 编辑:程序博客网 时间:2024/04/28 04:49

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

大致步骤:

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
1 0
原创粉丝点击