`
sinaier
  • 浏览: 33961 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

实例编程iPhone 录音和播放(收藏)

阅读更多
实例编程iPhone 录音和播放是本文要介绍的内容,最近准备做一个关于录音和播放的项目!查了一些资料,很简单的做了一个,下面我就分享一下iPhone的录音和播放的使用心得。iPhone的录音和播放使用到了media层的内容,media层处于cocoa层之下,用到的很大一部分都是c语言的结构。

1、引入框架。

#import <AVFoundation/AVFoundation.h>

2、创建录音项。
- (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
  }
通过以上的方法就应该能够实现播放,播放的时候也是可以加入振幅过程的,大家可以试试!这样一个iPhone录音机就做好了
分享到:
评论
1 楼 yulanfeiyang 2012-07-30  

相关推荐

Global site tag (gtag.js) - Google Analytics