zoukankan      html  css  js  c++  java
  • 第五十一篇、录音

    录音

    在AVFoundation框架中有一个AVAudioRecorder类专门处理录音操作,它同样支持多种音频格式。与AVAudioPlayer类似,你完全可以将它看成是一个录音机控制类,下面是常用的属性和方法:

    先来了解下AVAudioRecorder的常用属性:
    @property (readonly, getter=isRecording) BOOL recording;//是否正在录音
    @property (readonly) NSDictionary<NSString *, id> *settings;//录音配置
    @property (readonly) NSURL *url;//录音文件存放URL
    @property (readonly) NSTimeInterval currentTime;//录音时长
    @property (getter=isMeteringEnabled) BOOL meteringEnabled;//是否监控声波
    
    常用对象方法:
    - (BOOL)prepareToRecord;//为录音准备缓冲区
    - (BOOL)record;//录音开始,暂停后调用会恢复录音
    - (BOOL)recordAtTime:(NSTimeInterval)time;//在指定时间后开始录音
    - (BOOL)recordForDuration:(NSTimeInterval) duration;//按指定时长录音
    - (BOOL)recordAtTime:(NSTimeInterval)time forDuration:(NSTimeInterval)duration;//上面2个的合体
    - (void)pause; //中断录音
    - (void)stop; //停止录音
    - (BOOL)deleteRecording;//删除录音,必须先停止录音再删除
    
    常用的代理方法:
    //录音完成后调用
    - (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag;//录音编码发送错误时调用
    - (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error;

    音频

    如果播放较大的音频或者要对音频有精确的控制则System Sound Service可能就很难满足实际需求了,通常这种情况会选择使用AVFoundation.framework中的AVAudioPlayer来实现。AVAudioPlayer可以看成一个播放器,它支持多种音频格式,而且能够进行进度、音量、播放速度等控制

    AVAudioPlayer的使用比较简单:
    
    1.初始化AVAudioPlayer对象,此时通常指定本地文件路径。
    
    2.设置播放器属性,例如重复次数、音量大小等。
    
    3.调用play方法播放。

    具体实现:

    #import <AVFoundation/AVFoundation.h>
    #define kRecordAudioFile @"myRecord.caf"
    
    
    @interface ViewController ()<AVAudioRecorderDelegate>
    {
        NSString *dateName;
    
    }
    @property (weak, nonatomic) IBOutlet UITableView *table;
    
    @property (nonatomic,strong) AVAudioRecorder *audioRecorder;//音频录音机
    @property (nonatomic,strong) AVAudioPlayer *audioPlayer;//音频播放器,用于播放录音文件
    
    
    @property(nonatomic,strong) NSMutableArray *spaceData;
    
    
    @end
    
    @implementation ViewController
    #pragma mark - 私有方法
    /**
     *  设置音频会话
     */
    -(void)setAudioSession{
    
        AVAudioSession *audioSession=[AVAudioSession sharedInstance];
        //设置为播放和录音状态,以便可以在录制完之后播放录音
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
        [audioSession setActive:YES error:nil];
    }
    
    
    
    /**
     *  取得录音文件设置
     *
     *  @return 录音设置
     */
    -(NSDictionary *)getAudioSetting{
        NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
        //设置录音格式
        [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
        //设置录音采样率,8000是电话采样率,对于一般录音已经够了
        [dicM setObject:@(8000) forKey:AVSampleRateKey];
        //设置通道,这里采用单声道
        [dicM setObject:@(1) forKey:AVNumberOfChannelsKey];
        //每个采样点位数,分为8、16、24、32
        [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey];
        //是否使用浮点数采样
        [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
        //....其他设置等
        return dicM;
    }
    /**
     *  取得录音文件保存路径
     *
     *  @return 录音文件路径
     */
    -(NSURL *)getPlayPath:(NSString *)title{
    
    
        //    static int index = 0;
    
        NSString *urlStr=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        urlStr=[urlStr stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@",title,kRecordAudioFile]];
        NSLog(@"play file path:%@",urlStr);
        NSURL *url=[NSURL fileURLWithPath:urlStr];
    
        return url;
    }
    
    /**
     *  以日期为title,来保存录音
     *
     *  @return <#return value description#>
     */
    - (NSString *) convertDateFromString
    {
        NSDate *date = [NSDate date];
        //    NSLog(@"%@--askl",date);
        //    
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
        //zzz表示时区,zzz可以删除,这样返回的日期字符将不包含时区信息。
    
       [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
       NSString *destDateString = [dateFormatter stringFromDate:date];
    
        return destDateString;
    
    }

    长按开始录音,松开停止:

    - (void)setClikeSpaceState:(NSString *)aState
    {
        NSLog(@"点击语音---");    
    
        if([aState isEqualToString:@"begin"])
        {
            NSLog(@"begin---");
    
            dateName = [self convertDateFromString];
            //创建录音文件保存路径
            NSURL *url=[self getPlayPath:dateName];
            //创建录音格式设置
            NSDictionary *setting=[self getAudioSetting];
            //创建录音机
            NSError *error=nil;
            _audioRecorder=[[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];
            _audioRecorder.delegate=self;
            _audioRecorder.meteringEnabled=YES;//如果要监控声波则必须设置为YES
    
            if (![self.audioRecorder isRecording]) {
                [self.audioRecorder record];//首次使用应用时如果调用record方法会询问用户是否允许使用麦克风
                //        self.timer.fireDate=[NSDate distantPast];
    
                NSLog(@"111");
            }
    
    
        }else
        {
            NSLog(@"end---");
    
    
            /** 停止录音*/
            [self.audioRecorder stop];
    
    
            /** 录音地址*/
            NSURL *url = [self getPlayPath:dateName];
    
            /** 加载数据*/
    
            AVAudioPlayer   *audioPlayer1 = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    
            Model *model = [[Model alloc]init];
            model.duration = [NSString stringWithFormat:@"%.f",audioPlayer1.duration];
            model.spacePath = dateName;
    
    
    
            /** table 刷新*/
            [self.spaceData addObject:model];
            [self.table reloadData];
    
    
            /** table 滚动到当前row*/
    
            [self.table selectRowAtIndexPath:[NSIndexPath indexPathForRow:(self.spaceData.count - 1) inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];
    
    
    
    
    
    
        }
    }

    点击播放:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
    
        Model *model = self.spaceData[indexPath.row];    
    
        /** 播放录音*/
        NSURL *url=[self getPlayPath:model.spacePath];
        NSError *error=nil;
        _audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
        _audioPlayer.numberOfLoops=0;
    
        [_audioPlayer prepareToPlay];
        [self.audioPlayer play];
    
        NSLog(@"%.0f---aaaa",_audioPlayer.duration);
    
        /** UIImage动画数组*/
        NSMutableArray   *imgData = [NSMutableArray array];
        for(int i=0;i<4;i++)
        {
            UIImage *aImage = [UIImage imageNamed:[NSString stringWithFormat:@"chat_receiver_audio_playing00%d",i]];
            [imgData addObject:aImage];
    
        }
    
        TwoTableViewCell *twoCell = [self.table cellForRowAtIndexPath:indexPath];
    
    
    
    
        /** 点击动画*/
    
        [twoCell.speak  setAnimationImages:imgData];
        //        [twoCell.speak setAnimationRepeatCount:1];
        [twoCell.speak setAnimationDuration:1];
        [twoCell.speak startAnimating];
    
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)([model.duration intValue] * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    
            [twoCell.speak stopAnimating];
    
        });
    
    }
  • 相关阅读:
    使用NBU进行oracle异机恢复
    mycat偶尔会出现JVM报错double free or corruption并崩溃退出
    exp导出数据时丢表
    service_names配置不正确,导致dg创建失败
    XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax
    HTTP协议简介详解 HTTP协议发展 原理 请求方法 响应状态码 请求头 请求首部 java模拟浏览器客户端服务端
    java集合框架容器 java框架层级 继承图结构 集合框架的抽象类 集合框架主要实现类
    【JAVA集合框架一 】java集合框架官方介绍 Collections Framework Overview 集合框架总览 翻译 javase8 集合官方文档中文版
    java内部类深入详解 内部类的分类 特点 定义方式 使用
    再谈包访问权限 子类为何不能使用父类protected方法
  • 原文地址:https://www.cnblogs.com/HJQ2016/p/5952907.html
Copyright © 2011-2022 走看看