iphone錄音和播放(解決錄音延遲問題)

- (void) prepareToRecord 
   { 
  AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 
  NSError *err = nil; 
  [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err]; 
  if(err){ 
  NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]); 
  return; 
  
  [audioSession setActive:YES error:&err]; 
  err = nil; 
  if(err){ 
  NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]); 
   return; 
   } 

 recordSetting = [[NSMutableDictionary alloc] init]; 
  [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey]; 
  [recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; 
  [recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey]; 
  [recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; 
        [recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey]; 
  [recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey]; 
  // Create a new dated file  NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0]; 
  NSString *caldate = [now description]; 
  recorderFilePath = [[NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, caldate] retain]; 
  NSURL *url = [NSURL fileURLWithPath:recorderFilePath]; 
  err = nil; 
  recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err]; 
  if(!recorder){ 
  NSLog(@"recorder: %@ %d %@", [err domain], [err code], [[err userInfo] description]); 
  UIAlertView *alert = 
  [[UIAlertView alloc] initWithTitle: @"Warning" 
  message: [err localizedDescription] 
  delegate: nil  cancelButtonTitle:@"OK"  otherButtonTitles:nil]; 
  [alert show]; 
  [alert release]; 
  return; 
  
  //prepare to record 
  [recorder setDelegate:self]; 
  [recorder prepareToRecord]; 

  recorder.meteringEnabled = YES; 

//判斷設備是否支持錄音

  BOOL audioHWAvailable = audioSession.inputIsAvailable; 
  if (! audioHWAvailable) { 
  UIAlertView *cantRecordAlert =  
  [[UIAlertView alloc] initWithTitle: @"Warning" 
  message: @"Audio input hardware not available" 
  delegate: nil  cancelButtonTitle:@"OK"  otherButtonTitles:nil]; 
  [cantRecordAlert show];    
  [cantRecordAlert release]; 

  return; 

 } 

   } 
以上這個方法就是創建了錄音項,其中包括錄音的路徑和一些音頻屬性,但只是準備錄音還沒有錄,如果要錄的話還要加入以下的方法: 
(void)startrecorder  { 
 [recorder record]; 
  } 
這樣就在我們創建的路徑下開始了錄音。完成錄音很簡單: 
(void) stopRecording{ 
 [recorder stop]; 
  } 
這裏順便提一下錄音的代理方法: 
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag  { 
NSLog(@"recorder successfully");  
UIAlertView *recorderSuccessful = 
[[UIAlertView alloc] initWithTitle:@"" 
message:@"錄音成功"delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
[recorderSuccessful show]; 
[recorderSuccessful release]; 
}  
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)arecorder error:(NSError *)error  {  
btnRecorder.enabled = NO; 
UIAlertView *recorderFailed = 
[[UIAlertView alloc] initWithTitle:@"" message:@"發生錯誤" 
delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
[recorderFailed show]; 
[recorderFailed release]; 

以上兩個代理方法分別指定了錄音的成功或失敗。 

錄音中有一個的錄音對象有一個averagePowerForChannel和peakPowerForChannel的屬性分別爲聲音的最高振幅和平均振幅,有了他們就可以做一個動態的振幅的錄音效果。 

- (void) updateAudioDisplay { 
 if (isStart == NO) { 
 currentTimeLabel.text = @"--:--"; 
 
 else { 
 double currentTime = recorder.currentTime; 
 currentTimeLabel.text = [NSString stringWithFormat: @"d:d", 
 (int) currentTime/60,   (int) currentTime%60]; 
 //START:code.RecordViewController.setlevelmeters 
 [recorder updateMeters];   
 [leftLevelMeter setPower: [recorder averagePowerForChannel:0] peak: [recorder peakPowerForChannel: 0]];
 if (! rightLevelMeter.hidden) { 
 [rightLevelMeter setPower: [recorder averagePowerForChannel:1]   peak: [recorder peakPowerForChannel: 1]]; 
  } 
  //END:code.RecordViewController.setlevelmeters 
  } 
  }  
  以上就是錄音相關的內容。 
  下面說一下播放的方法: 
  void SystemSoundsDemoCompletionProc (  SystemSoundID  soundID,  void           *clientData)  { 
  AudioServicesDisposeSystemSoundID (soundID);  
  ((AudioRecorderPlayerAppDelegate*)clientData).statusLabel.text = @"Stopped"; 
  } 
  -(void)playAudio  { 
 //START:code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound 
 // create a system sound id for the selected row  SystemSoundID soundID; 
 OSStatus err = kAudioServicesNoError; 
 // special case: vibrate 
 //震動 
 //soundID = kSystemSoundID_Vibrate; 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.vibratesystemsound"/>
 // find corresponding CAF file 
 //NSString *cafName = [NSString stringWithFormat: @"%@",recorderFilePath]; 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.rowtonumberstring"/> 
 NSURL *url = [NSURL fileURLWithPath:recorderFilePath]; 
 //NSString *cafPath =  
 //[[NSBundle mainBundle] pathForResource:cafName ofType:@"caf"]; 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.findcafinbundle"/> 
 //NSURL *cafURL = [NSURL fileURLWithPath:url]; 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.fileurlwithpath"/> err =AudioServicesCreateSystemSoundID((CFURLRef) url, &soundID); 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.createsystemsound"/> 
 //END:code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound 
 //START:code.SystemSoundsDemo.SystemSoundsDemoViewController.registercompletionprocandplaysound 
 if (err == kAudioServicesNoError) {  
 // set up callback for sound completion  err = AudioServicesAddSystemSoundCompletion 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.addcompletionproc"/>(soundID, 
 // sound to monitor  NULL, 
 // run loop (NULL==main)  NULL, 
 // run loop mode (NULL==default)  SystemSoundsDemoCompletionProc, 
 // callback function 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.completionprocroutine"/> self 
 // data to provide on callback  ); 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.addcompletionprocend"/> statusLabel.text =@"Playing"; 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.setlabel"/> AudioServicesPlaySystemSound(soundID); 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.playsound"/> 
 
 if (err != kAudioServicesNoError) { 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.errorblockstart"/> 
 CFErrorRef error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, err, NULL); 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.createcferror"/> 
 NSString *errorDesc = (NSString*) CFErrorCopyDescription (error); 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.copycferrordescription"/>
 UIAlertView *cantPlayAlert =  [[UIAlertView alloc] initWithTitle:@"Cannot Play:"    message: errorDesc    delegate:nil  cancelButtonTitle:@"OK" otherButtonTitles:nil];  [cantPlayAlert show]; 
 [cantPlayAlert release]; 
 [errorDesc release]; 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.releaseerrordescription"/>
 CFRelease (error); 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.releaseerror"/> 
 
 //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.errorblockend"/> 
 //END:code.SystemSoundsDemo.SystemSoundsDemoViewController.registercompletionprocandplaysound 

  } 

紅色字體部分一定要加上,不然再ios5下面錄音時會有幾秒鐘的延遲。

轉自:http://sinaier.iteye.com/blog/1271114


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章