zoukankan      html  css  js  c++  java
  • iOS 录音功能的实现

    这两天也调了一下ios的录音,原文链接:http://www.iphoneam.com/blog/index.php?title=using-the-iphone-to-record-audio-a-guide&more=1&c=1&tb=1&pb=1

    这里ios的录音功能主要依靠AVFoundation.framework与CoreAudio.framework来实现

    在工程内添加这两个framework

    我这里给工程命名audio_text

    在生成的audio_textViewController.h里的代码如下

    [cpp] view plaincopy
     
    1. #import <UIKit/UIKit.h>  
    2. #import <AVFoundation/AVFoundation.h>  
    3. #import <CoreAudio/CoreAudioTypes.h>  
    4.   
    5. @interface audio_textViewController : UIViewController {  
    6.   
    7.     IBOutlet UIButton *bthStart;  
    8.     IBOutlet UIButton *bthPlay;  
    9.     IBOutlet UITextField *freq;  
    10.     IBOutlet UITextField *value;  
    11.     IBOutlet UIActivityIndicatorView *actSpinner;  
    12.     BOOL toggle;  
    13.       
    14.     //Variable setup for access in the class  
    15.     NSURL *recordedTmpFile;  
    16.     AVAudioRecorder *recorder;  
    17.     NSError *error;  
    18. }  
    19.   
    20. @property (nonatomic,retain)IBOutlet UIActivityIndicatorView *actSpinner;  
    21. @property (nonatomic,retain)IBOutlet UIButton *bthStart;  
    22. @property (nonatomic,retain)IBOutlet UIButton *bthPlay;  
    23.   
    24. -(IBAction)start_button_pressed;  
    25. -(IBAction)play_button_pressed;  
    26. @end  

    audio_textViewController.m

    [cpp] view plaincopy
     
    1. #import "audio_textViewController.h"  
    2.   
    3. @implementation audio_textViewController  
    4.   
    5.   
    6. - (void)viewDidLoad {  
    7.     [super viewDidLoad];  
    8.       
    9.     //Start the toggle in true mode.  
    10.     toggle = YES;  
    11.     bthPlay.hidden = YES;  
    12.       
    13.     //Instanciate an instance of the AVAudioSession object.  
    14.     AVAudioSession * audioSession = [AVAudioSession sharedInstance];  
    15.     //Setup the audioSession for playback and record.   
    16.     //We could just use record and then switch it to playback leter, but  
    17.     //since we are going to do both lets set it up once.  
    18.     [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];  
    19.     //Activate the session  
    20.     [audioSession setActive:YES error: &error];  
    21.       
    22. }  
    23. /* 
    24. // The designated initializer. Override to perform setup that is required before the view is loaded. 
    25. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
    26.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    27.     if (self) { 
    28.         // Custom initialization 
    29.     } 
    30.     return self; 
    31. } 
    32. */  
    33.   
    34. /* 
    35. // Implement loadView to create a view hierarchy programmatically, without using a nib. 
    36. - (void)loadView { 
    37. } 
    38. */  
    39.   
    40.   
    41. /* 
    42. // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
    43. - (void)viewDidLoad { 
    44.     [super viewDidLoad]; 
    45. } 
    46. */  
    47.   
    48.   
    49. /* 
    50. // Override to allow orientations other than the default portrait orientation. 
    51. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    52.     // Return YES for supported orientations 
    53.     return (interfaceOrientation == UIInterfaceOrientationPortrait); 
    54. } 
    55. */  
    56.   
    57. - (IBAction)  start_button_pressed{  
    58.       
    59.     if(toggle)  
    60.     {  
    61.         toggle = NO;  
    62.         [actSpinner startAnimating];  
    63.         [bthStart setTitle:@"停" forState: UIControlStateNormal ];     
    64.         bthPlay.enabled = toggle;  
    65.         bthPlay.hidden = !toggle;  
    66.           
    67.         //Begin the recording session.  
    68.         //Error handling removed.  Please add to your own code.  
    69.           
    70.         //Setup the dictionary object with all the recording settings that this   
    71.         //Recording sessoin will use  
    72.         //Its not clear to me which of these are required and which are the bare minimum.  
    73.         //This is a good resource: http://www.totodotnet.net/tag/avaudiorecorder/  
    74.         NSMutableDictionary* recordSetting = [[NSMutableDictionary alloc] init];  
    75.           
    76.         [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];  
    77.           
    78.         [recordSetting setValue:[NSNumber numberWithFloat:[freq.text floatValue]] forKey:AVSampleRateKey];   
    79.         [recordSetting setValue:[NSNumber numberWithInt: [value.text intValue]] forKey:AVNumberOfChannelsKey];  
    80.           
    81.         //Now that we have our settings we are going to instanciate an instance of our recorder instance.  
    82.         //Generate a temp file for use by the recording.  
    83.         //This sample was one I found online and seems to be a good choice for making a tmp file that  
    84.         //will not overwrite an existing one.  
    85.         //I know this is a mess of collapsed things into 1 call.  I can break it out if need be.  
    86.         recordedTmpFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"%.0f.%@", [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"caf"]]];  
    87.         NSLog(@"Using File called: %@",recordedTmpFile);  
    88.         //Setup the recorder to use this file and record to it.  
    89.         recorder = [[ AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:&error];  
    90.         //Use the recorder to start the recording.  
    91.         //Im not sure why we set the delegate to self yet.    
    92.         //Found this in antother example, but Im fuzzy on this still.  
    93.         [recorder setDelegate:self];  
    94.         //We call this to start the recording process and initialize   
    95.         //the subsstems so that when we actually say "record" it starts right away.  
    96.         [recorder prepareToRecord];  
    97.         //Start the actual Recording  
    98.         [recorder record];  
    99.         //There is an optional method for doing the recording for a limited time see   
    100.         //[recorder recordForDuration:(NSTimeInterval) 10]  
    101.           
    102.     }  
    103.     else  
    104.     {  
    105.         toggle = YES;  
    106.         [actSpinner stopAnimating];  
    107.         [bthStart setTitle:@"开始录音" forState:UIControlStateNormal ];  
    108.         bthPlay.enabled = toggle;  
    109.         bthPlay.hidden = !toggle;  
    110.           
    111.         NSLog(@"Using File called: %@",recordedTmpFile);  
    112.         //Stop the recorder.  
    113.         [recorder stop];  
    114.     }  
    115. }  
    116.   
    117. - (void)didReceiveMemoryWarning {  
    118.     // Releases the view if it doesn't have a superview.  
    119.     [super didReceiveMemoryWarning];  
    120.       
    121.     // Release any cached data, images, etc that aren't in use.  
    122. }  
    123.   
    124. -(IBAction) play_button_pressed{  
    125.       
    126.     //The play button was pressed...   
    127.     //Setup the AVAudioPlayer to play the file that we just recorded.  
    128.     AVAudioPlayer * avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:recordedTmpFile error:&error];  
    129.     [avPlayer prepareToPlay];  
    130.     [avPlayer play];  
    131.       
    132. }  
    133.   
    134. - (void)viewDidUnload {  
    135.     // Release any retained subviews of the main view.  
    136.     // e.g. self.myOutlet = nil;  
    137.     //Clean up the temp file.  
    138.     NSFileManager * fm = [NSFileManager defaultManager];  
    139.     [fm removeItemAtPath:[recordedTmpFile path] error:&error];  
    140.     //Call the dealloc on the remaining objects.  
    141.     [recorder dealloc];  
    142.     recorder = nil;  
    143.     recordedTmpFile = nil;  
    144. }  
    145.   
    146.   
    147. - (void)dealloc {  
    148.     [super dealloc];  
    149. }  
    150.   
    151. @end  

    最后在interface builder里面绘制好界面,如

    设置下按键的属性

    基本就ok了,可以开始录音了。

    BUG解决
    但是大家要注意一个貌似是ios5.0之后引入的bug,就是当你录制音频的时候启动时间往往会比较慢,大概需要3--5秒的时间吧,这种现象尤其在播放的时候立刻切换到录制的时候非常明显。
     
    具体的原因我也不是很清楚,感觉应该是更底层的一些bug。目前我的解决方案是这样的。
    1.在音频队列的初始化方法中加入代码

    OSStatus error = AudioSessionInitialize(NULL, NULL, NULL, NULL);

            UInt32 category = kAudioSessionCategory_PlayAndRecord;

    error = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);

            

    AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, NULL, self);

    UInt32 inputAvailable = 0;

    UInt32 size = sizeof(inputAvailable);

    AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable);

    AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, NULL, self);

            AudioSessionSetActive(true); 

    2.在录制声音开始的时候先把播放声音stop,加入

        UInt32 category = kAudioSessionCategory_PlayAndRecord;

        AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);

     

    这样做应该会让你的录制启动速度显著加快的。
     
    csdn转载:http://blog.csdn.net/ch_soft/article/details/7382411
  • 相关阅读:
    (4.3)ODBC/OLE DB/ADO概念与使用情况
    查找至少连续出现三次的所有数字/连续3天的日期【LeetCode】
    javascript 事件触发
    document.referrer
    创业公司
    关于javascript 回调函数
    promise
    javascript deferred
    document.readystate
    window---->load, document------DOMContentLoaded
  • 原文地址:https://www.cnblogs.com/Camier-myNiuer/p/3144577.html
Copyright © 2011-2022 走看看