【转】iOS 音频-AVAudioSession
1. AVAudioSession 概述
最近一年一直在做IPC Camera的iOS客户端开发。和音频打交道,必须要弄清楚
AVAudioSession。
先看下苹果的官方图:

可以看到AVAudioSession就是用来管理多个APP对音频硬件设备(麦克风,扬声器)的资源使用。
举例一下AVAudioSession可以做这些事情
- 设置自己的APP是否和其他APP音频同时存在,还是中断其他APP声音
- 在手机调到静音模式下,自己的APP音频是否可以播放出声音
- 电话或者其他APP中断自己APP的音频的事件处理
- 指定音频输入和输出的设备(比如是听筒输出声音,还是扬声器输出声音)
- 是否支持录音,录音同时是否支持音频播放
2. AVAudioSession Category
AVAudioSession的接口比较简单。APP启动的时候会自动帮激活AVAudioSession,当然我们可以手动激活代码如下。
//导入头文件
#import <AVFoundation/AVFoundation.h>
//AVAudioSession是一个单例类
AVAudioSession *session = [AVAudioSession sharedInstance];
//AVAudioSessionCategorySoloAmbient是系统默认的category
[session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
//激活AVAudioSession
[session setActive:YES error:nil];
可以看到设置session这里有两个参数,category和options
Category iOS下目前有七种,每种Category都对应是否支持下面四种能力
- Interrupts non-mixable apps audio:是否打断不支持混音播放的APP
- Silenced by the Silent switch:是否会响应手机静音键开关
- Supports audio input:是否支持音频录制
- Supports audio output:是否支持音频播放
下面用图表来直观的看下每种category具体的能力集
Category | 是否允许音频播放/录音 | 是否打断其他不支持混音APP | 是否会被静音键或锁屏键静音 |
---|---|---|---|
AVAudioSessionCategoryAmbient | 只支持播放 | 否 | 是 |
AVAudioSessionCategoryAudioProcessing | 不支持播放,不支持录制 | 是 | 否 |
AVAudioSessionCategoryMultiRoute | 支持播放,支持录制 | 是 | 否 |
AVAudioSessionCategoryPlayAndRecord | 支持播放,支持录制 | 默认YES,可以重写为NO | 否 |
AVAudioSessionCategoryPlayback | 只支持播放 | 默认YES,可以重写为NO | 否 |
AVAudioSessionCategoryRecord | 只支持录制 | 是 | 否(锁屏下仍可录制) |
AVAudioSessionCategorySoloAmbient | 只支持播放 | 是 | 是 |
AVAudioSessionCategoryAmbient,只支持音频播放。这个 Category,音频会被静音键和锁屏键静音。并且不会打断其他应用的音频播放。
AVAudioSessionCategorySoloAmbient,这个是系统默认使用的 Category,只支持音频播放。音频会被静音键和锁屏键静音。和AVAudioSessionCategoryAmbient不同的是,这个会打断其他应用的音频播放
AVAudioSessionCategoryPlayback,只支持音频播放。你的音频不会被静音键和锁屏键静音。适用于音频是主要功能的APP,像网易云这些音乐app,锁屏后依然可以播放。
需要注意一下,选择支持在静音键切到静音状态以及锁屏键切到锁屏状态下仍然可以播放音频 Category 时,必须在应用中开启支持后台音频功能,详见 UIBackgroundModes。
- AVAudioSessionCategoryRecord,只支持音频录制。不支持播放。
- AVAudioSessionCategoryPlayAndRecord,支持音频播放和录制。音频的输入和输出不需要同步进行,也可以同步进行。需要音频通话类应用,可以使用这个 Category。
- AVAudioSessionCategoryAudioProcessing,只支持本地音频编解码处理。不支持播放和录制。
- AVAudioSessionCategoryMultiRoute,支持音频播放和录制。允许多条音频流的同步输入和输出。(比如USB连接外部扬声器输出音频,蓝牙耳机同时播放另一路音频这种特殊需求)
我们也可以通过AVAudioSession的属性来读取当前设备支持的Category
@property(readonly) NSArray<NSString *> *availableCategories;
这样可以保证设备兼容性。
设置Category的代码示例如下
NSError *setCategoryError = nil;
BOOL isSuccess = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
if (!success) {
//这里可以读取setCategoryError.localizedDescription查看错误原因
}
3. AVAudioSession Mode&&Options
刚刚介绍的Category定义了七种主场景,实际开发需求中有时候需要对Category进行微调整,我们发现这个接口还有两个参数Mode和Options。
/* set session category and mode with options */
- (BOOL)setCategory:(NSString *)category mode:(NSString *)mode options:(AVAudioSessionCategoryOptions)options error:(NSError **)outError API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0));
AVAudioSession Mode
我们通过读取下面这条属性获取当前设备支持的Mode
@property(readonly) NSArray<NSString *> *availableModes;
iOS下有七种mode来定制我们的Category行为
模式 | 兼容的 Category | 场景 |
---|---|---|
AVAudioSessionModeDefault | All | 默认模式 |
AVAudioSessionModeVoiceChat | AVAudioSessionCategoryPlayAndRecord | VoIP |
AVAudioSessionModeGameChat | AVAudioSessionCategoryPlayAndRecord | 游戏录制,GKVoiceChat自动设置 |
AVAudioSessionModeVideoRecording | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord | 录制视频 |
AVAudioSessionModeMoviePlayback | AVAudioSessionCategoryPlayback | 视频播放 |
AVAudioSessionModeMeasurement | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayback | 最小系统 |
AVAudioSessionModeVideoChat | AVAudioSessionCategoryPlayAndRecord | 视频通话 |
下面逐一介绍下每个Mode
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 Options
我们还可以使用options去微调Category行为,如下表
Option | Option功能说明 | 兼容的 Category |
---|---|---|
AVAudioSessionCategoryOptionMixWithOthers | 支持和其他APP音频 mix | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionDuckOthers | 系统智能调低其他APP音频音量 | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionAllowBluetooth | 支持蓝牙音频输入 | AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionCategoryOptionDefaultToSpeaker | 设置默认输出音频到扬声器 | AVAudioSessionCategoryPlayAndRecord |
调优我们的Category
通过Category和合适的Mode和Options的搭配我们可以调优出我们的效果,下面举两个应用场景:
用过高德地图的都知道,在后台播放QQ音乐的时候,如果导航语音出来,QQ音乐不会停止,而是被智能压低和混音,等导航语音播报完后,QQ音乐正常播放,这里我们需要后台播放音乐,所以Category使用AVAudioSessionCategoryPlayback,需要混音和智能压低其他APP音量,所以Options选用 AVAudioSessionCategoryOptionMixWithOthers和AVAudioSessionCategoryOptionDuckOthers
代码示例如下
BOOL isSuccess = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDuckOthers error:&setCategoryError];
又或者我希望AVAudioSessionCategoryPlayAndRecord这个Category默认的音频由扬声器播放,那么可以调用这个接口去调整Category
- (BOOL)setCategory:(NSString *)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError
通过选择合适和Category,mode和options,就可以调优音频的输入输出,来满足日常开发需求(需要注意的是Category,mode,option是搭配使用的,而不是简单组合,也就是说某种Category支持某些mode和option,从上面的表中也可以看出这一点)
4. 音频中断处理
其他APP或者电话会中断我们的APP音频,所以相应的我们要做出处理。
我们可以通过监听AVAudioSessionInterruptionNotification这个key获取音频中断事件
回调回来Userinfo有键值
- AVAudioSessionInterruptionTypeKey:
取值AVAudioSessionInterruptionTypeBegan表示中断开始
取值AVAudioSessionInterruptionTypeEnded表示中断结束
中断开始:我们需要做的是保存好播放状态,上下文,更新用户界面等
中断结束:我们要做的是恢复好状态和上下文,更新用户界面,根据需求准备好之后选择是否激活我们session。
选择不同的音频播放技术,处理中断方式也有差别,具体如下:
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。
需要注意的是:1. 有中断开始事件,不一定对应有中断结束事件,所以需要在用户进入前台,点击UI操作的时候,需要保存好播放状态和对Audio Session管理,以便不影响APP的音频功能。2.音频资源竞争上,一定是电话优先。3. AVAudioSession同样可以监听外设音频状态,比如耳机拔入拔出。这里不做累述
5. AVAudioSession总结
AVAudioSession的作用就是管理音频这一唯一硬件资源的分配,通过调优合适的AVAudioSession来适配我们的APP对于音频的功能需求。切换音频场景时候,需要相应的切换AVAudioSession。
from:https://www.jianshu.com/p/fb0e5fb71b3c
【转】iOS 音频-AVAudioSession的更多相关文章
- 一篇对iOS音频比较完善的文章
转自:http://www.cnblogs.com/iOS-mt/p/4268532.html 感谢作者:梦想通 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改我也 ...
- IOS 音频播放
iOS音频播放 (一):概述 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改我也因此对于iOS下的音频播放实现有了一定的研究.写这个系列的博客目的一方面希望能够抛砖 ...
- iOS音频播放 (二):AudioSession 转
原文出处 :http://msching.github.io/blog/2014/07/08/audio-in-ios-2/ 前言 本篇为<iOS音频播放>系列的第二篇. 在实施前一篇中所 ...
- iOS 音频开发之CoreAudio
转自:http://www.cnblogs.com/javawebsoa/archive/2013/05/20/3089511.html 接 触过IOS音频开发的同学都知道,Core Audio 是I ...
- iOS音频AAC视频H264编码 推流最佳方案
iOS音频AAC视频H264编码 推流最佳方案 项目都是个人的调研与实验,可能很多不好或者不对的地方请多包涵. 1 功能概况 * 实现音视频的数据的采集 * 实现音视频数据的编码,视频编码成 ...
- IOS 音频开发文件大小计算
音频基础知识 音频文件计算大小 音频转码 标签(空格分隔): 调查 IOS音频 https://developer.apple.com/library/ios/documentation/MusicA ...
- iOS音频处理
ios音频处理 1. iOS底层音频处理技术(带源代码) http://www.cocoachina.com/ios/20111122/3563.html 2.ios 音频入门 http://blog ...
- iOS音频播放(一):概述
(本文转自码农人生) 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改,我也因此对于iOS下的音频播放实现有了一定的研究.写这个 系列的博客目的一方面希望能够抛砖引玉 ...
- IOS音频1:之采用四种方式播放音频文件(一)AudioToolbox AVFoundation OpenAL AUDIO QUEUE
本文转载至 http://blog.csdn.net/u014011807/article/details/40187737 在本卷你可以学到什么? 采用四种方法设计应用于各种场合的音频播放器: 基于 ...
随机推荐
- mysql无法远程连接
在mysql的mysql数据库下: select user,host from user;(查看,没有本机的访问权限) grant all privileges on *.* to root@&quo ...
- JavaScript如何工作:内存管理+如何处理4个常见的内存泄漏
摘要: 作者将自己常用的JavaScript模块分享给大家. 原文:JavaScript如何工作:内存管理+如何处理4个常见的内存泄漏 作者:前端小智 Fundebug经授权转载,版权归原作者所有. ...
- JavaScript 中的相等操作符 ( 详解 [] == []、[] == ![]、{} == !{} )
ECMAScript 中的相等操作符由两个等于号 ( == ) 表示,如果两个操作数相等,则返回 true. 相等操作符会先转换操作数(通常称为强制转型),然后比较它们的相等性. 在转换不同的数据类型 ...
- C#字节图片互转、字节转换图片、图片转换字节、byte[]转换图片、图片转换成byte[]
原文地址:http://www.cnblogs.com/wifi/articles/3522773.html /// <summary> /// 图片转换成字节流 /// </sum ...
- 在 Apex 中使用合并统计查询
SOQL 中的合并统计查询 在 SOQL 中,我们可以使用一系列函数来进行合并统计查询.它们的功能和标准 SQL 中的 SUM(),COUNT() 等函数类似. 官方文档 Apex 中使用合并统计查询 ...
- Testlink1.9.17使用方法(第六章 测试计划制定)
第六章 测试计划制定 QQ交流群:585499566 在TestLink系统中,一个完整的测试计划包括:集成测试阶段.系统测试阶段. 一. 创建测试计划 1,点击主页上[测试计划管理] 2,在“测试计 ...
- android adb 流程原理代码分析(一)
由于要用到adb的知识,但是对adb啥也不了解,看了下android的代码,adb的源码在system/core/adb下面,然后网上搜下了资料,发现很多大神的源码分析,瞬间信心爆棚,把大神写的博客都 ...
- VS调试IDAPython脚本
本文最后修改时间:20180213 1.安装VS插件PTVS , 这一步与第2步中安装版本应该一致,否则最后调试时会连不上 https://github.com/Microsoft/PTVS/ 2.安 ...
- Django Admin后台管理用户密码修改
方法一 在Terminal中执行:python manage.py changepassword your_name(其中“your_name”为你要修改密码的用户名),根据提示内容修改即可. 方法二 ...
- js每隔一段时间执行函数
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...