最近做的项目中,用到了录音的功能,简单记录一下。

我的想法是:通过重写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中调用系统录音功能及其播放的更多相关文章

  1. IOS中调用系统的电话、短信、邮件、浏览功能

    iOS开发系列--通讯录.蓝牙.内购.GameCenter.iCloud.Passbook系统服务开发汇总 2015-01-13 09:16 by KenshinCui, 26990 阅读, 35 评 ...

  2. IOS中调用系统拨打电话发送短信

    一.调用打电话界面 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat ...

  3. iOS程序中调用系统自带应用(短信,邮件,浏览器,地图,appstore,拨打电话,iTunes,iBooks )

    在网上找到了下在记录下来以后方便用 在程序中调用系统自带的应用,比如我进入程序的时候,希望直接调用safar来打开一个网页,下面是一个简单的使用:

  4. Java乔晓松-android中调用系统拍照功能并显示拍照的图片

    android中调用系统拍照功能并显示拍照的图片 如果你是拍照完,利用onActivityResult获取data数据,把data数据转换成Bitmap数据,这样获取到的图片,是拍照的照片的缩略图 代 ...

  5. Cocos2d-x 3.x 在wp8中调用系统字体的解决方案

    问题和解决方法: 在使用cocos2d-x设计游戏的时候,字体是个很重要的部分.如果游戏中对字体没有太多的要求,就可以使用平台系统自带的字体,可以节省游戏的尺寸,以及减小游戏运行时所占用的内存.当加载 ...

  6. Android中调用系统所装的软件打开文件(转)

    Android中调用系统所装的软件打开文件(转) 在应用中如何调用系统所装的软件打开一个文件,这是我们经常碰到的问题,下面是我所用到的一种方法,和大家一起分享一下! 这个是打开文件的一个方法: /** ...

  7. C#在winform中调用系统控制台输出

    在Winform程序中有时候调试会通过Console.Write()方式输出一些信息,这些信息是在Visual Studio的输出窗口显示. 所以就会想,能不能调用系统的Cmd窗口输出呢,经过一番查阅 ...

  8. iOS开发 调用系统相机和相册

    调用系统相机和相册 (iPad,iPhone)打开相机:(iPad,iPhone)//先设定sourceType为相机,然后判断相机是否可用(ipod)没相机,不可用将sourceType设定为相片库 ...

  9. iOS开发 调用系统相机和相册 分类: ios技术 2015-03-30 15:52 65人阅读 评论(0) 收藏

     调用系统相机和相册 (iPad,iPhone) 打开相机:(iPad,iPhone) //先设定sourceType为相机,然后判断相机是否可用(ipod)没相机,不可用将sourceType设定为 ...

随机推荐

  1. vi 命令 使用方法

    一.Unix编辑器概述       编辑器是使用计算机的重要工具之中的一个,在各种操作系统中,编辑器都是不可缺少的部件.Unix及其类似的ix 操作系统系列中,为方便各种用户在各个不同的环境中使用,提 ...

  2. php-cli模式学习(PHP命令行模式)(转)

    之前知道php—cli模式是一种类似shell命令式的执行php程序,不过一直以为这个是一种落后的方式,应该没有什么意义,因为从没有遇到过使用这个cli模式编程的.不过今天遇到了使用cli模式的应用. ...

  3. javascript Arguments对象——函数的实际参数

    在javascript函数体内,标识符arguments具有特殊含义.它是调用对象的一个特殊属性,用来引用Arguments对象.Arugments对象就像数组,注意这里只是像并不是哈. javasc ...

  4. iLinuxBot: Designing Botnets to Manage Linux Clients

    转:http://www.linuxforu.com/2012/05/ilinuxbot-designing-botnets-to-manage-linux-clients/ By Nishant S ...

  5. Java最重要的21个技术点和知识点之JAVA基础

     (一)Java最重要的21个技术点和知识点之JAVA基础  写这篇文章的目的是想总结一下自己这么多年JAVA培训的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享给刚刚入门的Ja ...

  6. sqoop1.99.4安装与简介

    1.什么是sqoop clouder公司开发的一个在关系数据库和hdfs,hive之间数据导入导出的一个工具 2.版本及其区别 现在分为sqoop1和sqoop2 1)架构图(sqoop1和hadoo ...

  7. Solr高亮显示highlight的三种实现

    高亮显示在搜索中使用的比较多,比较常用的有三种使用方式,如果要对某field做高亮显示,必须对该field设置stored=true      第一种是普通的高亮显示Highlighter,根据查询的 ...

  8. nodejs学习第一天

    //按照nodejs文档上第一页的例子敲了一遍运行了 迷茫 先这样吧 慢慢来 const http = require('http'); const host = '127.0.0.1'; const ...

  9. sphinx-2.2.10-1.rhel6.x86_64 rpm包安装的位置

    /etc/logrotate.d/sphinx /etc/rc.d/init.d/searchd/etc/sphinx/etc/sphinx/sphinx.conf/usr/bin/indexer/u ...

  10. 【MYSQL】常用命令备忘录

    source 不接路径时,查找文件的路径是执行mysql命令时的路径 接路径时,使用路径+filename [root@wordpressserver mysql]# vi demo.mysql [r ...