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];
    
        });
    
    }
  • 相关阅读:
    [转] 一文读懂 HTTP/2 特性
    设置VS2019 支持C++17标准
    switch case 字符串表达式支持
    在Fabric实现类似Uniswap的去中心化交易所
    数据上链的原则与方式
    2.4g无线私有协议透传方案特色梳理
    无线数字麦克风解决方案小结
    高保真的音频编解码器模块及方案解析
    基于wifi的音频采集及处理解决方案小结
    基于智能降噪的助听器解决方案解析
  • 原文地址:https://www.cnblogs.com/HJQ2016/p/5952907.html
Copyright © 2011-2022 走看看