• CoreAudio实现录音播音和扬声器听筒模式的切换


    本例子使用Core Audio实现类似于微信的音频对讲功能,可以录音和播放并且实现了听筒模式和扬声器模式的切换。录音主要使用AVAudioRecorder类来实现录音功能,播放则使用AVAudioPlayer类来实现播放音频功能,扬声器和听筒模式的切换是通过设置AVAudioSession类的属性值来实现切换效果。


    - (void)viewDidLoad
    {
        [super viewDidLoad];
        //创建录音按钮
        UIButton* recorderB = [[[UIButton alloc]initWithFrame:CGRectMake(20, 220, 60, 40)]autorelease];
        [recorderB setTitle:@"record" forState:UIControlStateNormal];
        [recorderB setBackgroundColor:[UIColor grayColor]];
        [recorderB addTarget:self action:@selector(prerecord:) forControlEvents:UIControlEventTouchDown];
        [recorderB addTarget:self action:@selector(startrecord:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:recorderB];
        
        //创建播放按钮
        UIButton* play = [[[UIButton alloc]initWithFrame:CGRectMake(230, 220, 60, 40)]autorelease];
        [play setTitle:@"play" forState:UIControlStateNormal];
        [play setBackgroundColor:[UIColor grayColor]];
        [play addTarget:self action:@selector(play:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:play];
        
        //创建听筒模式和扬声器模式切换按钮
        change = [[[UISwitch alloc]initWithFrame:CGRectMake(120, 225, 40, 40)]autorelease];
        //默认设置为没有打开,则用听筒模式
        [change setOn:NO];
        [change addTarget:self action:@selector(change:) forControlEvents:UIControlEventValueChanged];
        [self.view addSubview:change];
        
    }

    //切换按钮事件
    -(void)change:(UISwitch*)sender{
        NSLog(@"%@",NSStringFromSelector(_cmd));
         //录音的时候因为设置的音频会话是录音模式,所以录音完成后要把音频会话设置回听筒模式或者扬声器模式,根据切换器的值判断,kAudioSessionOverrideAudioRoute_None为听筒模式,kAudioSessionOverrideAudioRoute_Speaker为扬声器模式
        UInt32 audioRouteOverride = ![sender isOn] ?kAudioSessionOverrideAudioRoute_None:kAudioSessionOverrideAudioRoute_Speaker;
        AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setActive:YES error:nil];
    }

    //录音事件
    -(void)record:(id)sender{
            //获取当前应用的AudioSession,每个应用都有自己唯一的声频会话
            AVAudioSession * audioSession = [AVAudioSession sharedInstance];
            NSError* error1;
            //设置当前应用的声频会话为录音模式
            /*
            Use this category for background sounds such as rain, car engine noise, etc.
             Mixes with other music.
             
             AVF_EXPORT NSString *const AVAudioSessionCategoryAmbient;
             
             Use this category for background sounds.  Other music will stop playing.     AVF_EXPORT NSString *const AVAudioSessionCategorySoloAmbient;
             
             Use this category for music tracks.
             
             AVF_EXPORT NSString *const AVAudioSessionCategoryPlayback;
             
             Use this category when recording audio.
             
             AVF_EXPORT NSString *const AVAudioSessionCategoryRecord;
             
             Use this category when recording and playing back audio.
             
             AVF_EXPORT NSString *const AVAudioSessionCategoryPlayAndRecord;
             
             Use this category when using a hardware codec or signal processor while
             not playing or recording audio.
             
             AVF_EXPORT NSString *const AVAudioSessionCategoryAudioProcessing;
             */

            [audioSession setCategory:AVAudioSessionCategoryRecord error: &error1];
            //激活音频会话
            [audioSession setActive:YES error: &error1];
            NSLog(@"record...");
            //创建录音的文件保存位置
            NSString* filepath = [DOCUMENT_PATH stringByAppendingPathComponent:@"test.caf"];
            url = [[NSURL fileURLWithPath:filepath]retain];
            NSLog(@"path:%@",filepath);
            //设置录音的相关属性
            NSMutableDictionary *settings = [[NSMutableDictionary alloc] init];
            //设置音频格式
            [settings
             setValue:[NSNumber numberWithInteger:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
            //设置采用率
            [settings
             setValue:[NSNumber numberWithFloat:44100.0f] forKey:AVSampleRateKey];
            //设置频道
            [settings
             setValue:[NSNumber numberWithInteger:2] forKey:AVNumberOfChannelsKey];
            //设置录音质量
            [settings
             setValue:[NSNumber numberWithInteger:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
            NSError* error;
            recorder = [[AVAudioRecorder alloc]initWithURL:url settings:settings error:&error];
            recorder.delegate = self;
            //录音准备,会为建立录音文件做好需要的准备
            BOOL isrecord = [recorder prepareToRecord];
            NSLog(@"isrecord:%d",isrecord);
            //正式开始录音
            [recorder record];
            NSLog(@"record begin...");

        
    }
    //手指离开点击录音按钮的事件
    -(void)startrecord:(id)sender{

        NSLog(@"%@",NSStringFromSelector(_cmd));
        NSTimeInterval now = [[NSDate date]timeIntervalSince1970];
        //获取长按录音按钮的时间
        NSTimeInterval offset = now - starttime;
        NSLog(@"offset:%f",offset);
        //如果长按的时间少于1秒,则不录音
        if (offset<=1) {
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(record:) object:self];
        }else{
            //超过一秒,则完成录音,停止继续录音
            [self stoprecorder:recorder];
        }
    }
    //手指点击录音按钮时间
    -(void)prerecord:(id)sender{
        NSLog(@"%@",NSStringFromSelector(_cmd));
        //获取点击的时间
        starttime = [[NSDate date]timeIntervalSince1970];
        NSLog(@"starttime:%f",starttime);
        //点击超过一秒后才正式录音
        [self performSelector:@selector(record:) withObject:self afterDelay:1];
    }

    //停止录音的事件
    -(void)stoprecorder:(AVAudioRecorder*)sender{
        NSLog(@"%@",NSStringFromSelector(_cmd));
        //判断是否还在录音,如果是就停止
        if ([recorder isRecording]) {
            [recorder stop];
        }
       
    }
    //播放事件
    -(void)play:(id)sender{
       
        NSLog(@"%@",NSStringFromSelector(_cmd));
        NSError* error;
        NSLog(@"url:%@",url);
        //通过AVAudioPlayer打开刚才录音的文件
        AVAudioPlayer* player = [[AVAudioPlayer alloc]initWithData:[NSData dataWithContentsOfURL:url] error:&error];
        //AVAudioPlayer预处理,为需要播放做好准备
        BOOL isplay = [player prepareToPlay];
        NSLog(@"isplay:%d",isplay);
      //  player.volume = 1;
        player.delegate = self;
        //正式播放
        [player play];
    }
    - (void)didReceiveMemoryWarning
    {
        
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    //录音完成后的回调事件
    - (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
        NSLog(@"%@",NSStringFromSelector(_cmd));
        //录音完成后关闭释放资源
        if ([recorder isRecording]) {
            [recorder stop];
        }
        [recorder release];
        //录音的时候因为设置的音频会话是录音模式,所以录音完成后要把音频会话设置回听筒模式或者扬声器模式,根据切换器的值判断,kAudioSessionOverrideAudioRoute_None为听筒模式,kAudioSessionOverrideAudioRoute_Speaker为扬声器模式
        UInt32 audioRouteOverride = ![change isOn] ?kAudioSessionOverrideAudioRoute_None:kAudioSessionOverrideAudioRoute_Speaker;
        AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        //类别要AVAudioSessionCategoryPlayAndRecord,才有效
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
        [audioSession setActive:YES error:nil];
        
    }

    //录音编码出错的回调
    - (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error{
        NSLog(@"%@",NSStringFromSelector(_cmd));
        [recorder release];
    }
    //播放音频完成后的回调
    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
         NSLog(@"%@",NSStringFromSelector(_cmd));
        //成功播放完音频后释放资源
        if ([player isPlaying]) {
            [player stop];
        }
        [player release];
    }

    //音频播放解码出错的回调
    - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
     NSLog(@"%@",NSStringFromSelector(_cmd));
        [player release];
    }



  • 相关阅读:
    VBA.replace替换单引号或双引号
    读取文件
    UPDATE
    alter update
    SQL日期格式
    python map的用法
    python os模块用法
    python re.I compile search
    python 正则匹配
    通过list中值得名称查询索引号
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3177986.html
Copyright © 2020-2023  润新知