本文转自:AVAudioSession(2):定义一个 Audio Session | www.samirchen.com

本文内容主要来源于 Defining an Audio Session

Audio Session 的默认行为

AVAudioSession 的默认行为如下:

  • 音频播放能力是开启的,但是音频录制能力是关闭的。
  • 当用户通过静音键切换到静音模式时,你的音频会被静音。
  • 当用户通过锁屏键锁定屏幕或者自动锁屏定时触发时,你的音频会被静音。
  • 当你的音频开始播放时,正在播放的其他 App 的音频会被静音。

这些行为是由默认的 AVAudioSessionCategorySoloAmbient Category 设定的。通常默认设置是不能满足你的需求的,除非你的 App 对音频的控制场景如下:

  • 你的 App 只使用 System Sound Services 或者 UIKit 中的 playInputClick 方法来处理音频,而没有用到其他音频相关的 API 时。
  • 你的 App 不使用任何音频。

系统如何解决竞争性的音频请求

流程大致如下图,还是挺好理解的:

需要注意的是,系统永远遵循一个原则:电话的优先级最高。

和 AVCaptureSession 协同

在 AV Foundatin capture 相关的 API 中(AVCaptureDevice, AVCaptureSession)允许你从摄像头和麦克风采集同步的音视频数据。其中表示麦克风的 AVCaptureDevice 对象可以共享你的 AVAudioSession。通常情况下,如果 AVCaptureSession 需要使用麦克风进行音频录制时,它会去修改优化你的 AVAudioSession 配置。如果你不希望这样,则需要设置对应的 AVCaptureSession 对象的 automaticallyConfiguresApplicationAudioSession 属性为 NO 来让 AVCaptureSession 使用你当前的 AVAudioSession 配置而不会修改它。

初始化 Audio Session

代码如下:

// implicitly initializes your audio session
AVAudioSession *session = [AVAudioSession sharedInstance];

音量和路径控制

苹果官方推荐使用 MPVolumeView 来控制音频音量和路径,MPVolumeView 提供了一个 Slider 来控制音量,提供了一个按钮来供你选择音频输出路径。

你可以通过如下代码来设置音频输出路径到话筒:

[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];

但苹果推荐你用 MPVolumeView 提供的路径选择按钮来实现音频输出路径切换。

响应远程控制事件

通过响应 Remote Control Events 能让你在播放音视频内容时,可以响应来自锁屏界面、外部设备等 App 外部的控制。

具体参见 Remote Control EventsMPNowPlayingInfoCenter Class Reference

激活和关闭 Audio Session

苹果官方建议如果你需要用到 Audio Session,总是应该显示地激活你的 Audio Session。并且参考 Setting Preferred Hardware Values 来设置相应的硬件参数。这样可以在你使用 Audio Session 前来测试是否能成功激活,以便于做出正确的处理逻辑。

激活 Audio Session 代码如下:

NSError *activationError = nil;
BOOL success = [[AVAudioSession sharedInstance] setActive:YES error:&activationError]; // Pass 'NO' when deactivate your audio session.
if (!success) { /* handle the error in activationError */ }

值得注意的是,大部分时候我们不需要关闭 Audio Session,除非是在 VoIP(Voice over Internet Protocol) 类应用、turn-by-turn 导航类应用和某些录制类应用中。这时你需要注意:

  • 对于 VoIP 类应用,要确保 Audio Session 只在电话接听中是 Active 的。当应用处于后台时,保持应用为准备接听电话的状态,但应用的 Audio Session 应该是 Inactive 的。
  • 对于定位于 Recording Category 来使用 Audio Session 的应用,要确保只在录制中设置 Audio Session 为 Active 状态,在录制开始前和录制结束后要确保 Audio Session 为 Inactive 状态以允许其他音频的播放。

检查是否有其他音频正在播放

你可以通过 otherAudioPlaying 来检查是否当前有其他应用的音频正在播放。

比如你是一个自带音效的游戏,当一个正在听音乐的用户打开你的游戏时,iOS 设计指南会建议你不要关闭用户正在听的音乐而播放你的游戏音效,这时候你怎么处理呢?你可以用上面的接口检查一下,如果有声音在播放则将你的音效静音并设置 AVAudioSessionCategorySoloAmbient。

Inter-App Audio 特性

Inter-App Audio 特性允许一个 Node App 将它的音频输出给一个 Host App。也可以由 Host App 发送它的音频给 Node App 进行处理,处理完后再发回给 Host App。Host App 需要设置一个 Active 的 Audio Session,而 Node App 则只在从 Host App 或系统接收音频输入时才需要一个 Active 的 Audio Session。

你可以使用下面这些规则来搭建 Inter-App Audio:

  • 为 Node App 和 Host App 都设置 「inter-app-audio」的 entitlement。
  • 为 Host App 设置 UIBackgroundModes 的 audio flag。
  • 为那些在与 Host App 连接时使用音频输入或输出路径的 Node App 设置 UIBackgroundModes 的 audio flag。
  • 为 Node App 和 Host App 都设置 AVAudioSessionCategoryOptionMixWithOthers 这个 Category。
  • 确保连接着 inter-app host 的 Node App 在接收来自系统的音频或者输出音频时的 Audio Session 是 Active 的。

AVAudioSession(2):定义一个 Audio Session的更多相关文章

  1. AVAudioSession(3):定制 Audio Session 的 Category

    本文转自:AVAudioSession(3):定制 Audio Session 的 Category | www.samirchen.com 本文内容主要来源于 Working with Catego ...

  2. AVAudioSession(1):iOS Audio Session 概览

    本文转自:AVAudioSession(1):iOS Audio Session 概览 | www.samirchen.com 本文内容主要来源于 Audio Session Programming ...

  3. H5页面实现一个Audio标签加载多个音频文件,并进行播放和展示音频长度

    最近微信项目中有需求,要将微信端发送过来的amr格式的语音文件,在项目中的页面上进行展示和播放,实现方式如下: 1.首先java后台收到微信端的消息推送的时候,使用 ffmpeg将amr格式的音频文件 ...

  4. audio session config

    #pragma mark - #pragma mark - audio session config - (void)setAudioSessionConfig { NSError *error; A ...

  5. IOS Audio session

    iOS实现长时间后台的两种方法:Audio session和VOIP socket 十二月 04 我们知道 iOS 开启后台任务后可以获得最多 600 秒的执行时间,而一些需要在后台下载或者与服务器保 ...

  6. NX二次开发-如何在类外面定义一个结构体

    #include <uf.h> #include <uf_obj.h> #include <uf_part.h> using namespace NXOpen; u ...

  7. 用CIL写程序:定义一个叫“慕容小匹夫”的类

    前文回顾: <用CIL写程序:你好,沃尔德> <用CIL写程序:写个函数做加法> 前言: 今天是乙未羊年的第一天,小匹夫先在这里给各位看官拜个年了.不知道各位看官是否和匹夫一样 ...

  8. java怎么定义一个二维数组?

    java中使用 [][] 来定义二维数组 定义数组时也可同时初始化下面是一些例子float[][] numthree; //定义一个float类型的2维数组numthree=new float[5][ ...

  9. 将对象的所有属性名放到一个数组中 || 获得对象的所有属性名 || return;不具有原子性 || 怎样自己制作异常|| 判断对象有没有某个属性 || 当传递的参数比需要的参数少的时候,没有的值会被赋予undefined || 获得函数实际传递的参数 || 怎么用函数处理一个对象 || 用一个名字空间定义一个模块所有的函数 || 给一个对象添加方法

    获得对象的所有属性名 || 将对象o的所有属性名放到数组中 var o = {x:1,y:2,z:3}; var arr = []; var i = 0; for(arr[i++] in o){};/ ...

随机推荐

  1. 源码浅谈(一):java中的 toString()方法

    前言: toString()方法 相信大家都用到过,一般用于以字符串的形式返回对象的相关数据. 最近项目中需要对一个ArrayList<ArrayList<Integer>> ...

  2. poj 1056 IMMEDIATE DECODABILITY 字典树

    题目链接:http://poj.org/problem?id=1056 思路: 字典树的简单应用,就是判断当前所有的单词中有木有一个是另一个的前缀,直接套用模板再在Tire定义中加一个bool类型的变 ...

  3. .NET面试题系列[16] - 多线程概念(1)

    .NET面试题系列目录 这篇文章主要是各个百科中的一些摘抄,简述了进程和线程的来源,为什么出现了进程和线程. 操作系统层面中进程和线程的实现 操作系统发展史 直到20世纪50年代中期,还没出现操作系统 ...

  4. 2017最新最稳定的彩票源码PHP+mysql 新增彩种+全新界面

    网站后台管理系统:新闻资讯系统 用户管理系统用户登录日志彩种规则说明玩法时间设置彩票期号管理足球对阵管理彩票方案撤单彩票出票管理开奖号码管理彩票方案查询彩票中奖查询 彩票追号查询服务支持中心财务中心管 ...

  5. EntityFramework中出现DateTime2异常的完美解决办法

    今天在使用entityframework往数据库插入数据的时候,突然出现了一个数据类型转换异常的问题: System.Data.SqlClient.SqlException: 从 datetime2 ...

  6. angular.js实现省市区三级联动指令

    不多说,直接上代码,一开始搞了好久,最后才弄懂,希望对大家有帮助 1.jade div.col-md-2 select.form-control(ng-options="value.code ...

  7. PHP导出生成CSV文件

    composer 用起来是非常方便的 所以我是依赖composer来做的包管理 1.先安装composer 自行百度一下composer安装以及使用 2.用composer下载安装office包即可 ...

  8. 【JAVAWEB学习笔记】15_request

    HttpServletRequest 学习目标 案例一.完成用户注册 案例二.完成登录错误信息的回显 1.HttpServletRequest概述 我们在创建Servlet时会覆盖service()方 ...

  9. SpringMVC中使用RedirectAttributes重定向传参,防止暴露参数

    RedirectAttributes是SpringMVC3.1版本之后出来的一个功能,专门用于重定向之后还能带参数跳转的. 当我从jsp页面函数中带参数到controller层方法,方法执行完毕后返回 ...

  10. jmeter跨线程组传值

    在测试过程中,有时候需要jmeter跨线程组传值,jmeter本身又不具备此功能,那么,又该如何实现呢? 其实,我们可以通过BeanShell去实现. 实现过程如下: 1.线程组A中,使用正则表达式提 ...