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)); 
    AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 
    if ([sender isOn]) { 
        //設置下揚聲器模式 
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; 
         
    }else{ 
        //設置聽筒模式 
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 
    } 
    [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]; 
    //錄音的時候因爲設置的音頻會話是錄音模式,所以錄音完成後要把音頻會話設置回聽筒模式或者揚聲器模式,根據切換器的值判斷 
    AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 
    if ([change isOn]) { 
        //揚聲器模式 
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; 
         
    }else{ 
        //聽筒模式 
        [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]; 


發佈了2 篇原創文章 · 獲贊 1 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章