播放和录制音频
1.理解音频会话
默认音频会话的预配置:
- 激活了音频播放,但是音频录制未激活
- 当用户切换响铃/静音开关到“静音”模式时,应用程序所播放的所有音频都会消失
- 当设备显示解锁屏幕时,应用程序的音频处于静音状态
- 当应用程序播放音频是,所有后台播放的音频都睡处于静音状态
音频会话的分类
分类 | 作用 | 是否允许混音 | 音频输入 | 音频输出 |
---|---|---|---|---|
Ambient | 游戏效率应用程序 | √ | √ | |
Solo Ambient(默认) | 游戏效率应用程序 | √ | ||
Playback | 音频和视频播放器 | 可选 | √ | |
Record | 录音机、音频捕捉 | √ | ||
Play and Record | VoIP、语音聊天 | 可选 | √ | √ |
Audio Processing | 离线会话和处理 | |||
Multi-Route | 使用外部硬件的高级A/V应用程序 | √ | √ |
配置音频会话
//在AppDelegate.m中的application:didFinishLaunchingWithOptions:中
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
2.使用AVAudioPlayer播放本地音频
AVAudioPlayer
- volume:播放音量
- pan:立体播放声音,-1.0左声道,1.0右声道
- rate:播放速度
- numberOfLoops:播放次数,-1时无限循环播放
简单播放
NSError *error = nil;
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if(!error){
[player prepareToPlay];
[player play];
}
处理中断事件
播放音乐是可能会有电话各种情况中断播放
//监听中断通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
//判断中断类型并处理中断
- (void)handleInterruption:(NSNotification *)notification {
NSDictionary *info = notification.userInfo;
AVAudioSessionInterruptionType type = [info[AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
if(type == AVAudioSessionInterruptionTypeBegan){
//停止播放
[self stop];
}else {
AVAudioSessionInterruptionOptions options = [info[AVAudioSessionInterruptionOptionKey] unsignedIntegerValue];
if(options == AVAudioSessionInterruptionOptionShouldResume){
//恢复播放
[self play];
}
}
}
耳机和扬声器的切换
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleRouteChange:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
- (void)handleRouteChange:(NSNotification *)notification {
NSDictionary *info = notification.userInfo;
AVAudioSessionRouteChangeReason reason = [info[AVAudioSessionRouteChangeReasonKey] unsignedIntegerValue];
if(reason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
AVAudioSessionRouteDescription *previousRoute = info[AVAudioSessionRouteChangePreviousRouteKey];
AVAudioSessionPortDescription *previousOutput = previousRoute.outputs[0];
NSString *portType = previousOutput.portType;
//拔掉耳机的时候停止播放
if([portType isEqualToString:AVAudioSessionPortHeadphones]){
[self stop];
}
}
}
设置后台播放:需要在plist文件里Required background modes添加App plays audio or streams audio/video using AirPlay
注:如果需要播放网络音乐可以使用AVPlayer这里不做过多介绍
3.使用AVAudioRecorder录制音频
创建AVAudioRecorder需要的参数
- 用于标识音频流写入文件的本地文件URL
- 包含用于配置录音会话键值信息的字典对象
- 用于捕捉初始化阶段各种错误的NSError对象
//录音保存文件的地址
NSURL *url = [NSURL URLWithString:@"..."];
//配置参数
NSDictionary *settings = @{AVFormatIDKey:@(kAudioFormatMPEG4AAC),
AVSampleRateKey:@44100.0f,
AVNumberOfChannelsKey:@1,
AVEncoderBitRateKey:@16,
AVEncoderAudioQualityKey:@(AVAudioQualityMedium)};
NSError *error = nil;
_recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
if(!error){
//准备录音
[_recorder prepareToRecord];
//开始录音
[_recorder record];
}
常用配置参数的介绍
- AVFormatIDKey:音频格式,常用kAudioFormatMPEG4AAC,也可根据需要自行选择,这个格式需要与保存文件的格式相一致
- AVSampleRateKey:采样率,一般分为8000、16000、22050和44100,使用44100较多
- AVNumberOfChannelsKey:记录音频内容的通道数,1为单声道,2为立体声录音
4.使用Audio Metering显示声音的分贝大小
AVAudioPlayer和AVAudioRecorder最强大和最实用的功能就是对音频进行测量,使用时需要将meteringEnabled属性设置为YES
两个类使用的方法都是averagePowerForChannel:和peakPowerForChannel:,两个方法返回一个用于表示声音分贝(dB)等级的浮点值,这个值得范围是最大分贝0Db到最小分贝或静音的-160dB