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; 
 //
 // find corresponding CAF file 
 //NSString *cafName = [NSString stringWithFormat: @"%@",recorderFilePath]; 
 //
 NSURL *url = [NSURL fileURLWithPath:recorderFilePath]; 
 //NSString *cafPath =  
 //[[NSBundle mainBundle] pathForResource:cafName ofType:@"caf"]; 
 //
 //NSURL *cafURL = [NSURL fileURLWithPath:url]; 
 //
 //
 //END:code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound 
 //START:code.SystemSoundsDemo.SystemSoundsDemoViewController.registercompletionprocandplaysound 
 if (err == kAudioServicesNoError) {  
 // set up callback for sound completion  err = AudioServicesAddSystemSoundCompletion 
 //
 // sound to monitor  NULL, 
 // run loop (NULL==main)  NULL, 
 // run loop mode (NULL==default)  SystemSoundsDemoCompletionProc, 
 // callback function 
 //
 // data to provide on callback  ); 
 //
 //
 //
 
 if (err != kAudioServicesNoError) { 
 //
 CFErrorRef error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, err, NULL); 
 //
 NSString *errorDesc = (NSString*) CFErrorCopyDescription (error); 
 //
 UIAlertView *cantPlayAlert =  [[UIAlertView alloc] initWithTitle:@"Cannot Play:"    message: errorDesc    delegate:nil  cancelButtonTitle:@"OK" otherButtonTitles:nil];  [cantPlayAlert show]; 
 [cantPlayAlert release]; 
 [errorDesc release]; 
 //
 CFRelease (error); 
 //
 
 //
 //END:code.SystemSoundsDemo.SystemSoundsDemoViewController.registercompletionprocandplaysound 

  } 

红色字体部分一定要加上,不然再ios5下面录音时会有几秒钟的延迟。

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

你可能感兴趣的:(iphone开发)