本文转自: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. 腾讯ISUX网页前端代码分析

    看了一下腾讯ISUX网页,无论是pc端还是移动端,展示都挺好看的,先对其代码进行分析如下: 1,先看前三行代码 <!DOCTYPE html> <!-- 腾讯 ISUX 是腾讯集团核 ...

  2. JavaScript利用闭包循环绑定事件

    我们经常在做前端面试题的时候,会遇到循环绑定事件后,输出打印结果,很多人总是搞不清楚,今天借此机会跟大家梳理一下闭包相关作用. 1.首先我们举一个简单的例子. html部分: <a href=& ...

  3. ubuntu 使用第一天

    1. 在 apt-get install xxx 时候 未选择合适的源 -> 改 sources.list2. 接1 未配好 DNS -> http://dudns.baidu.com/u ...

  4. 腾讯云万象优图每个账户提供50G的图片存储(支持黄图检测)

    文章由GIT博客迁移过来 程序下载地址(源码也在):点我下载 设计说明 10月20号晚上,准备写这么一个程序. 腾讯云万象优图每个账户提供50G的图片存储(支持黄图检测) 可以在截图之后,直接点击上传 ...

  5. Javascript开发技巧(JS中的变量、运算符、分支结构、循环结构)

    一.Js简介和入门 继续跟进JS开发的相关教程. <!-- [使用JS的三种方式] 1.HTML标签中内嵌JS(不提倡使用): 示例:<button onclick="javas ...

  6. CPU最核心的电子元件叫做石英晶振

    CPU是电子计算机的主要设备之一,是电脑中的核心配件.主要功能是解释计算机指令以及处理计算机软件中的数据.有人会问,你知道CPU里面都有什么吗?我想大家都会说硅晶体,集成度极大的半导体材料.却没有人提 ...

  7. mac下使用命令行打包出现bash gradle command not found的解决方案

    命令行打包的时候出现 bash gradle command not found这个问题,主要是因为gradle环境丢失.需要重新配置gradle的环境变量. 1. gradle路径的查找 然后gra ...

  8. 前端小课堂 js:函数的创建方式及区别

    js 函数的创建大体有这几种方式: -1-函数表达式(函数字面量): 说白了就是把一个函数赋值给了一个变量. var fun1 = function(index){ alert(index); } f ...

  9. js实现谷歌坐标转百度坐标

    js实现谷歌坐标转百度坐标 谷歌坐标转百度坐标 实现算法如下(以js为例,其他语言调整就行): //$lat 维度:$lng 经度  function GCJTobaidu($lat, $lng){ ...

  10. Java servlet ajax

    AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下. AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术. http://w ...