本文转自: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. bootstrap基础

    相信大多数后端开发人员的html,css并不是太好(主要说我).想要做一些网页效果,难度会比较大.看了下bootstrap这个前端框架,发现这个框架比较好的解决了网页效果制作中一般性问题.总的来说,b ...

  2. c# 内存的具体表现- 通用类型系统 深拷贝 浅拷贝 函数传参

    c# 通用类型系统 及变量在 深拷贝 浅拷贝 函数传参 中的深层次的表现 在编程中遇到了一些想不到的异常,跟踪发现,自己对于c#变量在内存上的表现理解有偏差,系统的学习并通过代码实验梳理了各种情况下, ...

  3. Power Pivot表属性无法切换回表预览模式的问题

    近期Office365用户升级后解决了在Power Pivot中输入中文的问题,但是同时也带来了一个新的问题就是表属性窗口默认为“查询编辑器”模式,且无法切换回“表预览”模式. 本文和您分享在这种情况 ...

  4. 如何应对苹果app 的ipv6 时代?腾讯专家教您进行环境改造

    WeTest 导读 WWDC2015苹果宣布在ios9支持纯IPv6的网络服务,并且要求2016年提交到app store的应用必须兼容纯IPv6的网络,要求适配的系统版本是ios9以上(包括ios9 ...

  5. JS立即执行函数表达式(IIFE)

    原文为 http://benalman.com/news/2010/11/immediately-invoked-function-expression/#iife ----------------- ...

  6. JavaScript window与undefined作为参数的作用

    1.原函数 输出结果:1 如图: 2.加window的参数 输出结果:window对象 如图: 注意:此时的window不是全局变量,而是局部变量 3.关于形参必须传window么?当然是不需要的 输 ...

  7. NodeJS安装第一个工程

    一.刚接触Node.js,下载好安装包后,一路Next,安装好后,结构目录如下 在命令行窗口输入node -v 和npm -v 二.建立一个Node.js工程 1.(控制台窗口)全局安装了expres ...

  8. CentOS6.7 防火墙规则(Iptables)

    查看防火墙的状态 /etc/init.d/iptables status 开启防火墙 /etc/init.d/iptables start 关闭防火墙 /etc/init.d/iptables sto ...

  9. 汉字转拼音,TinyPinyin、Pinyin4j与JPinyin哪个库更快

    1. 介绍 本文对TinyPinyin.Pinyin4j与JPinyin三个汉字转拼音库的用法.测试代码及转换的结果做一个简单的总结. TinyPinyin 适用于Java和Android的快速.低内 ...

  10. BAYESIAN STATISTICS AND CLINICAL TRIAL CONCLUSIONS: WHY THE OPTIMSE STUDY SHOULD BE CONSIDERED POSITIVE(转)

    Statistical approaches to randomised controlled trial analysis The statistical approach used in the ...