iOS录音播放

iOS录音播放Demo下载地址:http://download.csdn.net/detail/lovechris00/9587214


本文将涉及到以下内容:


一、搭建长按录音UI效果;

二、使用AVAudioRecorder录音;

三、使用AVAudioPlayer播放,并添加播放动画;

四、使用lame将caf音频转化为mp3;

五、将mp3 转化为 base64编码;

六、查看录音文件大小;

七、删除语音文件;


--------------------------


一、搭建长按录音UI效果;

页面样式效果如下:

其中:

1、录音按钮是由两个UIImageView实现,监听手势方法,长按第一层UIImageView时,第二层开始旋转动画;

   这里我想过用UIButton来实现点击录音效果,其中UIControlEventTouchDown可以检测点击下去的效果,UIControlEventTouchUpInside可以检测点击后起来的效果,但是测试点击下去后,没有直接起来,而是将手指移动到其他位置,导致录音无法关闭,所以,还是使用了长按手势来监听。


2、其他控件比较简单。




核心代码

1、长按启动录音;


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">- (UIImageView *)recordBtn  
  2. {  
  3.       
  4.     if (!_recordBtn) {  
  5.         _recordBtn = [[UIImageView alloc]init];  
  6.         _recordBtn.backgroundColor = [UIColor clearColor];  
  7.           
  8.         [_recordBtn setImage:[UIImage imageNamed:@"record_norm"]];  
  9.         _recordBtn.userInteractionEnabled = YES;//方便添加长按手势  
  10.     }  
  11.       
  12.     return _recordBtn;  
  13. }</span>  

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">self.recordBtn.frame = CGRectMake((kSCREEN_WIDTH - btnH)*0.5, CGRectGetMaxY(self.timeLabel.frame) + margin, btnH, btnH);  
  2.         self.recordBtn.layer.cornerRadius = self.recordBtn.frame.size.width * 0.5;  
  3.           
  4.         [self.recordBtn.layer setMasksToBounds:YES];  
  5.         //        [self.recordBtn addTarget:self action:@selector(recordNotice) forControlEvents:UIControlEventTouchDown];  
  6.         //        [self.recordBtn addTarget:self action:@selector(stopNotice) forControlEvents:UIControlEventTouchUpInside];  
  7.           
  8.         //实例化长按手势监听  
  9.         UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleTableviewCellLongPressed:)];  
  10.           
  11.         //代理  
  12.         longPress.delegate = self;  
  13.         longPress.minimumPressDuration = 0.5;  
  14.         [self.recordBtn addGestureRecognizer:longPress];  
  15. </span>  

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">//长按事件的实现方法  
  2.   
  3. - (void) handleTableviewCellLongPressed:(UILongPressGestureRecognizer *)gestureRecognizer {  
  4.       
  5.     if (gestureRecognizer.state ==  UIGestureRecognizerStateBegan) {  
  6.           
  7.         NSLog(@"UIGestureRecognizerStateBegan");  
  8.         [self startRecordNotice];  
  9.           
  10.     }  
  11.       
  12.     if (gestureRecognizer.state == UIGestureRecognizerStateChanged) {  
  13.           
  14.     }  
  15.       
  16.     if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {  
  17.           
  18.         NSLog(@"UIGestureRecognizerStateEnded");  
  19.         [self stopRecordNotice];  
  20.           
  21.     }  
  22.       
  23. }  
  24. </span>  


2、录音过程中,录音外圈旋转效果

1)初始化

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">-(UIImageView *)rotateImgView  
  2. {  
  3.     if (!_rotateImgView) {  
  4.         _rotateImgView = [[UIImageView alloc]init];  
  5.         _rotateImgView.image = [UIImage imageNamed:@"rcirle_norm"];  
  6.         _rotateImgView.frame = CGRectMake(00, btnH, btnH);  
  7.         _rotateImgView.center = self.recordBtn.center;  
  8.  }  
  9.     return _rotateImgView;  
  10. }  
  11. </span>  


2)动画设置

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">// 执行动画  
  2. - (void)starAnimalWithTime:(CFTimeInterval)time  //time为旋转一周的时间  
  3. {  
  4.     self.rotateImgView.image = [UIImage imageNamed:@"rcirle_high"];  
  5.       
  6.     self.rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];  
  7.     self.rotationAnimation.toValue = [NSNumber numberWithFloatM_PI * 2.0 ];  
  8.     self.rotationAnimation.duration = time;  
  9.     self.rotationAnimation.cumulative = YES;  
  10.     self.rotationAnimation.repeatCount = HUGE_VALF;  
  11.       
  12.     [self.rotateImgView.layer addAnimation:self.rotationAnimation forKey:@"rotationAnimation"];  
  13. }  
  14. </span>  


3、播放时的动画效果

1)动画设置

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;"><span style="font-size:18px;">#pragma mark - 动画效果  
  2.   
  3. - (void)pictureChangeAnimationSetting  
  4. {  
  5.     NSArray *picArray = @[[UIImage imageNamed:@"voice1"],  
  6.                           [UIImage imageNamed:@"voice2"],  
  7.                           [UIImage imageNamed:@"voice3"],];  
  8.       
  9.     //    self.imageView.image = [UIImage imageNamed:@"voice1"];  
  10.       
  11.       
  12.     //imageView的动画图片是数组images  
  13.     self.voiceView.animationImages = picArray;  
  14.     //按照原始比例缩放图片,保持纵横比  
  15.     self.voiceView.contentMode = UIViewContentModeScaleAspectFit;  
  16.     //切换动作的时间3秒,来控制图像显示的速度有多快,  
  17.     self.voiceView.animationDuration = 1;  
  18.     //动画的重复次数,想让它无限循环就赋成0  
  19.     self.voiceView.animationRepeatCount = 0;  
  20.       
  21. }</span></span>  

2)开启动画

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">[self.voiceView startAnimating];</span>  


3)关闭动画

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;"> [self.voiceView.layer removeAllAnimations];  
  2.     self.voiceView.image = [UIImage imageNamed:@"voice3"];</span>  


二、使用AVAudioRecorder录音;


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">#pragma mark -  Getter  
  2. /** 
  3.  *  获得录音机对象 
  4.  * 
  5.  *  @return 录音机对象 
  6.  */  
  7. -(AVAudioRecorder *)audioRecorder{  
  8.     if (!_audioRecorder) {  
  9.         //创建录音文件保存路径  
  10.         NSURL *url=[NSURL URLWithString:self.cafPathStr];  
  11.         //创建录音格式设置  
  12.         NSDictionary *setting=[self getAudioSetting];  
  13.         //创建录音机  
  14.         NSError *error=nil;  
  15.           
  16.         _audioRecorder=[[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];  
  17.         _audioRecorder.delegate=self;  
  18.         _audioRecorder.meteringEnabled=YES;//如果要监控声波则必须设置为YES  
  19.         if (error) {  
  20.             NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription);  
  21.             return nil;  
  22.         }  
  23.     }  
  24.     return _audioRecorder;  
  25. }  
  26. </span>  

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">/** 
  2.  *  取得录音文件设置 
  3.  * 
  4.  *  @return 录音设置 
  5.  */  
  6. -(NSDictionary *)getAudioSetting{  
  7.     //LinearPCM 是iOS的一种无损编码格式,但是体积较为庞大  
  8.     //录音设置  
  9.     NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];  
  10.     //录音格式 无法使用  
  11.     [recordSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey: AVFormatIDKey];  
  12.     //采样率  
  13.     [recordSettings setValue :[NSNumber numberWithFloat:11025.0] forKey: AVSampleRateKey];//44100.0  
  14.     //通道数  
  15.     [recordSettings setValue :[NSNumber numberWithInt:2] forKey: AVNumberOfChannelsKey];  
  16.     //线性采样位数  
  17.     //[recordSettings setValue :[NSNumber numberWithInt:16] forKey: AVLinearPCMBitDepthKey];  
  18.     //音频质量,采样质量  
  19.     [recordSettings setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];  
  20.       
  21.     return recordSettings;  
  22. }  
  23. </span>  

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">- (void)startRecordNotice{  
  2.   
  3.      if ([self.audioRecorder isRecording]) {  
  4.         [self.audioRecorder stop];  
  5.     }  
  6.      
  7.     [self deleteOldRecordFile];  //如果不删掉,会在原文件基础上录制;虽然不会播放原来的声音,但是音频长度会是录制的最大长度。  
  8.       
  9.     AVAudioSession *audioSession=[AVAudioSession sharedInstance];  
  10.     [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];  
  11.       
  12.       
  13.     if (![self.audioRecorder isRecording]) {//0--停止、暂停,1-录制中  
  14.           
  15.         [self.audioRecorder record];//首次使用应用时如果调用record方法会询问用户是否允许使用麦克风  
  16.         self.countNum = 0;  
  17.         NSTimeInterval timeInterval =1 ; //0.1s  
  18.         self.timer1 = [NSTimer scheduledTimerWithTimeInterval:timeInterval  target:self selector:@selector(changeRecordTime)  userInfo:nil  repeats:YES];  
  19.           
  20.         [self.timer1 fire];  
  21.     }  
  22.     [self starAnimalWithTime:2.0];  
  23. }  
  24. </span>  

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">- (void)stopRecordNotice  
  2. {  
  3.     NSLog(@"----------结束录音----------");  
  4.   
  5.     [self.audioRecorder stop];  
  6.     [self.timer1 invalidate];  
  7.      
  8. }</span>  


三、使用AVAudioPlayer播放;

这段代码写的不好,暂不分享,欢迎大家分享给我



四、使用lame将caf音频转化为mp3;

导入lame框架,import进来头文件即可使用,如果导出后是噪音,需要检查录音的设置

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">#pragma mark - caf转mp3  
  2. - (void)audio_PCMtoMP3  
  3. {  
  4.       
  5.     @try {  
  6.         int read, write;  
  7.           
  8.         FILEFILE *pcm = fopen([self.cafPathStr cStringUsingEncoding:1], "rb");  //source 被转换的音频文件位置  
  9.         fseek(pcm, 4*1024, SEEK_CUR);                                   //skip file header  
  10.         FILEFILE *mp3 = fopen([self.mp3PathStr cStringUsingEncoding:1], "wb");  //output 输出生成的Mp3文件位置  
  11.           
  12.         const int PCM_SIZE = 8192;  
  13.         const int MP3_SIZE = 8192;  
  14.         short int pcm_buffer[PCM_SIZE*2];  
  15.         unsigned char mp3_buffer[MP3_SIZE];  
  16.           
  17.         lame_t lame = lame_init();  
  18.         lame_set_in_samplerate(lame, 11025.0);  
  19.         lame_set_VBR(lame, vbr_default);  
  20.         lame_init_params(lame);  
  21.           
  22.         do {  
  23.             read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);  
  24.             if (read == 0)  
  25.                 write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);  
  26.             else  
  27.                 write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);  
  28.               
  29.             fwrite(mp3_buffer, write, 1, mp3);  
  30.               
  31.         } while (read != 0);  
  32.           
  33.         lame_close(lame);  
  34.         fclose(mp3);  
  35.         fclose(pcm);  
  36.     }  
  37.     @catch (NSException *exception) {  
  38.         NSLog(@"%@",[exception description]);  
  39.     }  
  40.     @finally {  
  41.         NSLog(@"MP3生成成功: %@",self.mp3PathStr);  
  42.     }  
  43.       
  44. }  
  45. </span>  


五、将mp3 转化为 base64编码;


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">#pragma mark - 文件转换  
  2. // 二进制文件转为base64的字符串  
  3. - (NSString *)Base64StrWithMp3Data:(NSData *)data{  
  4.     if (!data) {  
  5.         NSLog(@"Mp3Data 不能为空");  
  6.         return nil;  
  7.     }  
  8.     //    NSString *str = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];  
  9.     NSString *str = [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];  
  10.     return str;  
  11. }  
  12.   
  13. // base64的字符串转化为二进制文件  
  14. - (NSData *)Mp3DataWithBase64Str:(NSString *)str{  
  15.     if (str.length ==0) {  
  16.         NSLog(@"Mp3DataWithBase64Str:Base64Str 不能为空");  
  17.         return nil;  
  18.     }  
  19.     NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];  
  20.     NSLog(@"Mp3DataWithBase64Str:转换成功");  
  21.     return data;  
  22. }</span>  



六、查看录音文件大小;

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">//单个文件的大小,返回单位为K  
  2. - (long long) fileSizeAtPath:(NSString*)filePath{  
  3.       
  4.     NSFileManager* manager = [NSFileManager defaultManager];  
  5.       
  6.     if ([manager fileExistsAtPath:filePath]){  
  7.           
  8.         return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];  
  9.           
  10.     }  
  11.       
  12.     return 0;  
  13. }</span>  


调用

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">    
  2. //计算文件大小  
  3.     long long fileSize = [self fileSizeAtPath:self.mp3PathStr]/1024.0;  
  4.     NSString *fileSizeStr = [NSString stringWithFormat:@"%lld",fileSize];</span>  

七、删除(语音)文件;

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">-(void)deleteOldRecordFileAtPath:(NSString *)pathStr{  
  2.     NSFileManager* fileManager=[NSFileManager defaultManager];  
  3.       
  4.     BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:pathStr];  
  5.     if (!blHave) {  
  6.         NSLog(@"不存在");  
  7.         return ;  
  8.     }else {  
  9.         NSLog(@"存在");  
  10.         BOOL blDele= [fileManager removeItemAtPath:self.cafPathStr error:nil];  
  11.         if (blDele) {  
  12.             NSLog(@"删除成功");  
  13.         }else {  
  14.             NSLog(@"删除失败");  
  15.         }  
  16.     }  
  17. }</span>  


iOS录音播放Demo下载地址:http://download.csdn.net/detail/lovechris00/9587214


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值