iOS录音实践

在AVFoundation框架中AVAudioRecorder类专门处理录音操作,支持多种音频格式。下面是常用的属性和方法:

属性 说明
@property(readonly, getter=isRecording) BOOL recording; 是否正在录音,只读
@property(readonly) NSURL *url 录音文件地址,只读
@property(readonly) NSDictionary *settings 录音文件设置,只读
@property(readonly) NSTimeInterval currentTime 录音时长,只读,注意仅仅在录音状态可用
@property(readonly) NSTimeInterval deviceCurrentTime 输入设置的时间长度,只读,注意此属性一直可访问
@property(getter=isMeteringEnabled) BOOL meteringEnabled; 是否启用录音测量,如果启用录音测量可以获得录音分贝等数据信息
@property(nonatomic, copy) NSArray *channelAssignments 当前录音的通道
对象方法 说明
- (instancetype)initWithURL:(NSURL *)url settings:(NSDictionary *)settings error:(NSError **)outError 录音机对象初始化方法,注意其中的url必须是本地文件url,settings是录音格式、编码等设置
- (BOOL)prepareToRecord 准备录音,主要用于创建缓冲区,如果不手动调用,在调用record录音时也会自动调用
- (BOOL)record 开始录音
- (BOOL)recordAtTime:(NSTimeInterval)time 在指定的时间开始录音,一般用于录音暂停再恢复录音
- (BOOL)recordForDuration:(NSTimeInterval) duration 按指定的时长开始录音
- (BOOL)recordAtTime:(NSTimeInterval)time forDuration:(NSTimeInterval) duration 在指定的时间开始录音,并指定录音时长
- (void)pause; 暂停录音
- (void)stop; 停止录音
- (BOOL)deleteRecording; 删除录音,注意要删除录音此时录音机必须处于停止状态
- (void)updateMeters; 更新测量数据,注意只有meteringEnabled为YES此方法才可用
- (float)peakPowerForChannel:(NSUInteger)channelNumber; 指定通道的测量峰值,注意只有调用完updateMeters才有值
- (float)averagePowerForChannel:(NSUInteger)channelNumber 指定通道的测量平均值,注意只有调用完updateMeters才有值
代理方法 说明
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag 完成录音
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error 录音编码发生错误

AVAudioRecorder创建录音机时除了指定路径外还必须指定录音设置信息,因为录音机必须知道录音文件的格式、采样率、通道数、每个采样点的位数等信息,通常只需要几个常用设置。关于录音设置详见帮助文档中的“AV
Foundation Audio Settings Constants
”。

以下代码实现录音,暂停,继续,取消,停止,播放功能。

#import "ViewController.h"

#import <AVFoundation/AVFoundation.h>

#define kAudioFileName @"test.caf"

@interface ViewController ()<AVAudioRecorderDelegate>

@property (nonatomic,strong) AVAudioRecorder *audioRecorder; //音频录音机
@property (nonatomic,strong) AVAudioPlayer *audioPlayer;     //音频播放器
@property (nonatomic,strong) NSTimer *timer;            //录音监控

@property (weak, nonatomic) IBOutlet UIProgressView *audioPower;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setAudioSession];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/**
 *  设置音频会话
 */
-(void)setAudioSession{
    AVAudioSession *audioSession=[AVAudioSession sharedInstance];
    //设置为播放和录音状态,以便可以在录制完之后播放录音
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
    [audioSession setActive:YES error:nil];
}

/**
 *  录音文件设置
 *
 *  @return 返回录音设置
 */
- (NSDictionary *)getAudioSetting
{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    [dic setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];  //设置录音格式
    [dic setObject:@(8000) forKey:AVSampleRateKey];                 //设置采样率
    [dic setObject:@(1) forKey:AVNumberOfChannelsKey];              //设置通道,这里采用单声道
    [dic setObject:@(8) forKey:AVLinearPCMBitDepthKey];             //每个采样点位数,分为8,16,24,32
    [dic setObject:@(YES) forKey:AVLinearPCMIsFloatKey];            //是否使用浮点数采样
    return dic;
}

/**
 *  录音存储路径
 *
 *  @return 返回存储路径
 */
- (NSURL *)getSavePath
{
    NSString *url = [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask,YES) lastObject];
    url = [url stringByAppendingPathComponent:kAudioFileName];
    return [NSURL URLWithString:url];
}

- (NSTimer *)timer
{
    if (!_timer) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(audioPowerChange) userInfo:nil repeats:YES];
    }
    return _timer;
}

- (AVAudioRecorder *)audioRecorder
{
    if (!_audioRecorder) {
        NSError *error = nil;
        _audioRecorder = [[AVAudioRecorder alloc] initWithURL:[self getSavePath] settings:[self getAudioSetting] error:&error];
        _audioRecorder.delegate = self;
        _audioRecorder.meteringEnabled = YES; //是否启用录音测量,如果启用录音测量可以获得录音分贝等数据信息
        if (error) {
            NSLog(@"创建录音机对象发生错误:%@",error.localizedDescription);
            return nil;
        }
    }
    return _audioRecorder;
}

- (AVAudioPlayer *)audioPlayer
{
    if (!_audioPlayer) {
        NSError *error = nil;
        _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[self getSavePath] error:&error];
        if (error) {
            NSLog(@"创建音频播放器对象发生错误:%@",error.localizedDescription);
            return nil;
        }
    }
    return _audioPlayer;
}

#pragma mark -
#pragma mark - AVAudioRecorderDelegate
//录音成功
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
    if (![self.audioPlayer isPlaying]) {
        [self.audioPlayer play];
    }
}
//录音失败
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error
{

}

#pragma mark -
#pragma mark - Action

- (void)audioPowerChange{
    [self.audioRecorder updateMeters];  //更新测量值
    float power = [self.audioRecorder averagePowerForChannel:1]; //取得第一个通道的音频,注意音频强度范围时-160到0
    self.audioPower.progress = (1.0/160)*(power+160);
}

/**
 *  点击录音按钮
 *
 *  @param sender 录音按钮
 */
- (IBAction)startRecord:(id)sender {

    if (![self.audioRecorder isRecording]) {
        [self.audioRecorder record];
        self.timer.fireDate = [NSDate distantPast];
    }
}

/**
 *  点击取消录音按钮
 *
 *  @param sender 取消录音按钮
 */
- (IBAction)cancelRecord:(id)sender {
    self.audioRecorder.delegate = nil;
    if ([self.audioRecorder isRecording]) {
       [self.audioRecorder stop];
    }
    self.audioRecorder = nil;
}

/**
 *  点击暂定按钮
 *
 *  @param sender 暂停按钮
 */
- (IBAction)pause:(id)sender {
    if ([self.audioRecorder isRecording]) {
        [self.audioRecorder pause];
        self.timer.fireDate = [NSDate distantFuture];
    }
}

/**
 *  点击恢复按钮
 *  恢复录音只需要再次调用record,AVAudioSession会帮助你记录上次录音位置并追加录音
 *
 *  @param sender 恢复按钮
 */
- (IBAction)goon:(id)sender {
    [self startRecord:nil];
}

/**
 *  点击停止按钮
 *
 *  @param sender 停止按钮
 */
- (IBAction)stop:(id)sender {
    if ([self.audioRecorder isRecording]) {
        [self.audioRecorder stop];
        self.timer = [NSDate distantFuture];
    }
}

/**
 *  点击播放按钮
 *
 *  @param sender 播放按钮
 */
- (IBAction)play:(id)sender {

    if (![self.audioPlayer isPlaying]) {
        [self.audioPlayer play];
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 10:42:12

iOS录音实践的相关文章

(转)iOS 最佳实践

本文转自http://www.jianshu.com/p/b0bf2368fb95 感谢作者和译者 iOS最佳实践 iOS最佳实践 译者注 本文翻译自 futurice 公司的 iOS Good Practices,译文在 Github 上进行维护,同时在简书 上进行发布. 本文发出几天后发现网上也有了另外一个翻译版本:http://ios.jobbole.com/81830/ 原标题是iOS Good Practices,应该翻译成 iOS 良好实践/优秀实践的,不过好拗口,而且已经发出去了,

iOS 开发实践之 Auto Layout

原:http://xuexuefeng.com/autolayout/?utm_source=tuicool 本文是博主 iOS 开发实践系列中的一篇,主要讲述 iOS 中 Auto Layout(自动布局)在实际项目中的使用. Auto Layout 在 2012 年的 iOS 6 中发布,距今已经 2 年多了,如果从 2011 年在 Mac OS X 上发布的 Auto Layout 开始算起,已经超过 3 年了.如果你的简历上写着 2 年以上工作经验,而竟然不会使用 Auto Layout

iOS 开发实践之Auto Layout(From Vincent Sit)

本文是博主 iOS 开发实践系列中的一篇,主要讲述 iOS 中 Auto Layout(自动布局)在实际项目中的使用. Auto Layout 在 2012 年的 iOS 6 中发布,距今已经 2 年多了,如果从 2011 年在 Mac OS X 上发布的 Auto Layout 开始算起,已经超过 3 年了.如果你的简历上写着 2 年以上工作经验,而竟然不会使用 Auto Layout,真有点不可思议. 本文将会通过若干个 Demo 进行讲解,通过实践来理解 Auto Layout 到底是什么

iOS开发实践之GET和POST请求

iOS开发实践之GET和POST请求 GET和POST请求是HTTP请求方式中最最为常见的.在说请求方式之前先熟悉HTTP的通信过程: 请求 1.请求行 : 请求方法.请求路径.HTTP协议的版本 GET /MJServer/resources/images/1.jpg HTTP/1.1 2.请求头 : 客户端的一些描述信息 Host: 192.168.1.111:8080 // 客户端想访问的服务器主机地址 User-Agent: Mozilla/5.0 (Macintosh; Intel M

IOS PUSH 实践操作~~~~

1.推送过程简介 (1)App启动过程中,使用UIApplication::registerForRemoteNotificationTypes函数与苹果的APNS服务器通信,发出注册远程推送的申请.若注册成功,回调函数application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 会被触发,App可以得到deviceToken,该tok

Swift实现iOS录音与播放音频功能

作用AVPLayer:可以用来播放在线及本地音视频AVAudioSession:音频会话,主要用来管理音频设置与硬件交互使用时需要导入 #import <AVFoundation/AVFoundation.h> AVAudioSession中配置选项: AVAudioSessionCategory 注意:除了 AVAudioSessionCategoryMultiRoute 外,其他的 Category 都遵循 last in wins 原则,即最后接入的音频设备作为输入或输出的主设备. 1.

iOS代码实践总结

转载地址:http://mobile.51cto.com/hot-492236.htm 最近一个月除了专门抽时间和精力重构之外,还有就是遇到需要添加功能的模块的时候,由于项目中的代码历史因素比较多,第一件干的事情往往是重构整理代码,发现很多之前的代码写的时候没有注意的事情特别多,比如全局变量乱用:方法没有层次感,胡乱添加:对业务不了解的情况下,通过打补丁的方式实现功能等等. AD: 前几个月完成对MVVM/RAC的学习之后,最近一直在默默地对项目代码进行重构,写码比较多,过了一段时间回头发现自己

iOS录音和播放的那些事儿:几个奇葩的需求

最近在做的项目中,需要在iPhone上接上带麦耳机(苹果叫Headset,不带麦耳机叫Headphone),然后实现同步录音和播放.这个功能实现之后,需要改变录音.播放的输入源. 对于实现同步录音和播放功能,肯定就要使用到底层的接口,用AVAudioRecorder/AVAudioPlayer是无法实现的. 我研究了iOS声音处理的知识之后,发现自己实现太过麻烦,需要用到至少包括AudioQueue/AudioBuffer等等,然后还有各种复杂的C Struct.回调函数.回调处理等等,非常麻烦

2015-03 iOS最佳实践

一.为什么阅读本文档 跳 进了 iOS 的坑真是麻烦.无论是 Swift 还是 Objective-C, 都没有在其他地方广泛使用,而且这个平台对每个东西都几乎有它自己的命名方式,并且连要在真机上调试都充满了坎坷.无论你是刚刚入门 Cocoa 还是想纠正自己开发习惯的开发者,都能从本文档获益.不过下面写的仅仅是建议,所以如果你有一个更好的方案,那就试试吧! 二.入门 Xcode Xcode 是大多数 iOS 开发者的选择,并且是 Apple 唯一官方支持的IDE.有一些其他的选择,比如 AppC