AVAudioSession简介
AVAudioSession是用来管理多个APP对音频硬件设备(麦克风,扬声器)的资源使用。
AVAudioSession 可以用来做哪些事呢?
- 设置自己APP是否和其他APP音频同时存在,还是中断其他APP声音
- 在手机调到静音模式下,自己的APP的音频是否可以播放出声音
- 电话或者其他APP中断自己APP的音频的事件处理
- 指定音频输入和输出设备(比如是听筒输出声音,还是扬声器输出声音)
- 是否支持录音,录音同时是否支持音频播放
AVAudioSession Category 属性
1、使用案例:
AVAudioSession * audioSession = [AVAudioSession sharedInstance]; // 设置 Category属性 [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; // 激活 AVAudioSession [audioSession setActive:YES error:nil];
category | 是否允许录音/音频播放 | 是否打断其他不支持混音APP | 是否会被静音键或锁屏键静音 |
---|---|---|---|
AVAudioSessionCategoryAmbient | 只支持播放 | 否 | 是 |
AVAudioSessionCategoryAudioProcessing | 不支持播放,不支持录制 | 是 | 否 |
AVAudioSessionCategoryMultiRoute | 支持播放,支持录制 | 是 | 否 |
AVAudioSessionCategoryPlayAndRecord | 支持播放,支持录制 | 默认YES,可以重写为NO | 否 |
AVAudioSessionCategoryPlayback | 只支持播放 | 默认YES,可以重写为NO | 否 |
AVAudioSessionCategoryRecord | 只支持录制 | 是 | 否(锁屏下仍可录制) |
AVAudioSessionCategorySoloAmbient | 只支持播放 | 是 | 是 |
2、参数解释说明:
- AVAudioSessionCategoryAmbient,只支持音频播放。这个 Category,音频会被静音键和锁屏键静音。并且不会打断其他应用的音频播放。
- AVAudioSessionCategorySoloAmbient,这个是系统默认使用的 Category,只支持音频播放。音频会被静音键和锁屏键静音。和AVAudioSessionCategoryAmbient不同的是,这个会打断其他应用的音频播放
- AVAudioSessionCategoryPlayback 只支持音频播放。你的音频不会被静音键和锁屏键静音。适用于音频是主要功能的APP,像网易云这些音乐app,锁屏后依然可以播放。
- AVAudioSessionCategoryRecord 只支持音频录制。不支持播放。
- AVAudioSessionCategoryPlayAndRecord 支持音频播放和录制。音频的输入和输出不需要同步进行,也可以同步进行。需要音频通话类应用,可以使用这个 Category。
- AVAudioSessionCategoryAudioProcessing 只支持本地音频编解码处理。不支持播放和录制。
- AVAudioSessionCategoryMultiRoute 支持音频播放和录制。允许多条音频流的同步输入和输出。(比如USB连接外部扬声器输出音频,蓝牙耳机同时播放另一路音频这种特殊需求)
3、获取当前设置支持的Category:
@property(readonly) NSArray *availableCategories;
AVAudioSession Mode 属性
1、方法展示
-(BOOL)setCategory:(NSString *)category mode:(NSString *)mode options:(AVAudioSessionCategoryOptions)options error:(NSError **)outError API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0));
2、参数说明
模式 | 兼容的 Category | 场景 |
---|---|---|
AVAudioSessionModeDefault | All | 默认模式 |
AVAudioSessionModeVoiceChat | AVAudioSessionCategoryPlayAndRecord | VoIP |
AVAudioSessionModeGameChat | AVAudioSessionCategoryPlayAndRecord | 游戏录制,GKVoiceChat自动设置 |
AVAudioSessionModeVideoRecording | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord | 录制视频 |
AVAudioSessionModeMoviePlayback | AVAudioSessionCategoryPlayback | 视频播放 |
AVAudioSessionModeMeasurement | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayback | 最小系统 |
AVAudioSessionModeVideoChat | AVAudioSessionCategoryPlayAndRecord | 视频通话 |
3、参数解释
- AVAudioSessionModeDefault,默认模式,与所有的 Category 兼容
- AVAudioSessionModeVoiceChat,适用于VoIP 类型的应用。只能是 AVAudioSessionCategoryPlayAndRecord Category下。在这个模式系统会自动配置AVAudioSessionCategoryOptionAllowBluetooth 这个选项。系统会自动选择最佳的内置麦克风组合支持语音聊天。
- AVAudioSessionModeVideoChat,用于视频聊天类型应用,只能是 AVAudioSessionCategoryPlayAndRecord Category下。适在这个模式系统会自动配置 AVAudioSessionCategoryOptionAllowBluetooth 和 AVAudioSessionCategoryOptionDefaultToSpeaker 选项。系统会自动选择最佳的内置麦克风组合支持视频聊天。
- AVAudioSessionModeGameChat,适用于游戏类应用。使用 GKVoiceChat 对象的应用会自动设置这个模式和 AVAudioSessionCategoryPlayAndRecord Category。实际参数和AVAudioSessionModeVideoChat一致。
- AVAudioSessionModeVideoRecording,适用于使用摄像头采集视频的应用。只能是 AVAudioSessionCategoryPlayAndRecord 和 AVAudioSessionCategoryRecord 这两个 Category下。这个模式搭配 AVCaptureSession API 结合来用可以更好地控制音视频的输入输出路径。(例如,设置 automaticallyConfiguresApplicationAudioSession 属性,系统会自动选择最佳输出路径。
- AVAudioSessionModeMeasurement,最小化系统。只用于 AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryRecord、AVAudioSessionCategoryPlayback 这几种 Category。
- AVAudioSessionModeMoviePlayback,适用于播放视频的应用。只用于 AVAudioSessionCategoryPlayback 这个Category。
AVAudioSession Option 参数
1、参数说明
Option | Option功能说明 | 兼容的 Category |
---|---|---|
AVAudioSessionCategoryOptionMixWithOthers | 支持和其他APP音频 mix | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionDuckOthers | 系统智能调低其他APP音频音量 | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionAllowBluetooth | 支持蓝牙音频输入 | AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionCategoryOptionDefaultToSpeaker | 设置默认输出音频到扬声器 | AVAudioSessionCategoryPlayAndRecord |
音频中断处理
1、处理音频中断的方式
通过监听AVAudioSessionInterruptionNotification这个key获取音频中断事件,通知回调回来的UserInfo有键值:AVAudioSessionInterruptionTypeKey
- 取值AVAudioSessionInterruptionTypeBegan表示中断开始
- 取值AVAudioSessionInterruptionTypeEnded表示中断结束
中断开始:我们需要做的是保存好播放状态,上下文,更新用户界面等
中断结束:我们要做的是恢复好状态和上下文,更新用户界面,根据需求准备好之后选择是否激活我们session。
2、 处理不同音频播放方式的中断
- System Sound Services:使用 System Sound Services 播发音频,系统会自动处理,不受APP控制,当中断发生时,音频播放会静音,当中断结束后,音频播放会恢复。
- AV Foundation framework:AVAudioPlayer 类和 AVAudioRecorder 类提供了中断开始和结束的 Delegate 回调方法来处理中断。中断发生,系统会自动停止播放,需要做的是记录播放时间等状态,更新用户界面,等中断结束后,再次调用播放方法,系统会自动激活session。
- Audio Queue Services, I/O audio unit:使用aduio unit这些技术需要处理中断,需要做的是记录播放或者录制的位置,中断结束后自己恢复audio session。
- OpenAL:使用 OpenAL 播放时,同样需要自己监听中断。管理 OpenAL上下文,用户中断结束后恢复audio session。
3、注意
- 有中断开始事件,不一定对应有中断结束事件,所以需要在用户进入前台,点击UI操作的时候,需要保存好播放状态和对Audio Session管理,以便不影响APP的音频功能。
- 音频资源竞争上,一定是电话优先。
- AVAudioSession同样可以监听外设音频状态,比如耳机拔入拔出。
简单示例代码:
#import "AudioToolboxController.h" #import <AVFoundation/AVFoundation.h> @interface AudioToolboxController () @property(nonatomic,strong)AVPlayer * player; @property(nonatomic,strong)AVPlayerItem * playerItem; @end @implementation AudioToolboxController // 初始化播放器 -(AVPlayer *)player{ if (!_player) { NSString * path = [[NSBundle mainBundle] pathForResource:@"多幸运" ofType:@"mp3"]; NSURL * url = [NSURL fileURLWithPath:path]; _playerItem = [[AVPlayerItem alloc] initWithURL:url]; _player = [[AVPlayer alloc] initWithPlayerItem:_playerItem]; } return _player; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; [self.player play]; AVAudioSession * audioSession = [AVAudioSession sharedInstance]; // 读取当前设备支持的Category NSLog(@"%@",audioSession.availableCategories); // 设置Category [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; // 设置 Category Mode Options [audioSession setCategory:AVAudioSessionCategoryPlayback mode:AVAudioSessionModeDefault options:AVAudioSessionCategoryOptionAllowBluetooth error:nil]; [audioSession setActive:YES error:nil]; // 注册监听中断的通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getUerinfo:) name:@"AVAudioSessionInterruptionNotification" object:nil]; } -(void)getUerinfo:(NSNotification *)notification{ NSLog(@"%@",notification.userInfo); // 当打开其他音频软件时,会执行这段代码 if ([notification.userInfo[@"AVAudioSessionInterruptionTypeKey"]intValue] == AVAudioSessionInterruptionTypeBegan) { // 当其他软件抢占资源时,暂停播放 [self.player pause]; } // 当其他软件进入后台或者被杀死进程之后,本软件就会执行这段代码 if ([notification.userInfo[@"AVAudioSessionInterruptionTypeKey"] intValue] == AVAudioSessionInterruptionTypeEnded) { // 当其他软件让出资源,本软软件开始播放 [self.player play]; } } @end
其他与AVAudioSession相关知识点:
1、 检测App是否获取了录音权限
// 请求录音权限 [audioSession requestRecordPermission:^(BOOL granted) { NSLog(@"%d",granted); }];
2、判断手机现在是否有其他应用在播放音频
//判断其他应用是否在播放音频: IOS6开始可以使用 if (audioSession.otherAudioPlaying) { NSLog(@"其他应用正在播放音频"); }else{ NSLog(@"没有应用正在播放!"); } //判断其他应用是否在播放音频: IOS8开始可以使用 if(audioSession.secondaryAudioShouldBeSilencedHint){ NSLog(@"其他应用正在播放音频"); }else{ NSLog(@"没有应用正在播放!"); }
3、AVAudioSession 相关的通知
// 音频发生中断时的通知 AVAudioSessionInterruptionNotification //系统的音频路线更改时的通知 AVAudioSessionRouteChangeNotification //当其他应用程序的主要音频启动或停止是的通知 AVAudioSessionSilenceSecondaryAudioHintNotification //媒体服务器终止是的通知 AVAudioSessionMediaServicesWereLostNotification //媒体服务器重新启动时的通知 AVAudioSessionMediaServicesWereResetNotification