iOS 使用AVAudioPlayer开发录音功能
2014-08-18 17:03
274 查看
最近要做一个类似对讲的功能,所以需要用到录音上传,然后再播放的功能。
一、音频格式分析
因为之前没研究过音频这块,所以很多音频格式都是第一次见。
AAC:
AAC其实是“高级音频编码(advanced audio coding)”的缩写,它是被设计用来取代MP3格式的。你可能会想,它压缩了原始的声音,导致容量占用少但是质量肯定会有所下降。不过这些质量的损失 取决于声音比特率的大小,当比特率合适的时候,这些损失人耳是很难听出来的。事实上,aac比mp3有更好的压缩率,特别是在比特率低于128bit/s 的时候。
HE-AAC:
HE-AAC是AAC的一个超集,这个“HE”代表的是“High efficiency”。 HE-AAC是专门为低比特率所优化的一种音频编码格式,比如streaming audio就特别适合使用这种编码格式。
AMR:
AMR全称是“Adaptive Multi-Rate”,它也是另一个专门为“说话(speech)”所优化的编码格式,也是适合低比特率环境下采用。
ALAC:
它全称是“Apple Lossless”,这是一种没有任何质量损失的音频编码方式,也就是我们说的无损压缩。在实际使用过程中,它能够压缩40%-60%的原始数据。这种编码格式的解码速度非常快,这对iphone或者ipod这种小型设备来说非常适合。
iLBC:
这是另一种专门为说话所设计的音频编码格式,它非常适合于IP电话等其它需要流式音频的场合。
IMA4:
这是一个在16-bit音频文件下按照4:1的压缩比来进行压缩的格式。这是iphone上面一种非常重要的编码格式。
它的中文意思是基于线性脉冲编码调制,用于将模拟声音数据转换成数字声音数据。简而言之,就是意味着无压缩数据。由于数据是非压缩的,它可以非常快的播放,并且当空间不是问题时,这是在iphone上面首选的音频编码方式。
μ-law
and a-law: 就我所知道的,这种编码是交替的编码模拟数据为数字格式数据,但是在speech优化方面比linear PCM更好。
MP3:
这种格式是我们都知道也喜欢的,虽然很多年过去了,但MP3到目前为止仍然是一种非常流行的编码格式,它也能被iphone很好地支持。
LPCM也很早就被定义在DVD播放机
的标准内,为了和CD有所区别,DVD的的采样规格为16bit/48KHz,随着技术的发展,DVD的的采样规格更提升到24bit/96KHz,以达 到更高的播放品质,用96KHz/24bit方式记录的音频信号所能达到的频率上限是96÷2= 48KHz,而它的最大动态范围将可以达到24×6=144dB。从指标上就可以看出:它的声音比CD要好得多。pcm编码的最大的优点就是音质好,最大的缺点就是体数据量大。
录制音频需要选择音频的编码方式以及文件的格式。因为这个功能是项目中新添加的,所以格式和编码方式都还没有确定,所以我也只是写了个小Demo测试一下。所以我用的是aac的文件格式,而编码方式的话,因为在网上找到一些这样的说法:
文件格式选好以后,还是有很多的参数可以自己设定的,比特率、采样率和位宽等。当然,选用合适的音频格式还是比较重要,因为不同的格式之间文件大小差异还是比较明显的。就以AAC和LPCM对比为例,采样率同为44100Hz,默认的AAC一分钟的大小约为500kB,但是16bit位宽的LPCM就可以达到5MB。但作为我用于录音的用途,这么大的录音文件,估计录不了多少,用户就会骂我的程序怎么占用这么多空间了。录音务求能够听得出咬字清晰,不需要追求无损的音质。因此,我就选择了AAC格式,同时更小的空间占用也便于上传。
所以呢,我也选择aac的这些参数测试了一下,录制20多秒的音频,文件大小差不多是200多KB,非常小。
二、代码部分
首先需要导入两个框架,AVFoundation.framework与CoreAudio.framework ,网上有的讲解是用另外两个框架,
AudioToolbox.framework 和AVFoundation.framework,其中导入AVFoundation.framework就够了,这里需要用到AVFoundation.framework
框架中的三个对象,AVAudioRecorder、AVAudioPlayer、AVAudioSession 。
录音的大致过程是:先设置AVAudioSession的参数,录音的时候配置AVAudioRecorder的设置,然后开始录音。
录音按钮的操作:
播放录音操作如下:
.h文件代码如下:
.m文件代码如下:
一、音频格式分析
因为之前没研究过音频这块,所以很多音频格式都是第一次见。
AAC:
AAC其实是“高级音频编码(advanced audio coding)”的缩写,它是被设计用来取代MP3格式的。你可能会想,它压缩了原始的声音,导致容量占用少但是质量肯定会有所下降。不过这些质量的损失 取决于声音比特率的大小,当比特率合适的时候,这些损失人耳是很难听出来的。事实上,aac比mp3有更好的压缩率,特别是在比特率低于128bit/s 的时候。
HE-AAC:
HE-AAC是AAC的一个超集,这个“HE”代表的是“High efficiency”。 HE-AAC是专门为低比特率所优化的一种音频编码格式,比如streaming audio就特别适合使用这种编码格式。
AMR:
AMR全称是“Adaptive Multi-Rate”,它也是另一个专门为“说话(speech)”所优化的编码格式,也是适合低比特率环境下采用。
ALAC:
它全称是“Apple Lossless”,这是一种没有任何质量损失的音频编码方式,也就是我们说的无损压缩。在实际使用过程中,它能够压缩40%-60%的原始数据。这种编码格式的解码速度非常快,这对iphone或者ipod这种小型设备来说非常适合。
iLBC:
这是另一种专门为说话所设计的音频编码格式,它非常适合于IP电话等其它需要流式音频的场合。
IMA4:
这是一个在16-bit音频文件下按照4:1的压缩比来进行压缩的格式。这是iphone上面一种非常重要的编码格式。
它的中文意思是基于线性脉冲编码调制,用于将模拟声音数据转换成数字声音数据。简而言之,就是意味着无压缩数据。由于数据是非压缩的,它可以非常快的播放,并且当空间不是问题时,这是在iphone上面首选的音频编码方式。
μ-law
and a-law: 就我所知道的,这种编码是交替的编码模拟数据为数字格式数据,但是在speech优化方面比linear PCM更好。
MP3:
这种格式是我们都知道也喜欢的,虽然很多年过去了,但MP3到目前为止仍然是一种非常流行的编码格式,它也能被iphone很好地支持。
LPCM也很早就被定义在DVD播放机
的标准内,为了和CD有所区别,DVD的的采样规格为16bit/48KHz,随着技术的发展,DVD的的采样规格更提升到24bit/96KHz,以达 到更高的播放品质,用96KHz/24bit方式记录的音频信号所能达到的频率上限是96÷2= 48KHz,而它的最大动态范围将可以达到24×6=144dB。从指标上就可以看出:它的声音比CD要好得多。pcm编码的最大的优点就是音质好,最大的缺点就是体数据量大。
录制音频需要选择音频的编码方式以及文件的格式。因为这个功能是项目中新添加的,所以格式和编码方式都还没有确定,所以我也只是写了个小Demo测试一下。所以我用的是aac的文件格式,而编码方式的话,因为在网上找到一些这样的说法:
文件格式选好以后,还是有很多的参数可以自己设定的,比特率、采样率和位宽等。当然,选用合适的音频格式还是比较重要,因为不同的格式之间文件大小差异还是比较明显的。就以AAC和LPCM对比为例,采样率同为44100Hz,默认的AAC一分钟的大小约为500kB,但是16bit位宽的LPCM就可以达到5MB。但作为我用于录音的用途,这么大的录音文件,估计录不了多少,用户就会骂我的程序怎么占用这么多空间了。录音务求能够听得出咬字清晰,不需要追求无损的音质。因此,我就选择了AAC格式,同时更小的空间占用也便于上传。
所以呢,我也选择aac的这些参数测试了一下,录制20多秒的音频,文件大小差不多是200多KB,非常小。
二、代码部分
首先需要导入两个框架,AVFoundation.framework与CoreAudio.framework ,网上有的讲解是用另外两个框架,
AudioToolbox.framework 和AVFoundation.framework,其中导入AVFoundation.framework就够了,这里需要用到AVFoundation.framework
框架中的三个对象,AVAudioRecorder、AVAudioPlayer、AVAudioSession 。
录音的大致过程是:先设置AVAudioSession的参数,录音的时候配置AVAudioRecorder的设置,然后开始录音。
录音按钮的操作:
- (IBAction)recordAction:(id)sender { AVAudioSession *audioSession = [AVAudioSession sharedInstance]; NSError *error1; [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error1]; if (toggle) { toggle = NO; [_startButton setTitle:@"停止" forState:UIControlStateNormal]; _playButton.enabled = toggle; _playButton.hidden = !toggle; 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:@"%@/%@.aac", strUrl,[self getCurrentTimeLong]]]; fileURL = url; [audioSession setActive:YES error:&error1]; //初始化 recorder = [[AVAudioRecorder alloc]initWithURL:url settings:recordSetting error:&error1]; //开启音量检测 recorder.meteringEnabled = YES; recorder.delegate = self; //the subsstems so that when we actually say "record" it starts right away. [recorder prepareToRecord]; //Start the actual Recording [recorder record]; } else{ toggle = YES; [audioSession setActive:NO error:&error1]; [_startButton setTitle:@"开始" forState:UIControlStateNormal ]; _playButton.enabled = toggle; _playButton.hidden = !toggle; NSLog(@"Using File called: %@",fileURL); //Stop the recorder. [recorder stop]; } }这里开始录音和结束录音都是同一个按钮。主要是设置AVAudioSession的活动状态。
播放录音操作如下:
- (IBAction)playAction:(id)sender { AVAudioSession *audioSession = [AVAudioSession sharedInstance]; NSError *error1; [audioSession setCategory:AVAudioSessionCategorySoloAmbient error:&error1]; [audioSession setActive:YES error:&error1]; // NSURL *URL = [[NSURL alloc] initWithString:[[NSBundle mainBundle] pathForResource:@"1408341057084" ofType:@"aac"]]; NSError *error3; avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error3]; avPlayer.volume = 1.0f; [avPlayer prepareToPlay]; [avPlayer play]; NSLog(@"duration:%f",avPlayer.duration); }这里当时遇到一个问题,一开始avPlayer 我是在该方法里中初始化的,结果还没有开始播放就已经被释放咯,因为用的arc。然后改成实例变量之后,就OK咯。
.h文件代码如下:
#import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> #import <CoreAudio/CoreAudioTypes.h> @interface RootViewController : UIViewController<AVAudioRecorderDelegate> { BOOL toggle; NSURL *fileURL; AVAudioRecorder *recorder; NSError *error; AVAudioPlayer * avPlayer; } @property (weak, nonatomic) IBOutlet UIButton *startButton; @property (weak, nonatomic) IBOutlet UIButton *playButton; - (IBAction)recordAction:(id)sender; - (IBAction)playAction:(id)sender; @end
.m文件代码如下:
//
// RootViewController.m
// Audio_Test
//
// Created by MacOS on 14-8-18.
// Copyright (c) 2014年 MacOS. All rights reserved.
//
#import "RootViewController.h"
@interface RootViewController ()
@end
@implementation RootViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
toggle = YES;
_playButton.hidden = YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)recordAction:(id)sender { AVAudioSession *audioSession = [AVAudioSession sharedInstance]; NSError *error1; [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error1]; if (toggle) { toggle = NO; [_startButton setTitle:@"停止" forState:UIControlStateNormal]; _playButton.enabled = toggle; _playButton.hidden = !toggle; 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:@"%@/%@.aac", strUrl,[self getCurrentTimeLong]]]; fileURL = url; [audioSession setActive:YES error:&error1]; //初始化 recorder = [[AVAudioRecorder alloc]initWithURL:url settings:recordSetting error:&error1]; //开启音量检测 recorder.meteringEnabled = YES; recorder.delegate = self; //the subsstems so that when we actually say "record" it starts right away. [recorder prepareToRecord]; //Start the actual Recording [recorder record]; } else{ toggle = YES; [audioSession setActive:NO error:&error1]; [_startButton setTitle:@"开始" forState:UIControlStateNormal ]; _playButton.enabled = toggle; _playButton.hidden = !toggle; NSLog(@"Using File called: %@",fileURL); //Stop the recorder. [recorder stop]; } }
/**
* 播放录音
*
* @param sender 播放按钮
*/
- (IBAction)playAction:(id)sender { AVAudioSession *audioSession = [AVAudioSession sharedInstance]; NSError *error1; [audioSession setCategory:AVAudioSessionCategorySoloAmbient error:&error1]; [audioSession setActive:YES error:&error1]; // NSURL *URL = [[NSURL alloc] initWithString:[[NSBundle mainBundle] pathForResource:@"1408341057084" ofType:@"aac"]]; NSError *error3; avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error3]; avPlayer.volume = 1.0f; [avPlayer prepareToPlay]; [avPlayer play]; NSLog(@"duration:%f",avPlayer.duration); }
- (NSString *)getCurrentTimeLong
{
NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval a=[dat timeIntervalSince1970]*1000;
//为字符型
NSString *timeString = [NSString stringWithFormat:@"%f", a];
return [timeString substringToIndex:13];
}
@end
相关文章推荐
- iOS 使用AVAudioPlayer开发录音功能
- iOS 开发 初级:AVAudioPlayer 的使用
- iOS开发 - 滑动控制屏幕亮度和系统音量(附加AVAudioPlayer基本用法和Masonry简单使用)
- IOS开发之AVAudioPlayer的基本使用
- iOS开发之录音和播放问题AVAudioPlayer
- iOS开发之AVAudioPlayer 音频播放
- AVAudioPlayer音频播放器—IOS开发
- iOS开发之AVAudioPlayer 音频播放
- 【iOS开发-94】xcode6怎么使用GIT以及如何给老得项目增加GIT功能?
- AVAudioPlayer音频播放器—IOS开发
- iOS开发之AVAudioPlayer 音频播放
- AVAudioPlayer音频播放器—IOS开发
- IOS-使用AVAudioPlayer播放音乐文件
- IOS开发之使用Speex格式实现简单的语音聊天功能(二)
- iOS开发之AVAudioPlayer 音频播放
- iOS开发的一些小技术:让UIImage有缩放功能、控制log的输出、xcode修改文件注释、随机数的使用、在UIImageView 中旋转图像、在Quartz中如何设置旋转点、创建.plist文件并存储
- AVAudioPlayer音频播放器—IOS开发
- AVAudioPlayer音频播放器—IOS开发
- iOS开发之AVAudioPlayer 音频播放
- AVAudioPlayer音频播放器—IOS开发