iOS中调用系统录音功能及其播放
最近做的项目中,用到了录音的功能,简单记录一下。
我的想法是:通过重写button的点击事件,来达到录音的目的。
/*----------------------------------【录音】-----------------------------*/
首先,需要新建文件,并继承于UIButton,暂且命名为 TDRecoedButton;
在.h文件中:
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
typedef void (^successRecordToSend)(NSInteger time,NSURL *url);
typedef void (^faildRecordToSend)(NSString * reason);
@interface TDRecoedButton : UIButton<AVAudioRecorderDelegate>
{
AVAudioRecorder *recorder; //录音的对象
NSTimer *timer; //时间
NSURL *urlPlay; //保存路径
}
//录音并保存成功
@property (nonatomic,copy) successRecordToSend successBlock;
-(void)setBtnSuccessRecord:(successRecordToSend)sendBlock;
//录音失败及返回reason方法
@property (nonatomic,copy) faildRecordToSend faildBlock;
-(void)setBtnFaildRecord:(faildRecordToSend)sendBlock;
在.m文件中:
#import "TDRecoedButton.h"
#define reason @"录音时间太短!"
@implementation TDRecoedButton
-(instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self audio];
[self setBackgroundImage:[UIImage imageNamed:@"icon_voice_normal"] forState:UIControlStateNormal];
[self setBackgroundImage:[UIImage imageNamed:@"icon_voice_pressed"] forState:UIControlStateHighlighted];
[self addTarget:self action:@selector(btnDown:) forControlEvents:UIControlEventTouchDown];
[self addTarget:self action:@selector(btnUp:) forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:@selector(btnDragUp:) forControlEvents:UIControlEventTouchDragExit];
}
return self;
}
- (IBAction)btnDown:(id)sender
{
//创建录音文件,准备录音
if ([recorder prepareToRecord]) {
//开始
[recorder record];
}
//设置定时检测
// timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(detectionVoice) userInfo:nil repeats:YES];
}
- (IBAction)btnUp:(id)sender
{
NSInteger cTime = recorder.currentTime;
if (cTime > 1) {//如果录制时间<1 不发送
NSLog(@"发出去");
if (_successBlock) {
_successBlock(cTime,urlPlay);
}
}else {
//删除记录的文件
[recorder deleteRecording];
//删除存储的
if (_faildBlock) {
_faildBlock(reason);
}
}
[recorder stop];
[timer invalidate];
}
- (IBAction)btnDragUp:(id)sender
{
//删除录制文件
[recorder deleteRecording];
[recorder stop];
[timer invalidate];
NSLog(@"取消发送");
}
-(void)audio
{
//录音设置
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc]init];
//设置录音格式 AVFormatIDKey==kAudioFormatLinearPCM
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
//设置录音采样率(Hz) 如:AVSampleRateKey==8000/44100/96000(影响音频的质量)
[recordSetting setValue:[NSNumber numberWithFloat:44100] forKey:AVSampleRateKey];
//录音通道数 1 或 2
[recordSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
//线性采样位数 8、16、24、32
[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
//录音的质量
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
NSString *strUrl = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/byingRecord.aac", strUrl]];
NSLog(@"*********url:%@",url);
urlPlay = url;
NSError *error;
//初始化
recorder = [[AVAudioRecorder alloc]initWithURL:url settings:recordSetting error:&error];
//开启音量检测
recorder.meteringEnabled = YES;
recorder.delegate = self;
}
-(void)setBtnSuccessRecord:(successRecordToSend)sendBlock
{
self.successBlock = sendBlock;
}
-(void)setBtnFaildRecord:(faildRecordToSend)sendBlock
{
self.faildBlock = sendBlock;
}
这样,重写的button就成功了,在别的控制器中,导入头文件,生成对象,就可以录音了。
但是,这样写,在模拟器上运行是完全ok的,当我跑真机的时候,就一直报错,于是,我找了一些帖子,找到了解决办法。
解决办法:
在实例化record之前,加入以下这段代码:
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *setCategoryError = nil;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&setCategoryError];
if(setCategoryError){
NSLog(@"%@", [setCategoryError description]);
if (_faildBlock) {
_faildBlock([setCategoryError description]);
}
}
这样就可以在真机上运行了。
/*----------------------------------【播放】-----------------------------*/
播放相对就简单了,主要就是找到存储的路径:
首先,定义一个对象:
@property (nonatomic,strong) AVAudioPlayer * avPlay; /*播放*/
@property (nonatomic,strong) NSURL * urlPlay; /*播放路径*/
在播放按钮的点击事件中,加入此方法:
#pragma mark - 点击播放录音
-(void)pressRecordPlayBtn:(id)sender
{
if (self.avPlay.playing) {
[self.avPlay stop];
return;
}
AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:_urlPlay error:nil];//_urlPlay是保存录音的路径
self.avPlay = player;
[self.avPlay play];
}
这样,就可以实现录音和播放的功能了!
iOS中调用系统录音功能及其播放的更多相关文章
- IOS中调用系统的电话、短信、邮件、浏览功能
iOS开发系列--通讯录.蓝牙.内购.GameCenter.iCloud.Passbook系统服务开发汇总 2015-01-13 09:16 by KenshinCui, 26990 阅读, 35 评 ...
- IOS中调用系统拨打电话发送短信
一.调用打电话界面 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat ...
- iOS程序中调用系统自带应用(短信,邮件,浏览器,地图,appstore,拨打电话,iTunes,iBooks )
在网上找到了下在记录下来以后方便用 在程序中调用系统自带的应用,比如我进入程序的时候,希望直接调用safar来打开一个网页,下面是一个简单的使用:
- Java乔晓松-android中调用系统拍照功能并显示拍照的图片
android中调用系统拍照功能并显示拍照的图片 如果你是拍照完,利用onActivityResult获取data数据,把data数据转换成Bitmap数据,这样获取到的图片,是拍照的照片的缩略图 代 ...
- Cocos2d-x 3.x 在wp8中调用系统字体的解决方案
问题和解决方法: 在使用cocos2d-x设计游戏的时候,字体是个很重要的部分.如果游戏中对字体没有太多的要求,就可以使用平台系统自带的字体,可以节省游戏的尺寸,以及减小游戏运行时所占用的内存.当加载 ...
- Android中调用系统所装的软件打开文件(转)
Android中调用系统所装的软件打开文件(转) 在应用中如何调用系统所装的软件打开一个文件,这是我们经常碰到的问题,下面是我所用到的一种方法,和大家一起分享一下! 这个是打开文件的一个方法: /** ...
- C#在winform中调用系统控制台输出
在Winform程序中有时候调试会通过Console.Write()方式输出一些信息,这些信息是在Visual Studio的输出窗口显示. 所以就会想,能不能调用系统的Cmd窗口输出呢,经过一番查阅 ...
- iOS开发 调用系统相机和相册
调用系统相机和相册 (iPad,iPhone)打开相机:(iPad,iPhone)//先设定sourceType为相机,然后判断相机是否可用(ipod)没相机,不可用将sourceType设定为相片库 ...
- iOS开发 调用系统相机和相册 分类: ios技术 2015-03-30 15:52 65人阅读 评论(0) 收藏
调用系统相机和相册 (iPad,iPhone) 打开相机:(iPad,iPhone) //先设定sourceType为相机,然后判断相机是否可用(ipod)没相机,不可用将sourceType设定为 ...
随机推荐
- Codeforces Round #335 (Div. 1) C. Freelancer's Dreams 计算几何
C. Freelancer's Dreams Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.codeforces.com/contes ...
- hdu 5594 ZYB's Prime 最大流
ZYB's Prime Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5 ...
- [Angular2 Router] Configuring a Home Route and Fallback Route - Learn An Essential Routing Concept
In this tutorial we are going to learn how to configure the Angular 2 router to cover some commonly ...
- JS的setTimeout函数第一个参数问题
setTimeout的第一个参数只能放一个无参的函数,更像放了一个函数指针在那里,如果要放带参数的话,就要拿个匿名函数包裹一下
- Linux下的Libsvm使用历程录
原文:http://blog.csdn.net/meredith_leaf/article/details/6714144 Linux下的Libsvm使用历程录 首先下载Libsvm.Python和G ...
- 基于ARM-LINUX的温度传感器驱动-DS18B20
转载:http://blog.csdn.net/ayangke/article/details/6883244 作者:冯建,华清远见嵌入式学院讲师. DS18B20数字温度传感器接线方便,封装成后可应 ...
- C#.Net中的转义字符(转)
当声明一个字符串变量时有一些字符是不能以平常的方式包含在变量中的.为了解决这个问题,C#提供了两种不同的方法. 第一种方法是使用’转义序列’.例如,我们想得到如下的字符串 “Hello World H ...
- iOS (catagroy)类别
1:可以为类添加新的方法,但不能添加实例变量. 2:第一,无法向类中添加新的实例变量.类别没有位置容纳实例变量. 第二,名称冲突,即类别中的方法与现有的方法重名.当发生名称冲突时,类别具有更高的优先级 ...
- [Java] SSH框架笔记_框架分析+环境搭建+实例源码下载
首先,SSH不是一个框架,而是多个框架(struts+spring+hibernate)的集成,是目前较流行的一种Web应用程序开源集成框架,用于构建灵活.易于扩展的多层Web应用程序. 集成SSH框 ...
- 转js contains 方法
function Jcontains(root, el) { if (root.compareDocumentPosition) return root === el || !!(root.compa ...